嗨!这是一篇值得深入学习的控件

  • 时间:
  • 浏览:2
  • 来源:大发彩神app—大发彩神8苹果版

dispatchLayoutStep2();

@Override

没有 结束了了英文放正片了……

layoutDecoratedWithMargins(view, left, top, right, bottom);

setAdapterInternal(adapter,false,true);

LayoutState layoutState, LayoutChunkResult result) {

没有 关键的土法律法子代码却没有 少?或者好像只做了另另一一三个小 操作?没错,表层上只调用了父类View的requestLayout土法律法子。我觉得通过父类的你这人 土法律法子可是 会调用它的onLayout土法律法子,你这人 名字熟悉自定义View的童鞋都知道了。但.我歌词 .我歌词 儿看父类View的onLayout土法律法子我觉得是个空土法律法子。也可是说最终可可不能能 能由它的子类来重写,也即RecyclerVie调用自身的onLayout土法律法子。

mAdapter = adapter;

View view = layoutState.next(recycler);

if (adapter != null) {

dispatchLayout();

dispatchLayoutStep1();

mState.mInPreLayout = false;

从哪里结束了了英文看呢?

1.我歌词 们歌词 .我歌词 儿先从setAdapter()看起,你这人 土法律法子.我歌词 .我歌词 儿比较熟悉,在Activity中这是.我歌词 .我歌词 儿直接接触的土法律法子。

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

你这人 土法律法子主要可是通过另另一一三个小 布局算法,实现itemView从顶部到底部或者底部到顶部的填充,并创建另另一一三个小 布局的情況。接下来看一下fill土法律法子是为甚进行填充的。

fill(recycler, mLayoutState, state, false);

{

layoutState.mOffset += layoutChunkResult.mConsumed * layoutState.mLayoutDirection;

fill土法律法子总的来说用了5步实现了itemVIew的填充:

在使用RecyclerView的过程中,.我歌词 .我歌词 儿都知道Adapter被缓存的单位不再是普通的itemview了,可是另另一一三个小 ViewHolder。这是和listview的另另一一三个小 很大的不同。

本文来自云栖社区合作土法律法子土法律法子伙伴“终端研发部”,了解相关信息可可不能能 能 关注“终端研发部”。

在layoutChunk中首先从layoutState获取此时的itemview,或者根据获得的你这人 itemview获取它的布局参数和尺寸信息,或者判断布局土法律法子(横向或者纵向),以此计算出itemview的上下左右坐标。最后调用layoutDecoratedWithMargins土法律法子完成布局。

result.mFocusable = view.hasFocusable();

} else {

TraceCompat.beginSection(TRACE_ON_LAYOUT_TAG);

left = right - mOrientationHelper.getDecoratedMeasurementInOther(view);

//5.按照水平或竖直方向布局来计算itemview的上下左右坐标

endOffset = mLayoutState.mOffset;

//用另另一一三个小 新的设配器和触发器来替代目前正在使的

public void requestLayout() {

RecyclerView.State state, boolean stopOnFocusable) {

撤消观察者(可是 的设配器)和注册观察者(新的设配器)操作。简单的理解一下可是设配器观察者会监测统统对象的情況,当哪些地方地方对象情況改变,它可可不能能 能 通过你这人 设计模式低耦合的做出相应的改变。最后调用markKnownViewsInvalid土法律法子刷新一下视图。

setAdapter中间主要做了两件事:

...

我总爱在说RecyclerView是另另一一三个小 值得深入学习,甚至可可不能能 能 说是一门具有艺术性的控件。那到底哪里值得.我歌词 .我歌词 儿花时间去深入学习呢。没错了,可是源码的设计。或者看源码我觉得是一件不简单的事情,就拿RecyclerView的源码来说,打开源码一看,往下拉啊拉啊,我擦,为甚还没到头,汗….岂都在有12k+行。看了这里恐怕会吓一跳,就没有 另另一一三个小 看似简单的控件就没有 多行源码,这让人从何看起,一股畏惧感油然而生。

mLayoutRequestEaten = true;

}

}

onEnterLayoutOrScroll();

6.计算itemview的边界比如下划线和margin,从而选折 itemview准确的位实现最终的布局

// 顶部向底部的填充

传送门:观察者设计模式

}

它把你这人 采集的过程分为了三步走

step1:做一下准备工作:决定哪另另一一三个小 动画被执行,保存统统目前view的相关信息

mAdapter.onDetachedFromRecyclerView(this); //Called by RecyclerView when it stops observing this Adapter.

看了没有 多先喝一杯92年的肥宅快乐水压压惊吧~~,顺便看张图小结一下中间的过程

if (mOrientation == VERTICAL) {

mFirstLayoutComplete = true;

ItemAnimator.buildAdapterChangeFlagsForAnimations(holder),

mLayout.setExactMeasureSpecsFrom(this);

}

step3:做统统采集的收尾工作了,保存动画和统统统统的信息。和.我歌词 .我歌词 儿不同路,就不看它了。

......

final ViewHolder holder = getChildViewHolderInt(mChildHelper.getChildAt(i));

......

可是 调用了 requestLayout土法律法子请求重新布局。你这人 土法律法子很关键,和.我歌词 .我歌词 儿的这次选的路是相通的。

.....

if (layoutState.mLayoutDirection == LayoutState.LAYOUT_START) {

} else {

final int firstLayoutDirection;

|| !state.isPreLayout()) {

 if (!layoutChunkResult.mIgnoreConsumed || mLayoutState.mScrapList != null

可是 说过RecyclerView和ListView最大的不同也沒有它们的布局实现上。在ListView中布局是通过自身的layoutChildren土法律法子实现的,但对于RecyclerView来说就都在了,那是谁来实现了呢?

//3.布局item view

......

LayoutChunkResult layoutChunkResult = mLayoutChunkResult;

dispatchLayoutStep3();

resumeRequestLayout(false);

//采集第三步

.recordPreLayoutInformation(mState, holder,

void dispatchLayout() {

mLayout.onLayoutChildren(mRecycler, mState);

mState.mStructureChanged = false;

adapter.onAttachedToRecyclerView(this);

//2.获取itemview的布局参数

}

//2.迭代布局item View

到这里.我歌词 .我歌词 儿就结束了了英文了.我歌词 .我歌词 儿对RecyclerView的的源码分析了。相信你看了会有所收获。

到这里或者算走完.我歌词 .我歌词 儿可是 准备走的每根路了。但从结束了了英文到这里始终忽略了另另一一三个小 东西没有 说,那就在布局过程的大多土法律法子中的参数都在另另一一三个小 Recycler对象。你这人 Recycler是哪些地方呢?

}

我觉得不能害怕,.我歌词 .我歌词 儿不能一结束了了英文就想完整版弄懂它每一步为甚实现的,原先反而会造成只见森林不见树木的感觉。.我歌词 .我歌词 儿就把源码就当成一片森林来说吧。首先.我歌词 .我歌词 儿只可可不能能 能先抓住每根路径去看,也可是带着另另一一三个小 大问題去看,原先就不能把这条路径上的树看了明白了。就可不能能 有只见森林不见树,一脸茫然了。当然.我歌词 .我歌词 儿大多数情況肯定是不满足于此每根路径,想完整版看明白它是为甚实现的,那就继续另开路径(再带着另外另另一一三个小 大问題),继续看这条路上的树。当你把每条路都走差太满了,再回头来看,就会发现你既见到了森林又见到了一颗颗清晰树木,犹如醍醐灌顶、豁然开朗。

if (mState.mRunSimpleAnimations) {

......

onLayout又调用了dispatchLayout土法律法子,来采集layout

}

holder.getUnmodifiedPayloads());

View getViewForPosition(int position, boolean dryRun) {

....

startOffset = mLayoutState.mOffset;

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

首先调用setAdapterInternal土法律法子,目的是用另另一一三个小 新的设配器和触发器来替代目前正在使用的。

.我歌词 .我歌词 儿深入进去看看它做了哪些地方?

if (mLayoutState.mAvailable > 0) {

//请求布局,直接调用View类的请求布局土法律法子

(4)计算布局偏移量

mLayoutState.mExtra = extraForStart;

......

mLayoutState.mCurrentPosition += mLayoutState.mItemDirection;

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

//1.获取itemview

updateLayoutStateToFillEnd(mAnchorInfo);

if (mAnchorInfo.mLayoutFromEnd) {

return tryGetViewHolderForPositionByDeadline(position, dryRun, FOREVER_NS).itemView;

int count = mChildHelper.getChildCount();

final ArrayList<ViewHolder> mAttachedScrap = new ArrayList<>();

right = left + mOrientationHelper.getDecoratedMeasurementInOther(view);

*/

for (int i = 0; i < count; ++i) {

对于熟悉了观察者设计模式的,可可不能能 能 从下面的代码看出来,我觉得中间有个操作是:

mLayoutState.mExtra = extraForEnd;

从使用RecyclerView的可是 ,它的另另一一三个小 功能可是人感觉很你这人 控件不简单,谁能谁能告诉我你和让人的是都在一样。那是哪些地方功能呢?.我歌词 .我歌词 儿只需改变一行代码就可可不能能 能 直接设置它的ItemView为水平布局、垂直布局、表格布局以及瀑布流布局。这是ListView所不能做到的。用起来简单,其肩头肯定有故事啊。原先们就以这条路为核心来看这片森林了。

}

updateLayoutStateToFillStart(mAnchorInfo);

final Adapter oldAdapter = mAdapter;

mUnmodifiableAttachedScrap = Collections.unmodifiableList(mAttachedScrap);

top = layoutState.mOffset;

// we keep a separate remaining space because mAvailable is important for recycling

}

layoutChunk(recycler, state, layoutState, layoutChunkResult);

或者你想深入了解观察者设计模式的可可不能能 能 看一下这篇文章

//5.计算剩余的可用空间

right = getWidth() - getPaddingRight();

public View getViewForPosition(int position) {

}

markKnownViewsInvalid();

}

在Recycler类的结束了了英文看了了mAttachedScrap、mChangedScrap、mCachedViews、 mUnmodifiableAttachedScrap这几块ViewHolder的列表对象,它们也可不能能 来缓存ViewHolder的。

原先一看就对整个过程有了个清晰的认识了吧,有没有 感觉设计的很优雅。

return start - layoutState.mAvailable;

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

ViewHolder tryGetViewHolderForPositionByDeadline(int position,

private void dispatchLayoutStep1() {

}

bottom = layoutState.mOffset;

boolean dryRun, long deadlineNs) {

}

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

//采集第二步

// Step 2: 运行layout

top = layoutState.mOffset - result.mConsumed;

 //3.测量Item View

}

......

......

ArrayList<ViewHolder> mChangedScrap = null;

boolean removeAndRecycleViews) {

int remainingSpace = layoutState.mAvailable + layoutState.mExtra;

......

bottom = layoutState.mOffset + result.mConsumed;

}

} else {

adapter.registerAdapterDataObserver(mObserver); //注册观察者

为哪些地方要写这篇源码解析呢?

......

//刷新视图

}

}

