欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

StaggeredGridView 实现分析--首次填充过程(一)

发布时间:2025/6/15 编程问答 58 豆豆
生活随笔 收集整理的这篇文章主要介绍了 StaggeredGridView 实现分析--首次填充过程(一) 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

2019独角兽企业重金招聘Python工程师标准>>>

ExtendableListView.java

1, 因为是首次layout, changed为true, childCount是 0, 

//ExtendableListView.java /*** {@inheritDoc}*/@Overrideprotected void onLayout(final boolean changed, final int l, final int t, final int r, final int b) {// super.onLayout(changed, l, t, r, b); - skipping base AbsListView implementation on purpose// haven't set an adapter yet? get to itif (mAdapter == null) {return;}if (changed) {int childCount = getChildCount();for (int i = 0; i < childCount; i++) {getChildAt(i).forceLayout();}mRecycleBin.markChildrenDirty();}// TODO get the height of the view??mInLayout = true;layoutChildren();mInLayout = false;}

2, layoutChildren, 在步骤1中可知 在layoutChildren()期间 变量mInLayout 一直为true。

在attachToWindow() 和 setAdapter(..)时 ,如果adapter不为null, 则mDataChanged 设置为 true, 所以假设这里的mDataChanged是true .

在handleDataChanged() 中, mLayoutMode 被设置为 LAYOUT_FORTCE_TOP , 所以 mFirstPosition 为 0, 然后执行 fillFromTop( top) ,假设没有headerview, 那么 top值是0 或者 listview的 topPadding值。

//ExtendableListView.java /*** {@inheritDoc}*/@Overrideprotected void layoutChildren() {if (mBlockLayoutRequests) return;mBlockLayoutRequests = true;try {super.layoutChildren();invalidate();...int childrenTop = getListPaddingTop();int childCount = getChildCount();View oldFirst = null;// our last state so we keep our positionif (mLayoutMode == LAYOUT_NORMAL) {oldFirst = getChildAt(0);}boolean dataChanged = mDataChanged;if (dataChanged) {handleDataChanged();}...// Pull all children into the RecycleBin.// These views will be reused if possiblefinal int firstPosition = mFirstPosition;final RecycleBin recycleBin = mRecycleBin;if (dataChanged) { // true nowfor (int i = 0; i < childCount; i++) { // childcount is 0 nowrecycleBin.addScrapView(getChildAt(i), firstPosition + i);}}else {recycleBin.fillActiveViews(childCount, firstPosition);}// Clear out old viewsdetachAllViewsFromParent();recycleBin.removeSkippedScrap();switch (mLayoutMode) {case LAYOUT_FORCE_TOP: {mFirstPosition = 0;resetToTop();adjustViewsUpOrDown();fillFromTop(childrenTop);adjustViewsUpOrDown();break;}case LAYOUT_SYNC: {fillSpecific(mSyncPosition, mSpecificTop);break;}case LAYOUT_NORMAL:default: {if (childCount == 0) {fillFromTop(childrenTop);}else if (mFirstPosition < mItemCount) {fillSpecific(mFirstPosition,oldFirst == null ? childrenTop : oldFirst.getTop());}else {fillSpecific(0, childrenTop);}break;}}// Flush any cached views that did not get reused aboverecycleBin.scrapActiveViews();mDataChanged = false;mNeedSync = false;mLayoutMode = LAYOUT_NORMAL;invokeOnItemScrollListener();} finally {mBlockLayoutRequests = false;}}

2' , override:

这里将mColumnBottoms[] 和 mColumnTops[]是一样的值(每个值都是0, 或者listview的 topPadding值), 因为还没任何child view

//StaggeredGridView.java@Overrideprotected void layoutChildren() {preLayoutChildren();super.layoutChildren();}//mNeedSync 在 onRestoreInstanceState 时才会被设置为true,其他情况均为falseprivate void preLayoutChildren() {// on a major re-layout reset for our next layout passif (!mNeedSync) {Arrays.fill(mColumnBottoms, 0);}else {mNeedSync = false;}// copy the tops into the bottom// since we're going to redo a layout pass that will draw down from// the topSystem.arraycopy(mColumnTops, 0, mColumnBottoms, 0, mColumnCount);}

3, 回顾2, ExtendableListView.java, fillFromTop, 其参数是0 或者 listView的 topPadding值;mFirstPosition是0

在fillDown中, 此时 itemPos 是0 ; nextTop是顶部位置: topPadding 或 0 , 通过while循环这一过程,将有足够多的child view 被生成以填满整个listview。

//ExtendableListView.java/*** Fills the list from top to bottom, starting with mFirstPosition*/private View fillFromTop(int nextTop) {mFirstPosition = Math.min(mFirstPosition, mItemCount - 1);if (mFirstPosition < 0) {mFirstPosition = 0;}return fillDown(mFirstPosition, nextTop);}private View fillDown(int itemPos, int nextTop) { //(0,topPadding)if (DBG) Log.d(TAG, "fillDown - pos:" + pos + " nextTop:" + nextTop);View selectedView = null;int end = getHeight();if (mClipToPadding) {end -= getListPaddingBottom();}while ((nextTop < end || hasSpaceDown()) && pos < mItemCount) {// TODO : add selection support// 目前不支持select , 所以selected一律为falsemakeAndAddView(itemPos, nextTop, true, false);itemPos++;nextTop = getNextChildDownsTop(itemPos); // = child.getBottom();}return selectedView;}

4, makeAndAddView(0, 0, true, false):

执行obtainView

//ExtendableListView.java/*** Gets a view either a new view an unused view?? or a recycled view and adds it to our children*/private View makeAndAddView(int position, int y, boolean flowDown, boolean selected) {View child;onChildCreated(position, flowDown);if (!mDataChanged) {// now mDataChanged is true , so it is skipped here// Try to use an existing view for this positionchild = mRecycleBin.getActiveView(position);if (child != null) {// Found it -- we're using an existing child// This just needs to be positionedsetupChild(child, position, y, flowDown, selected, true);return child;}}// Make a new view for this position, or convert an unused view if possiblechild = obtainView(position, mIsScrap);// This needs to be positioned and measuredsetupChild(child, position, y, flowDown, selected, mIsScrap[0]);return child;}

4.1 onChildCreated( 0, true): ExtendableListView 的实现为空, 所以直接看StaggeredGridView的实现:

执行if 部分,需要看 getChildColumn 和 setPositionColumn 。

 //StaggeredGridView.java@Overrideprotected void onChildCreated(final int position, final boolean flowDown) {super.onChildCreated(position, flowDown);if (!isHeaderOrFooter(position)) {// do we already have a column for this position?final int column = getChildColumn(position, flowDown);setPositionColumn(position, column); }else {setPositionIsHeaderFooter(position);}}


转载于:https://my.oschina.net/u/255456/blog/344140

总结

以上是生活随笔为你收集整理的StaggeredGridView 实现分析--首次填充过程(一)的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。