解决add方法添加Fragment界面重合的问题+Fragment生命周期

动态添加一个fragment有两种方法

1.add
2.replace

两个方法的使用
这里写图片描述

这里写图片描述

两者的区别是什么(这里只做简单的阐述)?

add:允许Fragment共存
replace:不允许Fragment共存

共存和不共存的区别是,允许共存的话(add),再次添加一个Fragment,这个Fragment会覆盖到那个Fragment的上面;不共存的情况下(replace),再次添加一个Fragment时会先将一开始的Fragment的移除才会添加新的

两者存在着各自的有点也有各自的缺点

比如在一个fragment中有一个20秒中的网络请求,当replace方法添加fragment,网络请求的数据也会被移除,下一次回来要重新请求,如果是用add再次添加的话可以避免
又比如,我的第一个Fragment是几乎透明的,我用add方法添加一个新的Fragment,这个时候Fragment之间的文字会相互覆盖,效果如下

这里写图片描述

允许共存的情况下下每个Fragment之间都是可以获取焦点的
也就是说当前显示的是首页,但是我却可以去点帮助界面的按钮,并有反应

那么怎么解决界面重合影响整体效果的问题呢~~下面开始说正事!

怎样解决用add方法添加Fragment界面重合
以上图三个Fragment为例,分别是HomeFragment,SettingFragment,HelpFragment
PS:所有的Fragment都是存在一个

1.点击下方三个Button,显示不同的Fragment
2.在显示前判断Fragment是否已经存在于栈中
   -如果不存在将其添加(add)并显示
   -如果存在直接从栈中取出来显示
3.显示当前的Fragment时将它上一个显示的Fragment隐藏掉
(首先要判断它是否存在上一个Fragment,第一个显示的Fragment肯定是不存在的)

天呐!!我竟然哔哔了这么多字,下面上代码!!!!!!!

创建Fragment布局
这些是布局的创建,不想看的直接看下一个板块
1.在MainActivtiy布局中创建< FrameLayout >占位符

<FrameLayout
        android:id="@+id/main_fram"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        />

下面有个RadioGroup的导航栏

<RadioGroup
        android:id="@+id/main_rg"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        >
        <RadioButton
            android:id="@+id/main_home_rb"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="首页"
            android:button="@null"
            android:textSize="16sp"
            android:paddingLeft="0dp"
            android:drawableTop="@drawable/main_tab_home"
            android:drawablePadding="10dp"
            android:textColor="@drawable/text_color_select"
            android:gravity="center"
            android:checked="true"
            />
            ......
 <RadioGroup>

只演示一个RadioButton

设计Fragment布局,创建HomeFragment继承Fragment

public class HelpFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        View v= inflater.inflate(R.layout.fragment_help,null);
        return v;
    }
}

这样我们的Fragment就创建好了,下一步就是点击RadioButton添加不同的布局了

添加布局

1.创建FragmentManager

manager = getSupportFragmentManager();

2.自定义一个添加Fragment的方法

1.判断当前fragment是否存在于栈中,这里是为Fragment添加了一个标签判断的
如果不存在添加并显示,存在直接显示show出来,不用再添加到栈

Fragment fragment;
private void addFragment(String fTag) {
        //判断这个标签是否存在Fragment对象,如果存在则返回,不存在返回null
        fragment =  manager.findFragmentByTag(fTag);
        //如果这个fragment不存于栈中
        if (fragment == null) {
        //初始化Fragment事物
            transaction = manager.beginTransaction();
            //根据RaioButton点击的Button传入的tag,实例化,添加显示不同的Fragment
            if (fTag.equals("home")) {
                fragment = new HomeFragment();
            } else if (fTag.equals("help")) {
                fragment = new HelpFragment();
            } else if (fTag.equals("setting")) {
                fragment = new SettingFragment();
            }
            transaction.add(R.id.main_fram, fragment, fTag);
            transaction.commit();
        } else {
            //如果添加的Fragment已经存在,fragment不为空,直接显示fragment
            transaction = manager.beginTransaction();
            transaction.show(fragment);
            transaction.commit();



        }


    }

上面只是将Fragment添加到栈,并保证栈中只存在三个Fragment,并不能 解决界面重合

3.解决界面重合问题

1.判断 在想要显示的Fragment之前是否存在fragment

//保留当前可见的Fragment
    private Fragment currentFragment;

在第一次显示Fragment时这个对象是空的

如果不为空将上一个(current)Fragment隐藏,显示当前点击的Fragment,然后把当前(被点击的)的Fragment赋值给(current)Fragment

//在添加之前先将上一个Fragment隐藏掉
            if (currentFragment != null) {
                transaction.hide(currentFragment);
            }
            transaction.add(R.id.main_fram, fragment, fTag);
            transaction.commit();
            //更新可见
            currentFragment = fragment;

这是fragment不存在于栈中的情况下 ,如果存在于栈中就不用add,直接show出来就好了

transaction.show(fragment);
            transaction.hide(currentFragment);
            //更新可见
            currentFragment = fragment;
            transaction.commit();

那么整体代码

private void addFragment(String fTag) {
        //判断这个标签是否存在Fragment对象,如果存在则返回,不存在返回null
        fragment = (BaseFragment) manager.findFragmentByTag(fTag);
        // 如果这个fragment不存于栈中
        if (fragment == null) {
            //初始化Fragment事物
            transaction = manager.beginTransaction();
            //根据RaioButton点击的Button传入的tag,实例化,添加显示不同的Fragment
            if (fTag.equals("home")) {
                fragment = new HomeFragment();
            } else if (fTag.equals("help")) {
                fragment = new HelpFragment();
            } else if (fTag.equals("setting")) {
                fragment = new SettingFragment();
            }
            //在添加之前先将上一个Fragment隐藏掉
            if (currentFragment != null) {
                transaction.hide(currentFragment);
            }
            transaction.add(R.id.main_fram, fragment, fTag);
            transaction.commit();
            //更新可见
            currentFragment = fragment;
        } else {
            //如果添加的Fragment已经存在,则将隐藏掉的Fragment再次显示,其余当前
            transaction = manager.beginTransaction();
            transaction.show(fragment);
            transaction.hide(currentFragment);
            //更新可见
            currentFragment = fragment;
            transaction.commit();


        }


    }

方法的调用

 rg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, @IdRes int checkedId) {
                switch (checkedId) {
                    case R.id.main_home_rb:
                        addFragment(HOME);
                        break;
                    case R.id.main_setting_rb:
                        addFragment(SETTING);
                        break;
                    case R.id.amain_help_rb:
                        addFragment(HELP);
                        break;
                }
            }
        });

写了这么多字不知道看这篇博客的你有没有看懂呢~

下面奉上Fragment声明周期图,Android面试必备!

这里写图片描述

图片有些不清楚,可以先复制保存到电脑上然后再查看

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值