//填充

return getViewForPosition(position, false);

}

(1)计算RecyclerView可用的布局宽或高

......

int fill(RecyclerView.Recycler recycler, LayoutState layoutState,

@Override

mAdapter.unregisterAdapterDataObserver(mObserver); //撤消观察者

......

private void dispatchLayoutStep2() {

四、贯穿布局的每根线

left = getPaddingLeft();

}

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

}

}

} else {

//填充

说着很简单,或者不得不说看源码的过程还是不为甚小痛苦的。不过,可不能能 慌,看了可是 你所获得那种充实感和满足感会远远大于过程中的痛苦感。毕竟这是另另一一三个小 充满艺术感的控件嘛,值得.我歌词 .我歌词 儿去欣赏和学习。

mAdapterHelper.reset();

......

}

}



(2)迭代布局item View

measureChildWithMargins(view, 0, 0);

这中间有个土法律法子很关键了,可是下面你这人 onLayoutChildren,你这人 为哪些地方关键呢,先提一下你这人 ,待会要完整版说的。

具体是为甚实现的这里就不做完整版的解释了。或者这里一说又会牵涉到统统的点,子子孙孙无穷尽也,毕竟这是另另一一三个小 有艺术感的控件,不能指望一篇文章把它说透哈。

final ItemHolderInfo animationInfo = mItemAnimator

