Android之Fragment回退栈详解
2016-09-20 09:54
225 查看
前言:本文将结合开发中的实际需求,来讲解一下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; } }
相关文章推荐
- android Fragments详解二:创建Fragment
- android Fragments详解三:实现Fragment的界面
- android Fragments详解四:管理fragment
- Android Fragment详解(三): 实现Fragment的界面
- Android Fragment详解(二):Fragment创建及其生命周期
- Android Fragment使用详解
- android Fragment详解(一):概述
- android Fragments详解四:管理fragment
- android Fragments详解二:创建Fragment
- Android Fragment详解(五):Fragment与Activity通讯
- android Fragments详解三:实现Fragment的界面
- Android Fragment使用详解
- android Fragments详解四:管理fragment
- android Fragments详解三:实现Fragment的界面
- 【转】Android Fragment使用详解
- android Fragments详解二:创建Fragment
- android Fragments详解四:管理fragment
- android Fragments详解四:管理fragment
- android Fragments详解四:管理fragment
- Android Fragment详解(六):Fragement示例