RecyclerView实现吸顶效果项目实战(四),腾讯3轮面试都问了Android事件分发

}

构造函数中告诉我们,可以在布局文件中通过 app:layoutManager 来设置 RecyclerViewLayoutManager 对象。LayoutManager 主要负责 RecyclerView 的布局。

拿到 RecyclerView 对象后,如果在构造函数中没有设置 LayoutManager,可以通过调用 RecyclerViewsetLayoutManager(RecyclerView.LayoutManager layout) 方法进行设置。

public void setLayoutManager(RecyclerView.LayoutManager layout) {

if (layout != this.mLayout) {

this.mLayout = layout;

}

}

然后 RecyclerView 会调用 setAdapter 方法。

public void setAdapter(RecyclerView.Adapter adapter) {

this.setLayoutFrozen(false);

this.setAdapterInternal(adapter, false, true);

this.requestLayout();

}

setAdapterInternal 方法主要作用是将传进来的 adapter 保存到 mAdapter 变量。之后调用了 requestLayout 方法。

public void requestLayout() {

if (this.mEatRequestLayout == 0 && !this.mLayoutFrozen) {

super.requestLayout();

} else {

this.mLayoutRequestEaten = true;

}

}

requestLayout 方法又调用了父类的 requestLayout 方法,最终调用了 ViewrequestLayout 方法。

public void requestLayout() {

if (mParent != null && !mParent.isLayoutRequested()) {

mParent.requestLayout();

}

}

上面的 mParent 的真正实例为 ViewRootImpl,也就是说执行了 ViewRootImplrequestLayout 方法。

public void requestLayout() {

if (!mHandlingLayoutInLayoutRequest) {

checkThread();

mLayoutRequested = true;

scheduleTraversals();

}

}

scheduleTraversals 方法被执行,意味着后续开始执行 RecyclerViewonMeasureonLayoutonDraw 方法,之后RecyclerView 中子视图就展示出来了。

这里我们将 onLayout 方法单拎出来进行分析,因为 RecyclerView 之所以能适配多种滚动布局,主要是 onLayout 方法发挥作用。

protected void onLayout(boolean changed, int l, int t, int r, int b) {

this.dispatchLayout();

}

onLayout 方法接着调用了 dispatchLayout 方法。

void dispatchLayout() {

mState.mIsMeasuring = false;

if (mState.mLayoutStep == State.STEP_START) {

dispatchLayoutStep1();

mLayout.setExactMeasureSpecsFrom(this);

dispatchLayoutStep2();

}

dispatchLayoutStep3();

}

dispatchLayout 方法依次调用了 dispatchLayoutStep1dispatchLayoutStep2dispatchLayoutStep3 方法。

我们首先看 dispatchLayoutStep1 方法。

private void dispatchLayoutStep1() {

if (mState.mRunPredictiveAnimations) {

mLayout.onLayoutChildren(mRecycler, mState);

} else {

clearOldPositions();

}

}

dispatchLayoutStep1 方法中调用了 mLayoutonLayoutChildren 方法。上面分析告诉我们,mLayout 就是 LayoutManager,所以我们转到 LayoutManageronLayoutChildren 方法。

public void onLayoutChildren(Recycler recycler, State state) {

Log.e(TAG, "You must override onLayoutChildren(Recycler recycler, State state) ");

}

onLayoutChildren 方法是一个空实现,其具体实现在各个子类中。我们拿 LinearLayoutManager 进行分析,看其中 onLayoutChildren 的实现。

public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {

// layout algorithm:

// 1) by checking children and other variables, find an anchor coordinate and an anchor

// item position.

// 2) fill towards start, stacking from bottom

// 3) fill towards end, stacking from top

// 4) scroll to fulfill requirements like stack from bottom.

// create layout state

if (mAnchorInfo.mLayoutFromEnd) {

} else {

// fill towards end

updateLayoutStateToFillEnd(mAnchorInfo);

mLayoutState.mExtra = extraForEnd;

fill(recycler, mLayoutState, state, false);

endOffset = mLayoutState.mOffset;

final int lastElement = mLayoutState.mCurrentPosition;

if (mLayoutState.mAvailable > 0) {

extraForStart += mLayoutState.mAvailable;

}

// fill towards start

updateLayoutStateToFillStart(mAnchorInfo);

mLayoutState.mExtra = extraForStart;

mLayoutState.mCurrentPosition += mLayoutState.mItemDirection;

fill(recycler, mLayoutState, state, false);

startOffset = mLayoutState.mOffset;

if (mLayoutState.mAvailable > 0) {

extraForEnd = mLayoutState.mAvailable;

// start could not consume all it should. add more items towards end

updateLayoutStateToFillEnd(lastElement, endOffset);

mLayoutState.mExtra = extraForEnd;

fill(recycler, mLayoutState, state, false);

endOffset = mLayoutState.mOffset;

}

}

}

onLayoutChildren 方法中的注释已经为我们说明了 RecyclerView 的布局算法,mAnchorInfo 为布局锚点信息,包含了子控件在Y轴上起始绘制偏移量(coordinate),itemViewAdapter 中的索引位置(position)和布局方向(mLayoutFromEnd)-表示start、end方向。该方法的功能是:确定布局锚点,并以此为起点向开始和结束方向填充 ItemView,如下图所示。

在这里插入图片描述

onLayoutChildren 方法中,调用了 fill 方法,从该方法名可以知道,该方法应该是将子控件加入到RecyclerView 中的。

int fill(RecyclerView.Recycler recycler, LayoutState layoutState,

RecyclerView.State state, boolean stopOnFocusable) {

while ((layoutState.mInfinite || remainingSpace > 0) && layoutState.hasMore(state)) {

layoutChunk(recycler, state, layoutState, layoutChunkResult);

}

return start - layoutState.mAvailable;

}

fill 方法中循环调用了 layoutChunkResult 方法。

void layoutChunk(RecyclerView.Recycler recycler, RecyclerView.State state,

LayoutState layoutState, LayoutChunkResult result) {

View view = layoutState.next(recycler);

LayoutParams params = (LayoutParams) view.getLayoutParams();

if (layoutState.mScrapList == null) {

if (mShouldReverseLayout == (layoutState.mLayoutDirection

== LayoutState.LAYOUT_START)) {

addView(view);

} else {

addView(view, 0);

}

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

题外话

不管怎么样,不论是什么样的大小面试,要想不被面试官虐的不要不要的,只有刷爆面试题题做好全面的准备,当然除了这个还需要在平时把自己的基础打扎实,这样不论面试官怎么样一个知识点里往死里凿,你也能应付如流啊

这里我为大家准备了一些我工作以来以及参与过的大大小小的面试收集总结出来的一套进阶学习的视频及面试专题资料包,主要还是希望大家在如今大环境不好的情况下面试能够顺利一点,希望可以帮助到大家~

欢迎评论区讨论。

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
img
转存中…(img-xFn3agwv-1712758773961)]

题外话

不管怎么样,不论是什么样的大小面试,要想不被面试官虐的不要不要的,只有刷爆面试题题做好全面的准备,当然除了这个还需要在平时把自己的基础打扎实,这样不论面试官怎么样一个知识点里往死里凿,你也能应付如流啊

这里我为大家准备了一些我工作以来以及参与过的大大小小的面试收集总结出来的一套进阶学习的视频及面试专题资料包,主要还是希望大家在如今大环境不好的情况下面试能够顺利一点,希望可以帮助到大家~

[外链图片转存中…(img-QcbtPXHK-1712758773962)]

欢迎评论区讨论。

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-cihR85DH-1712758773962)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值