Fragment的回退栈管理分析

今天准备写写Fragment的回退栈管理策略。

 

为了更好的理解本篇博客的内容。大家最好先看看我的另一篇博客:Fragment加载过程分析。

下面是Fragment的回退栈使用方法的代码:


  @Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		findViewById(R.id.addBackStack).setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					//添加Fragment到id为root的ViewGroup。并将其加入回退栈
					getSupportFragmentManager().beginTransaction()
							.addToBackStack(null)
							.add(R.id.root, new TestFragment()).commit();
				}
			});

		findViewById(R.id.popBackStack).setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					//从回退栈里弹出最新加入的Fragment
					getSupportFragmentManager().popBackStackImmediate();
				}
			});
	}


在上面的代码中。我在界面加入两个按钮。一个点击后将TestFragment加入回退栈。一个点击后将新加入的TestFragmentFragment的回退栈中弹出。

 

要让添加的Fragment加入回退栈。需要记住,调用addToBackStack(String)方法必须在commit()方法之前。让Fragment从回退栈中弹栈的方法。有两种。一种就是上面用的popBackStackImmediate()方法。另一种是popBackStack(),它们的区别稍微会有详细的讲解。

 

首先说让Fragment的入栈操作。需要在commit()方法前调用addToBackStack()方法。下面我们来看此方法。此方法定义在BackStackRecord类中。它是FragmentTransaction的子类。也就是用于Fragment事务管理的类。


public FragmentTransaction addToBackStack(String name) {
        if (!mAllowAddToBackStack) {
            throw new IllegalStateException(
                    "This FragmentTransaction is not allowed to be added to the back stack.");
        }
        mAddToBackStack = true;
        mName = name;
        return this;
  }

在这个方法中。我们可以看到。它只是简单的将mAddToBackStack 标志位设为true。再保存当前Fragmenttag名。现在我们注意到。在最外层有一个mAllowAddToBackStack标志位。代表是否允许加入回退栈。若你不想它加入回退栈。可以调用 disallowAddToBackStack()方法,接着在我们提交此次添加操作时。调用了commitInternal()方法。它的调用层次为commit()--->commitInternal()


int commitInternal(boolean allowStateLoss) {
        if (mCommitted) throw new IllegalStateException("commit already called");
        if (FragmentManagerImpl.DEBUG) {
            Log.v(TAG, "Commit: " + this);
            LogWriter logw = new LogWriter(TAG);
            PrintWriter pw = new PrintWriter(logw);
            dump("  ", null, pw, null);
        }
        mCommitted = true;
        if (mAddToBackStack) {
            mIndex = mManager.allocBackStackIndex(this);
        } else {
            mIndex = -1;
        }
        mManager.enqueueAction(this, allowStateLoss);
        return mIndex;
    }

在第11行。当此Fragment要求入栈的时候。会由FargmentManager为它分配一个索引下标值。代表此次提交会将此组Fragment放于栈中的第几层。最下层的索引下标为0。接着往下。到BackStackRecord类中的run方法中:


  public void run() {
  ......
        if (mAddToBackStack) {
            mManager.addBackStackState(this);
        }
  }

这里直接调用addBackStackState()方法。跟进去!


void addBackStackState(BackStackRecord state) {
        if (mBackStack == null) {
            
  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值