一些用fragment的注意事项

Posted 台风中的橘子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一些用fragment的注意事项相关的知识,希望对你有一定的参考价值。

自从fragment出现以来现在越来越多的项目用了这个东西,下面总结一下遇到的一些问题和解决方案如果有更好的解决办法 欢迎回复

1    fragment刷新问题 动态创建fragment 调用m FragmentPagerAdapter. notifyDataSetChanged 发现部分,或者全部的fragment没有变化
这种情况一般出现在fragment1,fragment2,fragment3.....
当某些情况下 fragment2 里面数据元素发生了改变,导致UI需要更改,这个时候我们需要和listview一样调用 m FragmentPagerAdapter. notifyDataSetChanged
原因是 fragment2已经创建(如果显示过),系统会在 FragmentManager里面去找已经创建过的对象,如果存在那么再次需要显示时候直接找以前的对象

源码这样:
[mw_shl_code=java,true]    String name = makeFragmentName(container.getId(), position);
    Fragment fragment = mFragmentManager.findFragmentByTag(name);
    if (fragment != null)
        if (DEBUG) Log.v(TAG, "Attaching item #" + position + ": f=" + fragment);
        mCurTransaction.attach(fragment);
    else
        fragment = getItem(position);
        if (DEBUG) Log.v(TAG, "Adding item #" + position + ": f=" + fragment);
        mCurTransaction.add(container.getId(), fragment,
                makeFragmentName(container.getId(), position));
    [/mw_shl_code]

所以 为了解决这个问题 有种方法一种是改变tag,还一种直接清空以前对象(fm 是构造方法传递的FragmentManager
[mw_shl_code=java,true]public void setFragments(ArrayList<Fragment> fragments)
    if(this.fragments != null)
        FragmentTransaction ft = fm.beginTransaction();
        for(Fragment f:this.fragments)
            ft.remove(f);
        
        ft.commit();
        ft=null;
        fm.executePendingTransactions();
   
    this.fragments = fragments;
    notifyDataSetChanged();
[/mw_shl_code]
2    横竖屏切换时候空指针问题
我们在用Activity时候,横竖屏切换会导致调用oncreate(未对activity做任何设置时候),
fragmentActivity也有类似问题,他还会导致fragment我们用构造方法传递的数据清空
原因当横竖屏切换是 当前Fragment Activity中的fragment都会通过Fragment.instantiate重新生成, 方法将使用默认的构造函数 onCreate 来生成相应的Fragment 如果创建fragment 没有继承这个,那么重新生成的就不会得到你赋的值,那么在你调用的时候就会空指针了
下面是我的解决方法
[mw_shl_code=java,true]public String imgPath;
public String imgId;
public static DetailFragment newInstance(String id,String path)
    DetailFragment f = new DetailFragment();
    // Supply num input as an argument.
    Bundle args = new Bundle();
    args.putString("id", id);
    args.putString("path", path);
    f.setArguments(args);
    return f;


public void onCreate(Bundle savedInstanceState)
    super.onCreate(savedInstanceState);

    Bundle bundle = getArguments();
    if (bundle != null)
        imgId = bundle.getString("id");
        imgPath = bundle.getString("path");
   
[/mw_shl_code]


3   FragmentActivity  横竖屏切换事件不触发问题
这个问题简单 mainfest.xml文件修改下activity配置 多了一个属性
android:configChanges="orientation|keyboard|keyboardHidden|screenSize"

4   FragmentActivity  与fragment之间信息传递
这个问题没什么好研究的就会接口
[mw_shl_code=java,true]public interface SetShowDataTypeListener
      public void setDataType(int position);
  
  SetShowDataTypeListener mCallback;

btn.setOnClickListener(new OnClickListener()
           
          @Override
          public void onClick(View v)
              mCallback.setDataType(0);
         
      );
  @Override
  public void onAttach(Activity activity)
      super.onAttach(activity);
       
      // This makes sure that the container activity has implemented
      // 确认容器activity已经实现接口

      // the callback interface. If not, it throws an exception
      // 回调接口。如果没有,抛出异常

      try
          mCallback = (SetShowDataTypeListener) activity;
       catch (ClassCastException e)
          throw new ClassCastException(activity.toString() + " must implement SetShowDataTypeListener");
      
  [/mw_shl_code]



5   在情况3中 如果这个fragment未创建,在activity里面去试图访问属性会出错
fragment1,fragment2,fragment3 ,fragment4..fragmentN
如果我有这么多个fragment 我在某些情况下需要方法fragmentN的impath数据 imgPath ,因为这个fragment还未创建,这个时候imgPath就是null
可以这样在创建的时候赋值


[mw_shl_code=java,true]public static DetailFragment newInstance(String id,String path)
    DetailFragment f = new DetailFragment();
f.id = id;
f.imgPath = path;
    // Supply num input as an argument.
    Bundle args = new Bundle();
    args.putString("id", id);
    args.putString("path", path);
    f.setArguments(args);
    return f;
[/mw_shl_code]
6   Fragment生命周期 

有些人可能觉得这个生命周期和官网给的不一致,其实原因是fragment有缓存,这个和activity不一样。如果某一个fragment未被释放就会直接显示,和生命周期的图完全不一样,大家可以打印log看看

可能实际开发还好有其它问题,还有一些其它的注意事项可以看看论坛的别人帖子,这里就不写了,在中和这些就可以搞定了
7  
这段时间看到论坛很多人问到fragment 加载listview ,滑动或者replace再加载以后 ,listview不显示或者adapter不调用getview等等问题

其实这个还是fragment缓存问题,fragment把内部加载的view释放了,这个时候需要重新加载一次
这样就可以了
在fragment的这个方法onActivityCreated
添加类似
if(mAdapter == null)

   // initAdapter


mlistview.setAdapter(mAdapter)

以上是关于一些用fragment的注意事项的主要内容,如果未能解决你的问题,请参考以下文章

Android Toolbar使用及Fragment中的Toolbar处理

Fragment中的一些问题

Android Fragment 的使用,一些你不可不知的注意事项

Android Fragment 深度解析

Fragment用app包还是v4包解析

Activity与Fragment易混点归纳