您的位置:首页 > 其它

Fragment状态的保存

2016-01-20 15:32 417 查看
当我们需要切换fragment的时候,官方给我们提供了两种方式:replace和add.

首先来看看replace方法:

replace方法相当于先移除remove()原来所有已存在的fragments,然后添加add()当前这个fragment。这就导致了一个问题,我们切换一次,然后再切换回来,相当于重新加载了这个fragment,原来的状态不复存在,这显然与我们的日常使用不符。先做个实现说明一下这个现象。






最下面是两个按钮,用于切换两个Fragment,第一个Fragment中是一个按钮和一个文字,默认显示为你好吗,点击按钮切换文字为我很好,如图所示




但是当我们点击第二个按钮切换到第二个Fragment,然后在切换回来的时候,发现文字又变成默认的了,这就说明重新实例化了fragment对象,Fragment的状态没有得到保存。

我们在每个Fragment的生命周期的onCreateView方法中打印一行Log

[code]Log.d("Fragment", "FragmentOne------onCreateView");


每次切换Fragment时我们去看控制台是不是都会打印这句话。




可以看到,每次点击按钮切换Fragment时都会调用Fragment的onCreateView生命周期方法。这就说明使用replace方法切换Fragment是无法保存状态的。

代码如下:

[code]public class MainActivity extends FragmentActivity implements OnClickListener {

    private Button bt1;
    private Button bt2;
    private FragmentManager manager;
    private FragmentTransaction transaction;
    FragmentOne fragmentOne;
    FragmentTwo fragmentTwo;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bt1 = (Button) findViewById(R.id.bt1);
        bt2 = (Button) findViewById(R.id.bt2);
        bt1.setOnClickListener(this);
        bt2.setOnClickListener(this);
        manager = getSupportFragmentManager();
        // 默认选中第一个按钮
        bt1.performClick();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.bt1:
            if (fragmentOne == null) {
                fragmentOne = new FragmentOne();
            }
            transaction = manager.beginTransaction();
            transaction.replace(R.id.fl_content, fragmentOne);
            break;
        case R.id.bt2:
            if (fragmentTwo == null) {
                fragmentTwo = new FragmentTwo();
            }
            transaction = manager.beginTransaction();
            transaction.replace(R.id.fl_content, fragmentTwo);
            break;
        }
        transaction.commit();
    }
}


接下来看看add方法:

使用add的时候要和hide和show方法结合起来使用,使用hide隐藏原来的fragment,使用show显示你想要的fragment.

通过实验发现当第一个framgment里面的文字改变之后,在切换回来文字的状态依然是显示为我很好。而且通过控制台我们可以看到两个fragment的onCreateView方法只是在第一次点击按钮的时候会调用,下次切换不在调用。




说明采用add方法很好的保存的fragment的状态,避免每次去实例化新的对象。

代码如下:

[code]public class MainActivity extends FragmentActivity implements OnClickListener{

    private Button bt1;
    private Button bt2;
    //代表当前的fragment
    private Fragment content;
    FragmentOne fragmentOne;
    FragmentTwo fragmentTwo;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bt1 = (Button) findViewById(R.id.bt1);
        bt2 = (Button) findViewById(R.id.bt2);
        bt1.setOnClickListener(this);
        bt2.setOnClickListener(this);
        content = new FragmentOne();
        //默认选中第一个Fragment
        bt1.performClick();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.bt1:
            if(fragmentOne == null){
                fragmentOne = new FragmentOne();
            }
            switchContent(content, fragmentOne);
            break;
        case R.id.bt2:
            if(fragmentTwo == null){
                fragmentTwo = new FragmentTwo();
            }
            switchContent(content, fragmentTwo);
            break;
        }
    }
    /**
     * 切换fragment
     * @param from 要隐藏的fragment
     * @param to 要显示的fragment
     */
    public void switchContent(Fragment from, Fragment to){
        if(content!=to){
            content =to;
            FragmentTransaction transaction= getSupportFragmentManager().beginTransaction();
            //此处必须要进行判断,因为同一个fragment只能被add一次,否则会发生异常
            if(!to.isAdded()){
                //未添加
                transaction.hide(from).add(R.id.fl_content, to).commit();
            }else{
                //添加过直接显示
                transaction.hide(from).show(to).commit();
            }
        }
    }
}


但是,在使用add的时候,作为容器的FrameLayout其实有2层,使用replace的话只有一层,多层肯定比一层来的浪费。具体使用什么方法还是看具体的需求吧!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: