HardBirch

那些年,在Fragment中犯的错

时间:12-07-16 栏目:安卓源码解析与小应用 作者:张飞不张,文采横飞 评论:9 点击: 4,796 次

其实有些方法也是从网上找来的,拿来主义,共同分享下(Fragment其他资料:android之Fragment(官网资料翻译))。

第一个错误:FragmentManagerImpl.saveFragmentBasicState

下面是log:

        

E/AndroidRuntime(29923): FATAL EXCEPTION: main
E/AndroidRuntime(29923): java.lang.NullPointerException
E/AndroidRuntime(29923):     at android.app.FragmentManagerImpl.saveFragmentBasicState(FragmentManager.java:1544)
E/AndroidRuntime(29923):     at android.app.FragmentManagerImpl.saveAllState(FragmentManager.java:1574)
E/AndroidRuntime(29923):     at android.app.Activity.onSaveInstanceState(Activity.java:1213)
E/AndroidRuntime(29923):     at android.app.Activity.performSaveInstanceState(Activity.java:1162)
E/AndroidRuntime(29923):     at android.app.Instrumentation.callActivityOnSaveInstanceState(Instrumentation.java:1287)
E/AndroidRuntime(29923):     at android.app.ActivityThread.performStopActivityInner(ActivityThread.java:3208)
E/AndroidRuntime(29923):     at android.app.ActivityThread.handleStopActivity(ActivityThread.java:3266)
E/AndroidRuntime(29923):     at android.app.ActivityThread.access$900(ActivityThread.java:139)
E/AndroidRuntime(29923):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1279)
E/AndroidRuntime(29923):     at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(29923):     at android.os.Looper.loop(Looper.java:156)
E/AndroidRuntime(29923):     at android.app.ActivityThread.main(ActivityThread.java:5005)
E/AndroidRuntime(29923):     at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(29923):     at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(29923):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
E/AndroidRuntime(29923):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
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)方法了,就不会报异常了。

 

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

[java] view plaincopy
@Override
    protected void onSaveInstanceState(Bundle outState) {
        // TODO Auto-generated method stub
        //super.onSaveInstanceState(outState);  

    }

第二个、使用ListFragment:java.lang.RuntimeException: Content has view with id attribute 'android.R.id.list' that is not a ListView class

            在ListFragment中,想当然的以为,像其他Fragment一样:

 

public class ListFragmentTest extends ListFragment {

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View root = inflater.inflate(R.layout.list, null);
		return root;
	}

在list.xml里面

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/app_name"
        />
    <ListView
        android:id="@+id/list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        ></ListView>
</LinearLayout>

看下log:

 

