Fragment踩坑:使用hide()和show()而不使用replace() 以及偶现重叠问题

在项目中fragmen的使用已经非常常见了。但是往往图方便用的是replace的方法进行的。方便是方便,但是replace是一个替换的过程,意思是remove掉当前的fragment,重新初始化一个new fragment进行替换,会重复完全执行新的fragment的生命周期。The new fragment to place in the container.官方文档解释说:replace()这个方法只是在上一个Fragment不再需要时采用的简便方法。所以我们这里的思路往往是,add(),切换时hide()当前的碎片,show()想展示的碎片。

1、replace()

   /**
     * 设置fragment
     *
     * @param frg 碎片
     */
    private void setFragment(Fragment frg) {
        //开启Fragment事务
       FragmentTransaction transaction =             fm.beginTransaction();
        transaction.replace(R.id.fra_counselor, frg);
        transaction.commit();//提交
    }
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

2、switchContent(hide&&show)

    /**
     * fragment 切换
     *
     * @param from
     * @param to
     */
    public void switchContent(Fragment from, Fragment to, int position) {
        if (mContent != to) {
            mContent = to;
            FragmentTransaction transaction = fm.beginTransaction();
            if (!to.isAdded()) { // 先判断是否被add过
                transaction.hide(from)
                        .add(R.id.fra_counselor, to, tags[position]).commit(); // 隐藏当前的fragment,add下一个到Activity中
            } else {
                transaction.hide(from).show(to).commit(); // 隐藏当前的fragment,显示下一个
            }
        }
    }
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

注意:mContent是当前显示的fragment。tags是我们add()的时候记录的tags。由于一个容器添加多个fragment的id是相同的,所以只能通过手动添加tag来区分这些fragment。

3、ok。这里会有一个普遍的问题。fragment重叠的情况。
这是由于在手机内存不足的时候Activity被回收后重启所导致的Fragment重复创建和重叠的问题。
在Activity onCreate()中添加Fragment的时候一定不要忘了检查一下savedInstanceState,通过savedInstanceState是否为空来判断填充当前的状态。如果为空,则填充当前的context,若不为空,我们可以通过add时候的tag来找到对应的fragmemt,所有的碎片实例都是存在于内存中的,只是由于失去引用再次启动它的引用被销毁了。我们只要找到赋值给对应的碎片,再通过保存的状态来hide和show就好了。比较容易理解
我们这里采用的方式是:通过getSupportFragmentManager()找到所有的 Fragment,按记录的context碎片show()某一个Fragment,hide()其他所有的fragment。

   /**
     * 状态检测 用于内存不足时activity被回收重启的时候保证fragment   不会重叠
     */
    private void stateCheck(Bundle saveInstanceState) {
        if (saveInstanceState == null) {
            FragmentTransaction frs = fm.beginTransaction();
            mContent = mSaleCounselorF;
            frs.add(R.id.fra_counselor, mContent);
            frs.commit();
        } else {
            //通过tag找回失去引用但是存在内存中的fragment.id相同
            CounselorFrag counselorSaleFrag = (CounselorFrag) getSupportFragmentManager().findFragmentByTag(tags[0]);
            CounselorFrag counselorServerFrag = (CounselorFrag) getSupportFragmentManager().findFragmentByTag(tags[1]);
        getSupportFragmentManager().beginTransaction().show(counselorSaleFrag).hide(counselorServerFrag).commit();
        }
    }
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

4、完整的代码片给下好了,可优化:

package com.xxx.xxx.usercenter;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.content.ContextCompat;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RadioGroup;
import android.widget.TextView;

import com.coofond.carservices.R;
import com.coofond.carservices.baseobj.BaseAct;
import com.coofond.carservices.common.Constant;
import com.coofond.carservices.utils.JumpActivityUtil;
import com.coofond.carservices.utils.SharedPreferencesUtil;
import com.coofond.carservices.widget.AutoRadioGroup;

/**
 * @description: 私家顾问
 * @Author zsj on 2017/3/1 14:48.
 */

public class MyCounselorAct extends BaseAct {

