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 实现分析--首次填充过程(一)的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: MyBatis第二天
- 下一篇: (转)pipe row的用法, Orac