绝密android初学者在fragment中常放的错误和对应的解决办法Android工程师

/ 福州大学Android工程师 / 2017-05-05

android初学者在fragment中常放的错误和对应的解决办法

第一个、使用ListFragment:java.lang.RuntimeException: 

      Content has view with id attribute 'android.R.id.list' that is not a ListView class在ListFragment中,想当然的以为,像其他Fragment一样:

[java] view plain copy 

01.public class ListFragmentTest extends ListFragment {  

03.    @Override  

04.    public View onCreateView(LayoutInflater inflater, ViewGroup container,  

05.            Bundle savedInstanceState) {  

06.        View root = inflater.inflate(R.layout.list, null);  

07.        return root;  

08.    }  


在list.xml里面:

[html] view plain copy 

01.<?xml version="1.0" encoding="utf-8"?>  

02.<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  

03.    android:layout_width="fill_parent"  

04.    android:layout_height="fill_parent"  

05.    android:orientation="vertical" >  

07.    <TextView   

08.        android:layout_width="wrap_content"  

09.        android:layout_height="wrap_content"  

10.        android:text="@string/app_name"  

11.        />  

12.    <ListView   

13.        android:id="@+id/list"  

14.        android:layout_width="fill_parent"  

15.        android:layout_height="fill_parent"  

16.        ></ListView>  


17.</LinearLayout>  

看下log:

[java] view plain copy 

01.07-16 15:43:22.026: E/AndroidRuntime(605): FATAL EXCEPTION: main  

02.07-16 15:43:22.026: E/AndroidRuntime(605): java.lang.RuntimeException: Unable to start activity ComponentInfo{cn.demo/cn.demo.FragmentTestActivity}: android.view.InflateException: Binary XML file line #23: Error inflating class fragment  

03.07-16 15:43:22.026: E/AndroidRuntime(605):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)  

04.07-16 15:43:22.026: E/AndroidRuntime(605):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)  

05.07-16 15:43:22.026: E/AndroidRuntime(605):  at android.app.ActivityThread.access$600(ActivityThread.java:123)  

06.07-16 15:43:22.026: E/AndroidRuntime(605):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)  

07.07-16 15:43:22.026: E/AndroidRuntime(605):  at android.os.Handler.dispatchMessage(Handler.java:99)  

08.07-16 15:43:22.026: E/AndroidRuntime(605):  at android.os.Looper.loop(Looper.java:137)  

09.07-16 15:43:22.026: E/AndroidRuntime(605):  at android.app.ActivityThread.main(ActivityThread.java:4424)  

10.07-16 15:43:22.026: E/AndroidRuntime(605):  at java.lang.reflect.Method.invokeNative(Native Method)  

11.07-16 15:43:22.026: E/AndroidRuntime(605):  at java.lang.reflect.Method.invoke(Method.java:511)  

12.07-16 15:43:22.026: E/AndroidRuntime(605):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)  

13.07-16 15:43:22.026: E/AndroidRuntime(605):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)  

14.07-16 15:43:22.026: E/AndroidRuntime(605):  at dalvik.system.NativeStart.main(Native Method)  

15.07-16 15:43:22.026: E/AndroidRuntime(605): Caused by: android.view.InflateException: Binary XML file line #23: Error inflating class fragment  

16.07-16 15:43:22.026: E/AndroidRuntime(605):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:697)  

17.07-16 15:43:22.026: E/AndroidRuntime(605):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:739)  

18.07-16 15:43:22.026: E/AndroidRuntime(605):  at android.view.LayoutInflater.inflate(LayoutInflater.java:489)  

19.07-16 15:43:22.026: E/AndroidRuntime(605):  at android.view.LayoutInflater.inflate(LayoutInflater.java:396)  

20.07-16 15:43:22.026: E/AndroidRuntime(605):  at android.view.LayoutInflater.inflate(LayoutInflater.java:352)  

21.07-16 15:43:22.026: E/AndroidRuntime(605):  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:251)  

22.07-16 15:43:22.026: E/AndroidRuntime(605):  at android.app.Activity.setContentView(Activity.java:1835)  

23.07-16 15:43:22.026: E/AndroidRuntime(605):  at cn.demo.FragmentTestActivity.onCreate(FragmentTestActivity.java:11)  

24.07-16 15:43:22.026: E/AndroidRuntime(605):  at android.app.Activity.performCreate(Activity.java:4465)  

25.07-16 15:43:22.026: E/AndroidRuntime(605):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)  

26.07-16 15:43:22.026: E/AndroidRuntime(605):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)  

27.07-16 15:43:22.026: E/AndroidRuntime(605):  ... 11 more  

28.07-16 15:43:22.026: E/AndroidRuntime(605): Caused by: java.lang.RuntimeException: Content has view with id attribute 'android.R.id.list' that is not a ListView class  

29.07-16 15:43:22.026: E/AndroidRuntime(605):  at android.app.ListFragment.ensureList(ListFragment.java:402)  

30.07-16 15:43:22.026: E/AndroidRuntime(605):  at android.app.ListFragment.onViewCreated(ListFragment.java:203)  