07-16 15:43:22.026: E/AndroidRuntime(605): FATAL EXCEPTION: main
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
07-16 15:43:22.026: E/AndroidRuntime(605): 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
07-16 15:43:22.026: E/AndroidRuntime(605): 	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
07-16 15:43:22.026: E/AndroidRuntime(605): 	at android.app.ActivityThread.access$600(ActivityThread.java:123)
07-16 15:43:22.026: E/AndroidRuntime(605): 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
07-16 15:43:22.026: E/AndroidRuntime(605): 	at android.os.Handler.dispatchMessage(Handler.java:99)
07-16 15:43:22.026: E/AndroidRuntime(605): 	at android.os.Looper.loop(Looper.java:137)
07-16 15:43:22.026: E/AndroidRuntime(605): 	at android.app.ActivityThread.main(ActivityThread.java:4424)
07-16 15:43:22.026: E/AndroidRuntime(605): 	at java.lang.reflect.Method.invokeNative(Native Method)
07-16 15:43:22.026: E/AndroidRuntime(605): 	at java.lang.reflect.Method.invoke(Method.java:511)
07-16 15:43:22.026: E/AndroidRuntime(605): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
07-16 15:43:22.026: E/AndroidRuntime(605): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
07-16 15:43:22.026: E/AndroidRuntime(605): 	at dalvik.system.NativeStart.main(Native Method)
07-16 15:43:22.026: E/AndroidRuntime(605): Caused by: android.view.InflateException: Binary XML file line #23: Error inflating class fragment
07-16 15:43:22.026: E/AndroidRuntime(605): 	at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:697)
07-16 15:43:22.026: E/AndroidRuntime(605): 	at android.view.LayoutInflater.rInflate(LayoutInflater.java:739)
07-16 15:43:22.026: E/AndroidRuntime(605): 	at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
07-16 15:43:22.026: E/AndroidRuntime(605): 	at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
07-16 15:43:22.026: E/AndroidRuntime(605): 	at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
07-16 15:43:22.026: E/AndroidRuntime(605): 	at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:251)
07-16 15:43:22.026: E/AndroidRuntime(605): 	at android.app.Activity.setContentView(Activity.java:1835)
07-16 15:43:22.026: E/AndroidRuntime(605): 	at cn.demo.FragmentTestActivity.onCreate(FragmentTestActivity.java:11)
07-16 15:43:22.026: E/AndroidRuntime(605): 	at android.app.Activity.performCreate(Activity.java:4465)
07-16 15:43:22.026: E/AndroidRuntime(605): 	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
07-16 15:43:22.026: E/AndroidRuntime(605): 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
07-16 15:43:22.026: E/AndroidRuntime(605): 	... 11 more
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
07-16 15:43:22.026: E/AndroidRuntime(605): 	at android.app.ListFragment.ensureList(ListFragment.java:402)
07-16 15:43:22.026: E/AndroidRuntime(605): 	at android.app.ListFragment.onViewCreated(ListFragment.java:203)
07-16 15:43:22.026: E/AndroidRuntime(605): 	at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:811)
07-16 15:43:22.026: E/AndroidRuntime(605): 	at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1010)
07-16 15:43:22.026: E/AndroidRuntime(605): 	at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1108)
07-16 15:43:22.026: E/AndroidRuntime(605): 	at android.app.Activity.onCreateView(Activity.java:4243)
07-16 15:43:22.026: E/AndroidRuntime(605): 	at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:673)
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要用系统的:

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/app_name"
        />
    <ListView
        android:id="@id/android:list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        ></ListView>
</LinearLayout>

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


声明: 本文由( 张飞不张,文采横飞 )原创编译,转载请保留链接: 那些年,在Fragment中犯的错

那些年,在Fragment中犯的错:目前有9 条留言

  1. 9楼
    A328240784:

    ~有时候有机会用到fragment,但骨子里还是不愿意使用,宁愿用两个image作为Tab

    2012-07-17 12:42 [回复]
  2. [reply]A328240784[/reply]
    有时候在4.0里面用Fragment还挺好使的。

    2012-07-17 13:10 [回复]
  3. 7楼
    A328240784:

    [reply]aomandeshangxiao[/reply]
    左右拖动效果并且嵌套listview,不用它还真不好搞~~

    2012-07-17 14:23 [回复]
  4. [reply]A328240784[/reply]
    使用ViewPager阿。。。。不就滑动了吗。。

    2012-07-17 14:35 [回复]
  5. 5楼
    A328240784:

    [reply]aomandeshangxiao[/reply]
    也木有用过。。。好像是v4包的东西?我现在大部分知道的都是2.2的= =四个月没事干了。listview里面嵌套了两个button,好像可以让listview本身不处理点击,让button自己处理是吧?

    2012-07-17 15:38 [回复]
  6. [reply]A328240784[/reply]
    恩,你使用Button的话,会屏蔽LIst Item获取焦点,相应不了OnitemClickListener。

    2012-07-17 17:16 [回复]
  7. 地板
    see2851:

    Android平板开发需要用到这个吗?

    2012-07-17 21:46 [回复]
  8. [reply]see2851[/reply]
    4.0以上的系统,都可以用Fragment啊,当然,也可以不用。

    2012-07-17 21:57 [回复]
  9. [reply]hanjiang387_hust[/reply]
    火星人???

    2012-07-26 15:23 [回复]

发表评论


QQ群互动

Linux系统与内核学习群:194051772

WP建站技术学习交流群:194062106

魔豆之路QR

魔豆的Linux内核之路

魔豆的Linux内核之路

优秀工程师当看优秀书籍

优秀程序员,要看优秀书!

赞助商广告

友荐云推荐