    private CounselorFrag mSaleCounselorF;//销售顾问
    private CounselorFrag mServerCounselorF;//服务顾问
    private AutoRadioGroup ragCounselor;//切换顾问
    private Fragment mContent;//记录选中的fragment
    private FragmentManager fm;//fragement管理器
    private String[] tags = new String[]{Constant.PRECONSULANT, Constant.AFTERCONSULTANTID};
    //使用tab记录下标,由于每个fragment的id都是一样的。用tab区分

    @Override
    protected int getLayoutId() {
        return R.layout.act_mycounselor;
    }

    @Override
    protected void initView() {
        fraCounselor = getView(R.id.fra_counselor);
        ragCounselor = getView(R.id.rag_counselor);
    }

    @Override
    protected void initData() {
        //默认销售顾问
        if (mSaleCounselorF == null) {
            mSaleCounselorF = new CounselorFrag();
            Bundle bundle = new Bundle();
            bundle.putString("type", Constant.PRECONSULANT);
            bundle.putString("consultant_id", SharedPreferencesUtil.get(MyCounselorAct.this, "pre_consultant_id"));
            mSaleCounselorF.setArguments(bundle);
        }
        fm = getSupportFragmentManager();
        stateCheck(mSavedInstanceState);//状态检测,默认设置mcotext为顾问列表
        switchContent(mServerCounselorF, mSaleCounselorF, 0);
    }

    @Override
    protected void initEvent() {
        //切换顾问列表
        ragCounselor.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                switch (checkedId) {
                    //销售顾问
                    case R.id.rab_salecounselor:
//                        if (mSaleCounselorF == null) {
//                            mSaleCounselorF = new CounselorFrag();
//                            Bundle bundle = new Bundle();
//                            bundle.putString("type", Constant.PRECONSULANT);
//                            bundle.putString("consultant_id", SharedPreferencesUtil.get(MyCounselorAct.this, "pre_consultant_id"));
//                            mSaleCounselorF.setArguments(bundle);
//                        }
                        switchContent(mServerCounselorF, mSaleCounselorF, 0);
                        break;
                    //服务顾问
                    case R.id.rab_servercounselor:
                        if (mServerCounselorF == null) {
                            mServerCounselorF = new CounselorFrag();
                            Bundle bundle1 = new Bundle();
                            bundle1.putString("type", Constant.AFTERCONSULTANTID);
                            bundle1.putString("consultant_id", SharedPreferencesUtil.get(MyCounselorAct.this, "consultant_id"));
                            mServerCounselorF.setArguments(bundle1);
                        }
                        switchContent(mSaleCounselorF, mServerCounselorF, 1);
                        break;
                }
            }
        });

    }
    /**
     * fragment 切换
     *
     * @param from
     * @param to
     */
    public void switchContent(Fragment from, Fragment to, int position) {
        if (mContent != to) {
            mContent = to;
            FragmentTransaction transaction = fm.beginTransaction();
            if (!to.isAdded()) { // 先判断是否被add过
                transaction.hide(from)
                        .add(R.id.fra_counselor, to, tags[position]).commit(); // 隐藏当前的fragment,add下一个到Activity中
            } else {
                transaction.hide(from).show(to).commit(); // 隐藏当前的fragment,显示下一个
            }
        }
    }

    /**
     * 状态检测 用于内存不足时的时候保证fragment不会重叠
     */
    private void stateCheck(Bundle saveInstanceState) {
        if (saveInstanceState == null) {
            FragmentTransaction frs = fm.beginTransaction();
            mContent = mSaleCounselorF;
            frs.add(R.id.fra_counselor, mContent);
            frs.commit();
        } else {
            //通过tag找回失去引用但是存在内存中的fragment.id相同
            CounselorFrag counselorSaleFrag = (CounselorFrag) getSupportFragmentManager().findFragmentByTag(tags[0]);
            CounselorFrag counselorServerFrag = (CounselorFrag) getSupportFragmentManager().findFragmentByTag(tags[1]);
            getSupportFragmentManager().beginTransaction().show(counselorSaleFrag).hide(counselorServerFrag).commit();
        }
    }
}

   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132

参考链接:http://www.cnblogs.com/android-joker/p/4414891.html

5、继续踩坑。have a nice day~

猜你喜欢

转载自blog.csdn.net/mawei7510/article/details/82016945