欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android 保存Fragment 切换状态实例代码

程序员文章站 2024-03-06 09:31:49
前言  一般频繁切换fragment会导致频繁的释放和创建,如果fragment比较臃肿体验就非常不好了,这里分享一个方法。  正文  ...

前言

 一般频繁切换fragment会导致频繁的释放和创建,如果fragment比较臃肿体验就非常不好了,这里分享一个方法。

 正文

 一、应用场景

  1、不使用viewpager

  2、不能用replace来切换fragment,会导致fragment释放(调用ondestroyview)

 二、实现

1、xml

<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical" >

 <framelayout
  android:id="@+id/container"
  android:layout_width="match_parent"
  android:layout_height="0dip"
  android:layout_weight="1.0" >
 </framelayout>

 <radiogroup
  android:id="@+id/main_radio"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:layout_gravity="bottom"
  android:gravity="bottom"
  android:layout_marginbottom="-6dp"
  android:orientation="horizontal" >

  <radiobutton
   android:id="@+id/radio_button0"
   style="@style/main_tab_bottom"
   android:drawabletop="@drawable/bottom_1" />

  <radiobutton
   android:id="@+id/radio_button1"
   style="@style/main_tab_bottom"
   android:drawabletop="@drawable/bottom_2" />

  <radiobutton
   android:id="@+id/radio_button2"
   style="@style/main_tab_bottom"
   android:drawabletop="@drawable/bottom_3" />

  <radiobutton
   android:id="@+id/radio_button3"
   style="@style/main_tab_bottom"
   android:drawabletop="@drawable/bottom_4" />

  <radiobutton
   android:id="@+id/radio_button4"
   style="@style/main_tab_bottom"
   android:drawabletop="@drawable/bottom_5" />
 </radiogroup>

</linearlayout>

代码说明:

    非常常见的底部放5个radiobutton,点击切换不同的fragment。

  2、activity

   为radiobutton设置setoncheckedchangelistener事件,其他代码:

 public void oncheckedchanged(compoundbutton buttonview, boolean ischecked) {
  if (ischecked) {
   fragment fragment = (fragment) mfragmentpageradapter.instantiateitem(mcontainer, buttonview.getid());
   mfragmentpageradapter.setprimaryitem(mcontainer, 0, fragment);
   mfragmentpageradapter.finishupdate(mcontainer);
  } 
 }

 private fragmentpageradapter mfragmentpageradapter = new fragmentpageradapter(getsupportfragmentmanager()) {

  @override
  public fragment getitem(int position) {
   switch (position) {
   case r.id.radio_button1:
    return new fragment1();
   case r.id.radio_button2:
    return new fragment2();
   case r.id.radio_button3:
    return new fragment3();
   case r.id.radio_button4:
    return new fragment4();
   case r.id.radio_button0:
   default:
    return new fragment0();
   }
  }

  @override
  public int getcount() {
   return 5;
  }
 };

代码说明:

   instantiateitem从fragmentmanager中查找fragment,找不到就getitem新建一个,setprimaryitem设置隐藏和显示,最后finishupdate提交事务, mcontainer就是xml中的framelayout。

 三、fragmentpageradapter核心代码

 @override
 public object instantiateitem(viewgroup container, int position) {
  if (mcurtransaction == null) {
   mcurtransaction = mfragmentmanager.begintransaction();
  }

  final long itemid = getitemid(position);

  // do we already have this fragment?
  string name = makefragmentname(container.getid(), itemid);
  fragment fragment = mfragmentmanager.findfragmentbytag(name);
  if (fragment != null) {
   if (debug) log.v(tag, "attaching item #" + itemid + ": f=" + fragment);
   mcurtransaction.attach(fragment);
  } else {
   fragment = getitem(position);
   if (debug) log.v(tag, "adding item #" + itemid + ": f=" + fragment);
   mcurtransaction.add(container.getid(), fragment,
     makefragmentname(container.getid(), itemid));
  }
  if (fragment != mcurrentprimaryitem) {
   fragment.setmenuvisibility(false);
   fragment.setuservisiblehint(false);
  }

  return fragment;
 }

 @override
 public void destroyitem(viewgroup container, int position, object object) {
  if (mcurtransaction == null) {
   mcurtransaction = mfragmentmanager.begintransaction();
  }
  if (debug) log.v(tag, "detaching item #" + getitemid(position) + ": f=" + object
    + " v=" + ((fragment)object).getview());
  mcurtransaction.detach((fragment)object);
 }

 @override
 public void setprimaryitem(viewgroup container, int position, object object) {
  fragment fragment = (fragment)object;
  if (fragment != mcurrentprimaryitem) {
   if (mcurrentprimaryitem != null) {
    mcurrentprimaryitem.setmenuvisibility(false);
    mcurrentprimaryitem.setuservisiblehint(false);
   }
   if (fragment != null) {
    fragment.setmenuvisibility(true);
    fragment.setuservisiblehint(true);
   }
   mcurrentprimaryitem = fragment;
  }
 }

 @override
 public void finishupdate(viewgroup container) {
  if (mcurtransaction != null) {
   mcurtransaction.commitallowingstateloss();
   mcurtransaction = null;
   mfragmentmanager.executependingtransactions();
  
} 
 public void setmenuvisibility(boolean menuvisible) {
        super.setmenuvisibility(menuvisible);
        if (this.getview() != null)
            this.getview().setvisibility(menuvisible ? view.visible : view.gone);
    } }

fragmentpageradapter是support包自带的类。

四、注意

  之前自己模拟viewpager用attach、setmenuvisibility、setuservisiblehint来控制fragment的显示隐藏,经常会出现fragment重叠现象,非常头疼,换了这个之后目前没有发现重叠现象。

 结束:以上就是对android fragment 实例说明,希望能帮助有需要的同学。