2013-10-30 47 views
0

我想通過使用片段做待辦事項列表應用程序。而動態地創建這個片段,我採取一個空指針異常在該行(在mainactivity.java):動態創建片段時,如何擺脫「空指針異常」?

adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, todoItems); 
listToDo.setListAdapter(adapter); 

我不能看到這條消息上的logcat:Log.w(「6」,「ALTI」); 我的代碼有什麼問題?我怎麼解決這個問題?

activity_main.xml文件:

<LinearLayout 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:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    tools:context=".MainActivity" 
    android:orientation="vertical"> 


    <FrameLayout 
     android:id="@+id/list_view_fragment" 
     android:layout_width="match_parent" 
     android:layout_height="0dp" 
     android:layout_weight="1.5" 
     > </FrameLayout> 
    </LinearLayout> 

to_do_fragment.xml 

    <?xml version="1.0" encoding="utf-8"?> 
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:id="@+id/add_to_do_fragment" > 
    <Button 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentRight="true" 
     android:id="@+id/addButton" 
     android:contentDescription="@string/addItemContentDescription" 
     android:text="@string/add_button"/> 
    <EditText 
     android:id="@+id/editText" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentLeft="true" 
     android:layout_toLeftOf="@id/addButton" 
     android:hint="@string/edit_text" /> 
    </RelativeLayout> 

list_view.xml 

    <?xml version="1.0" encoding="utf-8"?> 
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:id="@+id/list_view" > 
    <ListView 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:id="@+id/listView"></ListView> 
    </RelativeLayout> 


LogCat 

    10-30 19:28:26.355: E/AndroidRuntime(1763): FATAL EXCEPTION: main 
    10-30 19:28:26.355: E/AndroidRuntime(1763): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.todolistwithdynamicfragments/com.example.todolistwithdynamicfragments.MainActivity}: java.lang.IllegalArgumentException: No view found for id 0x7f080003 (com.example.todolistwithdynamicfragments:id/add_to_do_fragment) for fragment AddToDoFragment{41770868 #0 id=0x7f080003} 
    10-30 19:28:26.355: E/AndroidRuntime(1763):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211) 
    10-30 19:28:26.355: E/AndroidRuntime(1763):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261) 
    10-30 19:28:26.355: E/AndroidRuntime(1763):  at android.app.ActivityThread.access$600(ActivityThread.java:141) 
    10-30 19:28:26.355: E/AndroidRuntime(1763):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256) 
    10-30 19:28:26.355: E/AndroidRuntime(1763):  at android.os.Handler.dispatchMessage(Handler.java:99) 
    10-30 19:28:26.355: E/AndroidRuntime(1763):  at android.os.Looper.loop(Looper.java:137) 
    10-30 19:28:26.355: E/AndroidRuntime(1763):  at android.app.ActivityThread.main(ActivityThread.java:5103) 
    10-30 19:28:26.355: E/AndroidRuntime(1763):  at java.lang.reflect.Method.invokeNative(Native Method) 
    10-30 19:28:26.355: E/AndroidRuntime(1763):  at java.lang.reflect.Method.invoke(Method.java:525) 
    10-30 19:28:26.355: E/AndroidRuntime(1763):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737) 
    10-30 19:28:26.355: E/AndroidRuntime(1763):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
    10-30 19:28:26.355: E/AndroidRuntime(1763):  at dalvik.system.NativeStart.main(Native Method) 
    10-30 19:28:26.355: E/AndroidRuntime(1763): Caused by: java.lang.IllegalArgumentException: No view found for id 0x7f080003 (com.example.todolistwithdynamicfragments:id/add_to_do_fragment) for fragment AddToDoFragment{41770868 #0 id=0x7f080003} 
    10-30 19:28:26.355: E/AndroidRuntime(1763):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:877) 
    10-30 19:28:26.355: E/AndroidRuntime(1763):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1057) 
    10-30 19:28:26.355: E/AndroidRuntime(1763):  at android.app.BackStackRecord.run(BackStackRecord.java:682) 
    10-30 19:28:26.355: E/AndroidRuntime(1763):  at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1435) 
    10-30 19:28:26.355: E/AndroidRuntime(1763):  at android.app.Activity.performStart(Activity.java:5142) 
    10-30 19:28:26.355: E/AndroidRuntime(1763):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2184) 
    10-30 19:28:26.355: E/AndroidRuntime(1763):  ... 11 more 
+0

NullPointerExceptions很容易追蹤。你需要發佈你的logcat輸出給我們來幫助你。 – wyoskibum

+0

MainActivity.java第41行的代碼是什麼? – AsG

+0

@AakashGoyal - 它指出了在問題頂部的權利.... – dymmeh

回答

0

移動此行

listToDo = (ToDoListFragment) fm.findFragmentById(R.id.list_view_fragment);

進入你的else語句。

由於片段管理器無法找到您剛剛提交的片段,因此您在第一次運行時基本上將其清除爲listToDocommit()安排您的片段添加。這並不意味着他們馬上被添加。因此,調用findFragmentById將在您立即調用後返回null,這就是爲什麼listToDo以null結尾的原因。

+0

我做了你說的,但我仍然得到一個錯誤。 – cgbs

+0

但是,我認爲空指針exeption消失了。 我再次編輯日誌貓 – cgbs

+0

@cgbs - 你的片段需要你的Activity來實現你的監聽器。將您的活動聲明更改爲「公共類MainActivity擴展活動實現AddToDoFragment.OnToDoAddedListener」。您已在接口的活動中擁有該方法,因此您只需更改活動即可實現該接口。 – dymmeh

0

你toDoItems未在下面一行得到初始化:

todoItems = savedInstanceState.getStringArrayList("todoItemTag"); 

我建議你測試的陣列,以確保它不爲空。喜歡的東西:

Log.i("ARRAY",todoItems.length); 
+0

基於他正在初始化/保存/恢復列表的方式,這永遠不會爲空。 – dymmeh

0

由於todoItems是在該行的三個參數,可以爲空,那一定是罪魁禍首的唯一的一個。我認爲它是空的唯一方法是如果savedInstanceState不包括"todoItemTag"這很容易發生在許多情況下。你的代碼假設savedInstanceState總是有"todoItemTag"如果savedInstanceState不爲空,但它非常好可以是非空的,並且沒有任何內容。我想重寫代碼的排序是這樣,但實際上我不明白爲什麼你只建立在某些情況下的片段,所以這可能需要更多的工作:

protected void onCreate(Bundle savedInstanceState) { 
super.onCreate(savedInstanceState); 
setContentView(R.layout.activity_main); 

if (savedInstanceState!=null) 
    todoItems = savedInstanceState.getStringArrayList("todoItemTag"); 

if (todoItems == null) { 
    todoItems = new ArrayList<String>(); 
} 

adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, todoItems); 
listToDo.setListAdapter(adapter); 

//TODO fragment management 

}