Android Fragment的子fragment之间切换保存状态遇到的坑
2016-08-11 21:29
344 查看
1.最近在做公司项目,记录下自己认为有价值的问题。现在软件一般都是viewpager+fragment组成的tab样式。在其中一个fragment里面。有俩个子fragment通过点击事件,来切换。当然肯定不能每次切换都要重新创建一个fragment,尤其这个fragment里面有网路请求的时候。更不能如此。现在我先把演示下自己遇到的问题。
当再次回到最后一个tab的时候,fragment3和fragment2 重合了。最后一个fragment的代码如下:
通过一番查资料。我知道了fragment会调用 onSaveInstanceState() ,将fragment的一些数据保存在Bundle,对象中这点和activity一样。onsave方法 会在onpause()这个方法被调用的时候调用。因此当你再次进入时候,fragment会把bundle里面的数据取出来,因此看到的fragment2
和fragment3重合了。知道了这个原因之后。我们可以在ondestoryView()里面把。子fragment都清除掉,从而bundle里面的数据为空。基于这个思想改进的代码如下:
@Override
public void onDestroyView() {
// TODO Auto-generated method stub
super.onDestroyView();
fg=getChildFragmentManager();
transaction=fg.beginTransaction();
transaction.detach(message);
transaction.detach(server);
transaction.commit();
}主要是对ondestroyview 方法的改进。运行之后报一个异常,异常的大概意思是。当insaveinstancestate方法被调用之后不能再调用事务的commit()方法了。但是
我们可以调用这个commit方法:
transaction.commitAllowingStateLoss(); 之后运行就没得问题了。这是我在做项目中遇到的比较有意思的问题。
过俩天在分享下。scrollview+viewpager里面的坑。以及调用webview加载图片适配问题。
希望这个博客能帮到你。
当再次回到最后一个tab的时候,fragment3和fragment2 重合了。最后一个fragment的代码如下:
package com.fragment; /* * @author:wxy * time:22:30 */ import com.example.bishe.R; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.Button; import android.widget.Toast; public class Fragment_Me extends Fragment implements OnClickListener{ Button but1; Button but2; Fragment_Server server; Fragment_Message message; FragmentManager fg; FragmentTransaction transaction; View mview; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { mview=inflater.inflate(R.layout.fragment_me, container, false); but1=(Button) mview.findViewById(R.id.but1); but2=(Button) mview.findViewById(R.id.but2); but1.setOnClickListener(this); but2.setOnClickListener(this); server=new Fragment_Server(); message=new Fragment_Message(); fg=getChildFragmentManager(); transaction=fg.beginTransaction(); if (!server.isAdded()) { transaction.add(R.id.fragment, server); Toast.makeText(getActivity(), "server没有被添加", Toast.LENGTH_SHORT).show(); } if (!message.isAdded()) { transaction.add(R.id.fragment, message); Toast.makeText(getActivity(), "message没有被添加", Toast.LENGTH_SHORT).show(); } transaction.show(server); transaction.hide(message); transaction.commit(); return mview; } @Override public void onClick(View v) { <span style="background-color: rgb(153, 255, 153);">fg=getChildFragmentManager(); transaction=fg.beginTransaction(); switch (v.getId()) { case R.id.but1: transaction.hide(message); transaction.show(server); break; case R.id.but2: transaction.hide(server); transaction.show(message); break; } transaction.commit(); </span> } @Override public void onDestroyView() { // TODO Auto-generated method stub super.onDestroyView(); Toast.makeText(getActivity(), "88", Toast.LENGTH_SHORT).show(); ((ViewGroup) mview.getParent()).removeView(mview); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); Toast.makeText(getActivity(), "34", Toast.LENGTH_SHORT).show(); } }通过调用transaction的hide,show方法来实现切换保存fragment的状态。然而在这里并不行。当再次回到“我”的那个fragment的时候,子fragment界面重复了。出现这个问题问过其他的人,但是却被鄙视了一番都说用hide,show可以实现。叫我看博客。但是实际上不是那么简单的。
通过一番查资料。我知道了fragment会调用 onSaveInstanceState() ,将fragment的一些数据保存在Bundle,对象中这点和activity一样。onsave方法 会在onpause()这个方法被调用的时候调用。因此当你再次进入时候,fragment会把bundle里面的数据取出来,因此看到的fragment2
和fragment3重合了。知道了这个原因之后。我们可以在ondestoryView()里面把。子fragment都清除掉,从而bundle里面的数据为空。基于这个思想改进的代码如下:
@Override
public void onDestroyView() {
// TODO Auto-generated method stub
super.onDestroyView();
fg=getChildFragmentManager();
transaction=fg.beginTransaction();
transaction.detach(message);
transaction.detach(server);
transaction.commit();
}主要是对ondestroyview 方法的改进。运行之后报一个异常,异常的大概意思是。当insaveinstancestate方法被调用之后不能再调用事务的commit()方法了。但是
我们可以调用这个commit方法:
transaction.commitAllowingStateLoss(); 之后运行就没得问题了。这是我在做项目中遇到的比较有意思的问题。
过俩天在分享下。scrollview+viewpager里面的坑。以及调用webview加载图片适配问题。
希望这个博客能帮到你。
相关文章推荐
- Android使用Fragment来实现ViewPager的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信
- Android使用Fragment来实现TabHost的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信
- Android使用Fragment来实现ViewPager的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信
- Android使用Fragment来实现TabHost的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信
- Android使用Fragment来实现TabHost的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信
- Android使用Fragment来实现ViewPager的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信
- Android使用Fragment来实现TabHost的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信
- Android使用Fragment来实现TabHost的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信
- Android使用Fragment来实现TabHost的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信
- Android使用Fragment来实现TabHost的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信
- Android使用Fragment来实现TabHost的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信
- Android使用Fragment来实现TabHost的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信
- Android使用Fragment来实现TabHost的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信
- Android使用Fragment来实现TabHost的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信
- Android使用Fragment来实现TabHost的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信
- Android使用Fragment来实现ViewPager的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信
- Android使用Fragment来实现TabHost的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信
- 【转】Android使用Fragment来实现ViewPager的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信
- Android使用Fragment来实现TabHost的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信
- android fragment切换无法保存状态的一种解决方法