【Android】保存Fragment切换状态
前言
一般频繁切换Fragment会导致频繁的释放和创建,如果Fragment比较臃肿体验就非常不好了,这里分享一个方法。
声明
欢迎转载,但请保留文章原始出处:)
博客园:
农民伯伯:
正文
一、应用场景
1、不使用ViewPager
2、不能用replace来切换Fragment,会导致Fragment释放(调用onDestroyView)
二、实现
1、xml
<LinearLayoutxmlns:android="/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事件,其他代码:
@Override
publicvoidonCheckedChanged(CompoundButtonbuttonView,booleanisChecked){
if(isChecked){
Fragmentfragment=(Fragment)mFragmentPagerAdapter.instantiateItem(mContainer,buttonView.getId());
mFragmentPagerAdapter.setPrimaryItem(mContainer,0,fragment);
mFragmentPagerAdapter.finishUpdate(mContainer);
}
}
privateFragmentPagerAdaptermFragmentPagerAdapter=newFragmentPagerAdapter(getSupportFragmentManager()){
@Override
publicFragmentgetItem(intposition){
switch(position){
caseR.id.radio_button1:
returnnewFragment1();
caseR.id.radio_button2:
returnnewFragment2();
caseR.id.radio_button3:
returnnewFragment3();
caseR.id.radio_button4:
returnnewFragment4();
caseR.id.radio_button0:
default:
returnnewFragment0();
}
}
@Override
publicintgetCount(){
return5;
}
};
代码说明:
instantiateItem从FragmentManager中查找Fragment,找不到就getItem新建一个,setPrimaryItem设置隐藏和显示,最后finishUpdate提交事务。
mContainer就是xml中的FrameLayout。
三、FragmentPagerAdapter核心代码
@Override
publicObjectinstantiateItem(ViewGroupcontainer,intposition){
if(mCurTransaction==null){
mCurTransaction=mFragmentManager.beginTransaction();
}
finallongitemId=getItemId(position);
//Dowealreadyhavethisfragment?
Stringname=makeFragmentName(container.getId(),itemId);
Fragmentfragment=mFragmentManager.findFragmentByTag(name);
if(fragment!=null){
if(DEBUG)Log.v(TAG,"Attachingitem#"+itemId+":f="+fragment);
mCurTransaction.attach(fragment);
}else{
fragment=getItem(position);
if(DEBUG)Log.v(TAG,"Addingitem#"+itemId+":f="+fragment);
mCurTransaction.add(container.getId(),fragment,
makeFragmentName(container.getId(),itemId));
}
if(fragment!=mCurrentPrimaryItem){
fragment.setMenuVisibility(false);
fragment.setUserVisibleHint(false);
}
returnfragment;
}
@Override
publicvoiddestroyItem(ViewGroupcontainer,intposition,Objectobject){
if(mCurTransaction==null){
mCurTransaction=mFragmentManager.beginTransaction();
}
if(DEBUG)Log.v(TAG,"Detachingitem#"+getItemId(position)+":f="+object
+"v="+((Fragment)object).getView());
mCurTransaction.detach((Fragment)object);
}
@Override
publicvoidsetPrimaryItem(ViewGroupcontainer,intposition,Objectobject){
Fragmentfragment=(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
publicvoidfinishUpdate(ViewGroupcontainer){
if(mCurTransaction!=null){
mitAllowingStateLoss();
mCurTransaction=null;
mFragmentManager.executePendingTransactions();
}
}
FragmentPagerAdapter是support包自带的类。
四、注意
之前自己模拟ViewPager用attach、setMenuVisibility、setUserVisibleHint来控制Fragment的显示隐藏,经常会出现Fragment重叠现象,非常头疼,换了这个之后目前没有发现重叠现象。
五、文章后期维护
-12-01 上传示例代码:/over140/SampleFragmentSwitch.zip
@Override
publicvoidsetMenuVisibility(booleanmenuVisible){
super.setMenuVisibility(menuVisible);
if(this.getView()!=null)
this.getView().setVisibility(menuVisible?View.VISIBLE:View.GONE);
}
重新做例子时发现自己也出不来效果了,后来发现少了这段代码。
-01-08 想实现本文的效果还是推荐直接使用ViewPager,通过自定义ViewPager禁用掉左右滑动和自动销毁即可,根据评论来看非正常情况下重影现象还是挺严重的。
结束
需要多看看源码,才能很好的解决问题。
/over140/p/3362047.html
如果觉得《【Android】保存Fragment切换状态》对你有帮助,请点赞、收藏,并留下你的观点哦!