Android Fragment的子fragment之间切换保存状态遇到的坑

1.最近在做公司项目,记录下自己认为有价值的问题。现在软件一般都是viewpager+fragment组成的tab样式。在其中一个fragment里面。有俩个子fragment通过点击事件,来切换。当然肯定不能每次切换都要重新创建一个fragment,尤其这个fragment里面有网路请求的时候。更不能如此。现在我先把演示下自己遇到的问题。


当再次回到最后一个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加载图片适配问题。


希望这个博客能帮到你。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值