刷新ViewPager活动中的片段中的ListView崩溃

时间:2014-03-04 08:21:10

标签: android listview android-listview android-fragments android-viewpager

我有一个带有ViewPager的Activity,里面有 2 个片段。一个片段用于向ListView添加项目,另一个片段包含ListView。现在我必须重新启动应用程序以在添加项目后刷新ListView,但我正在尝试修复它。方法如下:

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

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

这是片段中的 populateListView 方法:

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;
}

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

如果有帮助,这是logcat输出:

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)

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

UPDATE ------------------------------

完整的onCreateView代码:

@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 ---------------

Library Fragment 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" />

3 个答案:

答案 0 :(得分:0)

我认为您不需要从ViewPagerActivity发送listview。将listview的实例保存在库片段本身中,将其存储在onCreateView中。

将populateListView更改为

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

答案 1 :(得分:0)

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

更改
@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);
}

你必须在这里进行更改,因为在你的 populateListView 中有两个参数,而你只使用Context执行。所以改变它。

  populateListView(getActivity());

  populateListView(getActivity() , lv);

我认为问题可能就在这里

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

getDatabaseArrayList是您正在执行的函数,之后您已初始化您的Database类。所以它会在这里崩溃。所以改变

   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();
  }

答案 2 :(得分:0)

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

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

object

从您的主要活动中,public void setNewDAta(ArrayList<object> newData){ this.data = newData; } 可以通过在活动开始时声明它来确保全局可用,以确保您只使用一个并创建一种方法将新数据传递给{{1}并按如下方式刷新它:

customAdapter