Android之Fragment回退栈详解
来源:互联网 发布:少儿编程工具排行榜 编辑:程序博客网 时间:2024/05/19 17:58
前言:本文将结合开发中的实际需求,来讲解一下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放到回退栈中
public void addFragment(Fragment fragment, String tag) { // 开启事务 FragmentTransaction beginTransaction = fragmentManager .beginTransaction(); // 执行事务,添加Fragment beginTransaction.add(R.id.framelayout, fragment, tag); // 添加到回退栈,并定义标记 beginTransaction.addToBackStack(tag); // 提交事务 beginTransaction.commit(); }
- 监听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; }}
0 0
- Android之Fragment回退栈详解
- Android之fragment介绍及fragment详解
- 【Android基础】Fragment 详解之Fragment介绍
- 【Android基础】Fragment 详解之Fragment生命周期
- Android 开发 之 Fragment 详解
- Android 开发 之 Fragment 详解
- Android 开发 之 Fragment 详解
- Android 开发 之 Fragment 详解
- Android 开发 之 Fragment 详解
- Android进阶之Fragment详解
- Android 开发 之 Fragment 详解
- Android 开发 之 Fragment 详解
- Android开发之Fragment详解
- Android UI详解之Fragment实例详解
- Android UI详解之Fragment实例详解
- Android UI详解之Fragment实例详解
- Android UI详解之Fragment实例详解
- 详解Android Fragment之五:Fragment与Activity的通信
- iOS根据推送消息弹出指定界面
- 基于bootstrap的web登陆实例
- spring各jar包的作用
- 智能手机的密码总共有多少种
- msbuild不是内部或外部命令
- Android之Fragment回退栈详解
- centos之lnmp
- Easyui-tree 加载json数据及loadFilter的使用
- 核函数(Kernel Function)整理
- linux下vim对于意外退出的文档的再次开启
- Vim命令合集
- SSL/TLS协议运行机制的概述
- ava.lang.UnsatisfiedLinkError: Couldn't load XXXfrom loader dalvik.system.PathClassLoader[DexPathLis
- 简单的自定义标题栏(不使用Toolbar)