31.07-16 15:43:22.026: E/AndroidRuntime(605):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:811)  

32.07-16 15:43:22.026: E/AndroidRuntime(605):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1010)  

33.07-16 15:43:22.026: E/AndroidRuntime(605):  at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1108)  

34.07-16 15:43:22.026: E/AndroidRuntime(605):  at android.app.Activity.onCreateView(Activity.java:4243)  

35.07-16 15:43:22.026: E/AndroidRuntime(605):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:673)  

36.07-16 15:43:22.026: E/AndroidRuntime(605):  ... 21 more  


        为什么呢?因为ListFragment里面已经提供了系统自带的ListView,这样写,当然出错。可以直接不重写OnCreatView方法,使用getListView()获取系统提供的ListView.


        但是获取的ListView设置Item间隔线只能getListView().setDivider(divider),其参数为Drawable类型。当然如果只想简单的设置下Divider的颜色呢?


        其实ListFragment当然运行自定义布局,但是Listview要用系统的:

[java] view plain copy 

01.<?xml version="1.0" encoding="utf-8"?>  

02.<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  

03.    android:layout_width="fill_parent"  

04.    android:layout_height="fill_parent"  

05.    android:orientation="vertical" >     

07.    <TextView   

08.        android:layout_width="wrap_content"  

09.        android:layout_height="wrap_content"  

10.        android:text="@string/app_name"  

11.        />  

12.    <ListView   

13.        android:id="@id/android:list"  

14.        android:layout_width="fill_parent"  

15.        android:layout_height="fill_parent"  

16.        ></ListView>  

17.</LinearLayout>  

第二个错误:FragmentManagerImpl.saveFragmentBasicState

下面是log:

[java] view plain copy 

01.E/AndroidRuntime(29923): FATAL EXCEPTION: main  

02.E/AndroidRuntime(29923): java.lang.NullPointerException  

03.E/AndroidRuntime(29923):     at android.app.FragmentManagerImpl.saveFragmentBasicState(FragmentManager.java:1544)  

04.E/AndroidRuntime(29923):     at android.app.FragmentManagerImpl.saveAllState(FragmentManager.java:1574)  

05.E/AndroidRuntime(29923):     at android.app.Activity.onSaveInstanceState(Activity.java:1213)  

06.E/AndroidRuntime(29923):     at android.app.Activity.performSaveInstanceState(Activity.java:1162)  

07.E/AndroidRuntime(29923):     at android.app.Instrumentation.callActivityOnSaveInstanceState(Instrumentation.java:1287)  

08.E/AndroidRuntime(29923):     at android.app.ActivityThread.performStopActivityInner(ActivityThread.java:3208)  

09.E/AndroidRuntime(29923):     at android.app.ActivityThread.handleStopActivity(ActivityThread.java:3266)  

10.E/AndroidRuntime(29923):     at android.app.ActivityThread.access$900(ActivityThread.java:139) 

11.E/AndroidRuntime(29923):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1279)  

12.E/AndroidRuntime(29923):     at android.os.Handler.dispatchMessage(Handler.java:99)  

13.E/AndroidRuntime(29923):     at android.os.Looper.loop(Looper.java:156)  

14.E/AndroidRuntime(29923):     at android.app.ActivityThread.main(ActivityThread.java:5005)  

15.E/AndroidRuntime(29923):     at java.lang.reflect.Method.invokeNative(Native Method)  

16.E/AndroidRuntime(29923):     at java.lang.reflect.Method.invoke(Method.java:511)  

17.E/AndroidRuntime(29923):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)  

18.E/AndroidRuntime(29923):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)  

19.E/AndroidRuntime(29923):     at dalvik.system.NativeStart.main(Native Method) 

 

看老半天log,没有琢磨明白,在网上找了下,说出现这个问题,主要是以下两个因素:

一是用了Android.support.v4包, 二是FragmentActivity.

       本人正是在从Fragment跳转到另一个Activity时候报的错,据说是个官方Bug,已经有程序员把这个问题提交到官方了,https://android-review.googlesource.com/#/c/31261/。

下面看看他们提交的内容:       

If a fragment's saved view state is null and the user visible hint is true then the `result` bundle will have never been initialized to a value resulting in a `NullPointerException`.


        如果一个Fragment保存的视图状态为Null并且用户可见提示为true,那么'result' bundle(要保存的Bundle)会有一个微博初始化的值,然后导致空指针异常。


        如何解决此问题呢?问题出在Save上,在有Fragment的Activity中重写onSaveInstanceState()方法,并且注释掉super.onSaveInstanceState(),这样就不会调用父类的onSaveInstanceState(outState)方法了,就不会报异常了。

[java] view plain copy 

01.outState 对象为空..在onSaveInstanceState()函数中不使用到outState即可.  

02.  

03.[java] view plaincopy  

04.@Override    

05.    protected void onSaveInstanceState(Bundle outState) {    

06.        // TODO Auto-generated method stub     

07.        //super.onSaveInstanceState(outState);    

08.            

09.    }    

      在这里,就可以方便的设置listview的各个参数了。

   


公众号,微信

汇鱼网海峡创乐汇
汇鱼网海峡创乐汇