为什么fragment使用hide()和show()而不使用replace()

本文详细介绍了在Android应用开发中如何高效地使用Fragment。包括replace方法的弊端及替代方案,如使用add和切换显示/隐藏方法来优化用户体验并减少资源消耗。同时,文章还探讨了解决Fragment重叠问题的有效策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在项目中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();//提交
    }

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,显示下一个
            }
        }
    }

注意: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();
        }
    }

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();
        }
    }
}

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值