深入分析RecyclerView源码——布局流程(下)

接着上篇继续分析布局流程。

onLayoutChildren

所取onLayoutChildren是LinearLayoutManager的方法,RecyclerView把具体的布局交给了布局管理器去做,精简后的代码主要做了三件事:

一、确定锚点(updateAnchorInfoForLayout),所谓锚点就是布局的基准点,一般情况下layout子view是从上到下或者从下到上的,但是当子view有焦点时,比如子view是EditText输入时获得了焦点,那么会以该子view为锚点,分别向上和向下layout。还有一个问题是,如何得知应该从第几个子view开始layout,例如滑动之后怎么知道?事实上RecyclerView的滑动不会走onLayoutChildren方法(滑动不走measure和layout方法,直接调用fill修改布局),所以此处就只是简单沿用旧布局的position。

二、完成布局,调用fill函数完成布局。

三、处理动画(layoutForPredictiveAnimations),RecyclerView的dispatchLayoutStep1和dispatchLayoutStep3已经处理了一部分动画(见上篇),但是还不够。当子view被挤出屏幕时应该执行平移动画而不是淡出动画(淡出动画是被从Adapter的数据中彻底删除才用的),为了区分这里需要特殊处理。在布局完成后,被挤出屏幕的view实际上已经不在RecyclerView的mChildren数组中了,但是layoutForPredictiveAnimations会把该子view重新加进数组,不过是以DisappearingView的形式暂时存在,当平移动画结束立即会被删除。

public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
	//确保生成LayoutState
	ensureLayoutState();
	mLayoutState.mRecycle = false;
	// resolve layout direction
	//是否需要反向布局
	resolveShouldLayoutReverse();

	//获取焦点,可能有可能没有
	final View focused = getFocusedChild();
	if (!mAnchorInfo.mValid || mPendingScrollPosition != RecyclerView.NO_POSITION
			|| mPendingSavedState != null) {
		mAnchorInfo.reset();
		mAnchorInfo.mLayoutFromEnd = mShouldReverseLayout ^ mStackFromEnd;
		// calculate anchor position and coordinate
		//如果有mPendingSavedState,直接拿来用,如果子项view有焦点,以焦点为准,都没有则取头或者尾
		updateAnchorInfoForLayout(recycler, state, mAnchorInfo);
		mAnchorInfo.mValid = true;
	} else if (focused != null && (mOrientationHelper.getDecoratedStart(focused)	
		//焦点view被软键盘弹出屏幕时调用,把焦点view拉回屏幕顶端或底端
					>= mOrientationHelper.getEndAfterPadding()
			|| mOrientationHelper.getDecoratedEnd(focused)
			<= mOrientationHelper.getStartAfterPadding())) {
		mAnchorInfo.assignFromViewAndKeepVisibleRect(focused, getPosition(focused)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值