刷新 ViewPager 活动片段中的列表视图崩溃



我有一个带有ViewPager的活动,里面有2个片段。一个片段用于将项目添加到列表视图,另一个片段包含列表视图。现在,添加项目后,我必须重新启动应用程序以刷新ListView,但我正在尝试解决此问题。方法如下:

我正在尝试调用该方法从ViewPager刷新ListView,如下所示:

@Override
public void onPageSelected(int position) {
library.populateListView(getApplicationContext(), library.lView); //this is line 47
aBar.setSelectedNavigationItem(position);
}

这是片段中的填充列表视图方法:

public void populateListView(Context context, ListView listView){   
CustomListViewAdapter customAdapter = new CustomListViewAdapter(getDatabaseArrayList(context), getActivity());  
listView.setAdapter(customAdapter); //this is line 122
customAdapter.notifyDataSetChanged();
}

getDatabaseArrayList方法代码:

private ArrayList<RecordDetails> getDatabaseArrayList(Context context){
DatabaseHandler dbHandler = new DatabaseHandler(context);
Cursor c = dbHandler.getAllRecordedFiles();
ArrayList<RecordDetails> components = new ArrayList<RecordDetails>();
RecordDetails element;
if(c.moveToFirst()){
element = new RecordDetails();
element.setTitle(c.getString(c.getColumnIndex(SQLiteHelper.MUSIC_NAME)));
element.setDate(c.getString(c.getColumnIndex(SQLiteHelper.MUSIC_DATE)));
element.setDuration(c.getString(c.getColumnIndex(SQLiteHelper.MUSIC_DURATION)));
components.add(element);
while (c.moveToNext())
{
element = new RecordDetails();
element.setTitle(c.getString(c.getColumnIndex(SQLiteHelper.MUSIC_NAME)));
element.setDate(c.getString(c.getColumnIndex(SQLiteHelper.MUSIC_DATE)));
element.setDuration(c.getString(c.getColumnIndex(SQLiteHelper.MUSIC_DURATION)));
components.add(element);
}
}
return components;
}

我的猜测是应用程序崩溃了,因为我从library.lView等 ViewPager 活动调用 ListView,它可能返回null。但是我该如何解决这个问题呢?我试图在 ViewPager 活动中声明一个新的 ListView 变量,但它崩溃了,可能是因为该活动不包括 ListView 本身。

如果有帮助,这是日志猫输出:

03-04 08:43:44.092: E/AndroidRuntime(1779): FATAL EXCEPTION: main
03-04 08:43:44.092: E/AndroidRuntime(1779): java.lang.NullPointerException
03-04 08:43:44.092: E/AndroidRuntime(1779):     at com.matejhacin.beautifulvoicerecorder.LibraryFragment.populateListView(LibraryFragment.java:124)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at com.matejhacin.beautifulvoicerecorder.MainActivity$1.onPageSelected(MainActivity.java:46)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.support.v4.view.ViewPager.scrollToItem(ViewPager.java:567)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:551)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.support.v4.view.ViewPager.onTouchEvent(ViewPager.java:2015)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.view.View.dispatchTouchEvent(View.java:7384)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2205)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1940)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2211)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1954)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2211)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1954)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2211)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1954)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1966)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1418)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.app.Activity.dispatchTouchEvent(Activity.java:2424)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1914)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.view.View.dispatchPointerEvent(View.java:7564)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:3883)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3778)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3379)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3429)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3398)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3483)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3406)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3540)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3379)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3429)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3398)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3406)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3379)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5419)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5399)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5370)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5493)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:182)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.os.MessageQueue.nativePollOnce(Native Method)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.os.MessageQueue.next(MessageQueue.java:132)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.os.Looper.loop(Looper.java:124)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at android.app.ActivityThread.main(ActivityThread.java:5103)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at java.lang.reflect.Method.invokeNative(Native Method)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at java.lang.reflect.Method.invoke(Method.java:525)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
03-04 08:43:44.092: E/AndroidRuntime(1779):     at dalvik.system.NativeStart.main(Native Method)

