简体   繁体   English

动态创建片段时,如何摆脱“空指针异常”?

[英]How can I get rid of the “null pointer exception” while creating fragments dynamically?

I want to do to-do list application by using fragments. 我想使用片段来做待办事项清单应用程序。 While creating this fragments dynamically, I take a null pointer exception at this line (in mainactivity.java ): 动态创建此片段时,我在此行(在mainactivity.java )采用了空指针异常:

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

I cannot see this message on logcat: Log.w("6", "altı"); 我在logcat上看不到此消息:Log.w(“ 6”,“altı”); What is wrong with my code? 我的代码有什么问题? How can I solve this problem? 我怎么解决这个问题?

The activity_main.xml file: 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

Your toDoItems is not getting initialized in the following line: 您的toDoItems不会在以下行中初始化:

todoItems = savedInstanceState.getStringArrayList("todoItemTag");

I would suggest you test the array to ensure that it is not null. 我建议您测试该数组以确保它不为null。 Something like: 就像是:

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

Since todoItems is the only one of the three parameters in that line that could be null, that must be the culprit. 由于todoItems是该行中三个参数中唯一可以为null的参数之一,因此必须是罪魁祸首。 The only way I see for it to be null is if the savedInstanceState does not include "todoItemTag" which could easily happen under many scenarios. 我认为它为null的唯一方法是,如果savedInstanceState不包含"todoItemTag" ,那么在许多情况下很容易发生这种情况。 Your code is assuming that the savedInstanceState always has "todoItemTag" if savedInstanceState is not null, but it very well could be non-null and have nothing in it. 您的代码假定,如果savedInstanceState不为null,则savedInstanceState始终具有"todoItemTag" ,但它很可能为非null,并且其中没有任何内容。 I would rewrite your code sort of like this, but actually I don't understand why you are only creating the fragment under certain circumstances, so this probably needs more work: 我会像这样重写您的代码,但实际上我不明白为什么您只在某些情况下才创建片段,因此这可能需要更多的工作:

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

}

Move this line 移动这条线

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

into your else statement. 到您的else语句中。

You are essentially nulling out listToDo on your first run since the fragment manager will not find your fragment that you just committed. 由于片段管理器不会找到您刚刚提交的片段,因此您基本上在第一次运行时便使listToDo commit() schedules your fragments to be added. commit()计划要添加的片段。 It does not mean they are added right away. 这并不意味着它们会立即添加。 So, calling findFragmentById will return null when you call it immediately after which is why listToDo ends up null. 因此,当您立即调用findFragmentById将返回null,这就是listToDo最终为null的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM