我有一个带有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" />
答案 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