如果我需要发布完整的日志猫,请告诉我,因为我只发布了我认为最重要的部分。

更新------------------------------

完整的创建视图代码:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_library, container, false);
// ListView
lView = (ListView) v.findViewById(R.id.listView);
lView.setOnItemClickListener(this);
registerForContextMenu(lView);
//Other variables
components = new ArrayList<RecordDetails>();
components = getDatabaseArrayList(getActivity());
db = new DatabaseHandler(getActivity());
mp = new MediaPlayer();
playPause = (Button) v.findViewById(R.id.playPause);
playPause.setOnClickListener(this);
sBar = (SeekBar) v.findViewById(R.id.seekBar1);
sBar.setOnSeekBarChangeListener(this);
seekHandler = new Handler();
populateListView(getActivity());
seekHandler.post(run);
return v;
}

更新 2---------------

库片段 XML 代码:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/gradient_background"
tools:context=".LibraryFragment" >
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/seekBar1"
android:layout_below="@+id/view1"
android:layout_centerHorizontal="true"
android:focusable="false"
android:focusableInTouchMode="false" >
</ListView>
<View
android:id="@+id/view1"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:background="@drawable/gradient_shadow_transparent" />
<SeekBar
android:id="@+id/seekBar1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_marginBottom="53dp"
android:layout_marginLeft="40dp"
android:layout_marginRight="40dp" />
<Button
android:id="@+id/playPause"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="Play" />
<TextView
android:id="@+id/current"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/seekBar1"
android:layout_alignParentLeft="true"
android:text="0:03"
android:layout_marginLeft="5dp" />
<TextView
android:id="@+id/duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/seekBar1"
android:layout_alignParentRight="true"
android:text="0:17"
android:layout_marginRight="5dp" />

如果此代码在片段中,则需要从

@Override
public void onPageSelected(int position) {
library.populateListView(getApplicationContext(), library.lView); //this is line 47
aBar.setSelectedNavigationItem(position);
}

@Override
public void onPageSelected(int position) {
library.populateListView(getActivity(), library.lView); //this is line 47
aBar.setSelectedNavigationItem(position);
}

您还必须在此处进行更改,因为在填充ListView中有两个参数,并且仅使用上下文执行。所以改变它。

populateListView(getActivity());

populateListView(getActivity() , lv);

我认为问题可能在这里

components = getDatabaseArrayList(getActivity());
db = new DatabaseHandler(getActivity());

getDatabaseArrayList是正在执行的函数,之后你初始化了数据库类。所以它会在这里崩溃。所以改变

db = new DatabaseHandler(getActivity());
components = getDatabaseArrayList(getActivity());

你试过这个吗??

public void populateListView(Context context){   
CustomListViewAdapter customAdapter = new CustomListViewAdapter(components, getActivity());  
lView.setAdapter(customAdapter); //this is line 122
customAdapter.notifyDataSetChanged();
}

我认为你不需要从ViewPagerActivity发送列表视图。将列表视图的实例保留在库片段本身中,并将其存储在 onCreateView 中。

将填充列表视图更改为

public void populateListView(Context context){   
CustomListViewAdapter customAdapter = new CustomListViewAdapter(getDatabaseArrayList(context), getActivity());  
lView.setAdapter(customAdapter); //this is line 122
customAdapter.notifyDataSetChanged();
}

根据我从您的代码中了解到的是,您正在尝试使用新数据刷新listView,这会导致您的应用程序崩溃。

要安全地刷新listview,您需要在customAdapter中创建一个名为setNewData(ArrayList<object> newData)的方法。将object替换为您正在使用的数据类型,并在此方法中执行以下操作:

public void setNewDAta(ArrayList<object> newData){
this.data = newData;
}

从您的主要活动中,通过在活动开始时声明customAdapter,使它成为全局可用,以确保您只使用一个,并创建一个方法将新数据传递给adapter并刷新它,如下所示:

public void setListViewData(ArrayList<object> newData){
customAdapter.setNewDAta(newData);
customAdapter.notifyDataSetChanged();
}

最新更新