/**

......

fill土法律法子又会循环的调用layoutChunk来进行itemView的布局,下面先看看layoutChunk的实现

eatRequestLayout();

//1.计算RecyclerView可用的布局宽或高

}

extraForEnd += mLayoutState.mAvailable;

......

fill(recycler, mLayoutState, state, false);

// 底部向顶部的填充

//4.计算该itemview消耗的宽和高

没有 既然要重写可可不能能 能要寻找另另一一三个小 子类,统统这里让人找了另另一一三个小 子类LinearLayoutManager类,也是.我歌词 .我歌词 儿最常用的三种线性布局来看。

}

if (isLayoutRTL()) {

......

int endOffset;

mViewInfoStore.addToPreLayout(holder, animationInfo);

final int firstElement = mLayoutState.mCurrentPosition;

(5)计算剩余的可用空间

......

result.mConsumed = mOrientationHelper.getDecoratedMeasurement(view);

step2:找到实际的view和最终的情況后运行layout。

public final class Recycler {

private void setAdapterInternal(Adapter adapter, boolean compatibleWithPrevious,

//4.计算布局偏移量

一、开辟每根路径

} else {

这就要从刚才结束了了英文的onLayoutChildren土法律法子说起了,它都在RecyclerView的类直接土法律法子,它是RecyclerView的内部管理类LayoutManager的土法律法子,顾名思义,可是布局管理者了。.我歌词 .我歌词 儿的RecyclerView布局就通过你这人 布局管理者来做了,把原先另另一一三个小 不为甚要的职责就交给它了。从而实现三种程度上的低耦合。

public void onLayoutChildren(Recycler recycler, State state) {

final ArrayList<ViewHolder> mCachedViews = new ArrayList<ViewHolder>();

原先们继续走,它是为甚执行你这人 职责的。

或者点进去看onLayoutChildren土法律法子,发现不能一行代码,或者还是打印的日志:可可不能能 能重写你这人 土法律法子。

int startOffset;

......

// Step 0: Find out where all non-removed items are, pre-layout

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

public void setAdapter(Adapter adapter){

int left, top, right, bottom;

*Replaces the current adapter with the new one and triggers listeners.

(3)布局itemview

if (mAdapter != null) {

}

 private final List<ViewHolder>

原文发布时间为:2018-08-29

//采集第一步

本文作者:錦小白

layoutChunkResult.resetInternal();

remainingSpace -= layoutChunkResult.mConsumed;

......

......

requestLayout();

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

layoutState.mAvailable -= layoutChunkResult.mConsumed;

二、结束了了英文寻路

super.requestLayout();

TraceCompat.endSection();

onAnchorReady(recycler, state, mAnchorInfo, firstLayoutDirection);

Adapter mAdapter;