Android之Fragment回退栈详解

前言:本文将结合开发中的实际需求,来讲解一下Fragment中的回退栈 对于Activity,当按返回键时,能够返回到上一个Activity,但是,当我们Fragment到Activity中时,如果不做任何处理,当按返回键时,当前Fragment都会全部退出,如果想要拥有Activity逐渐退出的效果,我们需要应用一下Fragment中的回退栈

案例描述
大家可以自行打开京东,你会发现,如果你点击了分类,发现,购物车,我的,按钮,再按返回键的话,会先回到首页,然后再退出应用.这里应用的就是Fragment的回退栈功能.,下面我将带领大家了解一下回退栈的实现逻辑方法介绍
addToBackStack(tag); 将Fragment添加到回退栈中
popBackStack(); 清除回退栈中栈顶的Fragment
popBackStack(String tag, int i );
如果i=0,回退到该tag所对应的Fragment层
如果i=FragmentManager.POP_BACK_STACK_INCLUSIVE,回退到该tag所对应的Fragment的上一层
popBackStackImmediate 立即清除回退栈中栈顶Fragment
getBackStackEntryCount(); 获取回退栈中Fragment的个数
getBackStackEntryAt(int index) 获取回退栈中该索引值下的Fragment
逐层退出回退栈效果代码实现
布局代码,在布局中,写了一个FrameLayout,用来放置Fragment的容器;写了一个RadioGroup,用来放置下边的几个指示按钮

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <RadioGroup
            android:id="@+id/radioGroup"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#ff0000"
            android:orientation="horizontal" >

            <RadioButton
                android:id="@+id/rb_home"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:layout_weight="1"
                android:button="@drawable/home_selector"
                android:checked="true"
                android:gravity="center_horizontal" />

            <RadioButton
                android:id="@+id/rb_cart"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:button="@drawable/cart_selector" />

            <RadioButton
                android:id="@+id/rb_category"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:button="@drawable/category_selector" />

            <RadioButton
                android:id="@+id/rb_personal"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:button="@drawable/personal_selector" />
        </RadioGroup>
    </LinearLayout>

</LinearLayout>



MainActivity中的代码
初始化,在onCreate方法中
初始化控件,并设置监听
添加一个HomeFragment

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        // 获取Fragment管理者
        fragmentManager = getSupportFragmentManager();
        // 先默认添加fragment1
        addFragment(new Fragment1(), "fragment1");
    }


初始化控件给RadioButton设置监听

private void initView() {
        radioGroup = (RadioGroup) findViewById(R.id.radioGroup);
        rb_cart = (RadioButton) findViewById(R.id.rb_cart);
        rb_category = (RadioButton) findViewById(R.id.rb_category);
        rb_home = (RadioButton) findViewById(R.id.rb_home);
        rb_personal = (RadioButton) findViewById(R.id.rb_personal);
        // 对每一个RadioButton都设置点击事件,注意,在这里并没有对radioGroup设置checkChangeListener
        rb_cart.setOnClickListener(this);
        rb_category.setOnClickListener(this);
        rb_home.setOnClickListener(this);
        rb_personal.setOnClickListener(this);

    }


*点击按钮时,替换Fragment

/**
     * 根据点击的按钮---依次替换Fragment
     */
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.rb_home:
            addFragment(new Fragment1(), "fragment1");
            break;
        case R.id.rb_cart:
            addFragment(new Fragment2(), "fragment2");
            break;
        case R.id.rb_category:
            addFragment(new Fragment3(), "fragment3");
            break;
        case R.id.rb_personal:
            addFragment(new Fragment4(), "fragment4");
            break;
        default:
            break;
        }
    }


添加Fragment的时候,同时将Fragment放到回退栈中
12
监听Activity中的返回键,判断当前回退栈中的Fragment个数,如果回退栈中有大于一个,就一个个清除Fragment,如果只剩一个,说明只剩首页Fragment所对应的Fragment,就finish();

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        // 判断当前按键是返回键
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            // 获取当前回退栈中的Fragment个数
            int backStackEntryCount = fragmentManager.getBackStackEntryCount();
            // 判断当前回退栈中的fragment个数,
            if (backStackEntryCount > 1) {
                // 立即回退一步
                fragmentManager.popBackStackImmediate();
                // 获取当前退到了哪一个Fragment上,重新获取当前的Fragment回退栈中的个数
                BackStackEntry backStack = fragmentManager
                        .getBackStackEntryAt(fragmentManager
                                .getBackStackEntryCount() - 1);
                // 获取当前栈顶的Fragment的标记值
                String tag = backStack.getName();
                // 判断当前是哪一个标记
                if ("fragment1".equals(tag)) {
                    // 设置首页选中
                    rb_home.setChecked(true);
                } else if ("fragment2".equals(tag)) {
                    // 设置购物车的tag
                    rb_cart.setChecked(true);
                } else if ("fragment3".equals(tag)) {
                    rb_category.setChecked(true);
                } else if ("fragment4".equals(tag)) {
                    rb_personal.setChecked(true);
                }
            } else {
                //回退栈中只剩一个时,退出应用
                finish();
            }
        }
        return true;
    }

}


退出所有只剩首页而Fragment的代码
其他代码和上边一致,只需要修改一下退出的逻辑.需要判断当前回退栈中有多少个Fragment,使用While循环逐个退出.

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        // 判断当前按键是返回键
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            // 获取当前回退栈中的Fragment个数
            int backStackEntryCount = fragmentManager.getBackStackEntryCount();
            // 回退栈中至少有多个fragment,栈底部是首页
            if (backStackEntryCount > 1) {
                // 如果回退栈中Fragment个数大于一.一直退出
                while (fragmentManager.getBackStackEntryCount() > 1) {
                    fragmentManager.popBackStackImmediate();
                    //选中第一个界面
                    rb_home.setChecked(true);
                }
            } else {
                finish();
            }

        }
        return true;
    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值