利用BackStackEntryCount处理Fragment中返回键(back)

2015年12月10日 Android 暂无评论 阅读2003次

利用BackStackEntryCount处理Fragment中返回键(back)


前言

Android开发中,用过Fragment的猿们都知道,Framgent再处理返回键(back)时并不像Activity中那么灵活易用。

Fragment新手常常遇到Fragment中无法监听返回键事件的问题。

网络上很多处理Fragment中返回键的处理方法了,本文讲的是利用BackStackEntryCount处理Fragment中返回键(back)

了解BackStackEntryCount

我所说的BackStackEntryCount其实是一个方法的返回值。

getFragmentManager().getBackStackEntryCount() 

getBackStackEntryCount()的源码中有这样的注释

Return the number of entries currently in the back stack.

也就是,通过Fragment管理器得到当前已加入Fragment回退栈中的fragment的数量。

是从回退栈中得到fragment的数量,下面看下回退栈是如何实现的。

在android.app.FragmentTransaction#addToBackStack(String name)中能看到,addToBackStack(String)方法的说明

Add this transaction to the back stack. This means that the transaction will be remembered after it is committed, and will reverse its operation when later popped off the stack.

@param name An optional name for this back stack state, or null.

简单地翻译:增加这个事务到回退栈。该事务提交之后,这将会被保存起来,稍候执行pop出栈的时,事务将会后进先出地返回这个操作。

此处相关的方法还会有下面几个

// 弹出堆栈中的一个并且显示,也就是代码模拟按下返回键的操作
void popBackStack();
// 针对第一个参数
// 如果name为null, 那么只有顶部的状态被弹出;
// 如果name不为null, 并且找到了这个name所指向的Fragment对象
// 针对第二个参数 flags的值
// 如果是flag=0,那么将会弹出该状态以上的所有状态
// 如果flag=POP_BACK_STACK_INCLUSIVE,那么将弹出该状态(含该状态)以上所有状态
void popBackStack(String name, int flags); 

利用BackStackEntryCount的场景

有了上面对<b>BackStackEntryCount</b>的了解,下面就利用<b>BackStackEntryCount</b>处理一下Fragment中的back键。

先用一张图片说明应用到的业务场景。

一个Activity,首先是由FragmentA填充,FragmentA中有一按钮点击后,Activity将由FragmentB填充。而FragmentB中用户会按下手机的返回键(back)或FragmentB中本身也有一个返回按钮要回到FragmentA。

注意看下图中我标注的BackStackEntryCount的数值变化。这种场景下就可以用到BackStackEntryCount了。

利用BackStackEntryCount处理Fragment中返回键(back)

利用BackStackEntryCount处理Fragment中返回键(back)的代码实现

// Activity中初始状态:由FragmentA填充
// 这是在Activity类中写的代码
FramgentA mFramgentA;
mFramgentA = new FramgentA();
    getFragmentManager().beginTransaction()
        .replace(R.id.fragment_content, mFramgentA).commit();
// FragmentA中跳转到FragmentB中
// 这是在FragmentA类中写的代码
FramgentB mFramgentB = new FramgentB();
getFragmentManager().beginTransaction().hide(this)
    .add(R.id.fragment_content, mFramgentB)
    .addToBackStack(null).commit();
// FragmentA中跳转到FragmentB中
// 这是在FragmentA类中写的代码
FramgentB mFramgentB = new FramgentB();
getFragmentManager().beginTransaction().hide(this)
    .add(R.id.fragment_content, mFramgentB)
    .addToBackStack(null).commit();
// FragmentB中返回按钮的相应事件(返回到FragmentA)
// 这是在FragmentB类中写的代码
mBackBtn = (Button) view.findViewById(R.id.title_bar_left_btn);
mBackBtn.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        getFragmentManager().popBackStack();
    }
});
// 在Activity中监听返回键(back),并做相关处理
@Override
public void onBackPressed() {
    // 取得回退栈中Fragment的数量
    int backFragmentCount = getFragmentManager().getBackStackEntryCount();
    // backFragmentCount为1:说明栈中有1个Fragment,也就是当前是第二个Fragment
    // 从FragmentB返回到FragmentA
    if (backFragmentCount == 1) {
        getFragmentManager().popBackStack();
    } else {
        // backFragmentCount为0:当前就是FragmentA。返回键要处理的逻辑交给Activity父类处理
        super.onBackPressed();
    }
} 

注意点:

  • FragmentA中跳转到FragmentB时:代码一定是下面这样。特别注意<b>.addToBackStack()</b>

为简单说明问题,只考虑了两个Fragment之间跳转返回的情况。

文末,欢迎留言提出意见。谢谢!

分享本文至:

WRITTEN BY

avatar
看了本文是不是觉得很赞,那就赶紧点击下面按钮分享给身边的朋友吧!

欢迎留言




用户登录

sitemap