抽丝剥茧RecyclerView - LayoutManager

前言

抽丝剥茧RecyclerView系列文章的目的在于帮助Android开发者提高对RecyclerView的认知,本文是整个系列的第二篇。

LayoutManagerRecyclerView中的重要一环,使用LayoutManager就跟玩捏脸蛋的游戏一样,即使好看的五官(好看的子View)都具备了,也不一定能捏出漂亮的脸蛋,好在RecyclerView为我们提供了默认的模板:LinearLayoutManagerGridLayoutManagerStaggeredGridLayoutManager

说来惭愧,如果不是看了GridLayoutManager的源码,我还真不知道GridLayoutManager竟然可以这么使用,图片来自网络

 

 

 

不过呢,今天我们讲解的源码不是来自GridLayoutManager,而是线性布局LinearLayoutManagerGridLayoutManager也是继承自LinearLayoutManager),分析完源码,我还将给大家带来实战,完成以下的效果:

 

 

时间轴的效果来自TimeLine,自己稍微处理了一下,现在开始进入正题。

目录

一、源码分析

本着认真负责的精神,我把RecyclerView中用到LayoutManager的地方大致看了一遍,发现其负责的主要业务:

  • 回收和复用子View(当然,这会交给Recyler处理)。
  • 测量和布局子View。
  • 关于滑动的处理。

回收和复用子View显然不是LayoutManager实际完成的,不过,子View的新增和删除都是LayoutManager通知的,除此以外,滑动处理的本质还是对子View进行管理,所以,本文要讨论的只有测量和布局子View的。

测量和布局子View发生在RecyclerView三大工作流程,又...又回到了最初的起点?这是我们在上篇讨论过的,如果不涉及到LayoutManager的知识,我们将一笔带过即可。

1. 自动测量机制

RecyclerView#onMeasure方法中,LayoutManager是否支持自动测量会走不同的流程:

protected void onMeasure(int widthSpec, int heightSpec) {
	// ...
	if (mLayout.isAutoMeasureEnabled()) {
		final int widthMode = MeasureSpec.getMode(widthSpec);
		final int heightMode = MeasureSpec.getMode(heightSpec);
		// 未复写的情况下默认调用RecyclerView#defaultOnMeasure方法
		mLayout.onMeasure(mRecycler, mState, widthSpec, heightSpec);
		final Boolean measureSpecModeIsExactly =
		                    widthMode == MeasureSpec.EXACTLY && heightMode == MeasureSpec.EXACTLY;
      	        // 长和宽的MeasureSpec都为EXACTLY的情况下会return
		if (measureSpecModeIsExactly || mAdapter == null) {
			return;
		}
		if (mState.mLayoutStep == State.STEP_START) {
			dispatchLayoutStep1();
		}
		// 1. 计算宽度和长度等
		mLayout.setMeasureSpecs(widthSpec, heightSpec);
		mState.mIsMeasuring = true;
      	        // 2. 布局子View
		dispatchLayoutStep2();
		// 3. 测量子View的宽和高,并再次测量父布局
		mLayout.setMeasuredDimensionFromChildren(widthSpec, heightSpec);
		if (mLayout.shouldMeasureTwice()) {
		// 再走一遍1,2,3
		}
	} else {
		// ...
		mLayout.onMeasure(mRecycler, mState, widthSpec, heightSpec);
		// ....
	}
}

从代码上来看,使用自动测量机制需要具备:

  1. RecyclerView布局的长和宽的SpecMode不能是MeasureSpec.EXACTLY(大概率指的是布局中RecyclerView长或宽中有WrapContent)。
  2. RecyclerView设置的LayoutManger的<
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值