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第二天
- 下一篇: Linux sed命令使用