您的位置:首页 > 移动开发 > Android开发

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

2016-08-11 21:29 344 查看
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加载图片适配问题。

希望这个博客能帮到你。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Android
相关文章推荐