日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > 8CollapsingToolbarLayout源碼分析

8CollapsingToolbarLayout源碼分析

來源:程序員人生   發布時間:2016-10-11 08:42:45 閱讀次數:2770次

純色Toolbar滑動

最簡單代碼

先從最簡單的看起

<android.support.design.widget.AppBarLayout android:fitsSystemWindows="true" android:layout_width="match_parent" android:layout_height="256dp"> <android.support.design.widget.CollapsingToolbarLayout android:id="@+id/collapsingToolbarLayout" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_scrollFlags="scroll"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" android:minHeight="?attr/actionBarSize" app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" /> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout>

效果以下所示,toolbar可以舒展

AppBarLayout里有個接口,叫做OnOffsetChangedListener,如果AppBarLayout滑動了就會觸發里面的回調onOffsetChanged

/** * Interface definition for a callback to be invoked when an {@link AppBarLayout}'s vertical * offset changes. */ public interface OnOffsetChangedListener { /** * Called when the {@link AppBarLayout}'s layout offset has been changed. This allows * child views to implement custom behavior based on the offset (for instance pinning a * view at a certain y value). * * @param appBarLayout the {@link AppBarLayout} which offset has changed * @param verticalOffset the vertical offset for the parent {@link AppBarLayout}, in px */ void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset); }

AppBarLayout滑動的時候會調用setHeaderTopBottomOffset,里面調用dispatchOffsetUpdates(appBarLayout),以下所示,會把移動的消息發給listeners

private void dispatchOffsetUpdates(AppBarLayout layout) { final List<OnOffsetChangedListener> listeners = layout.mListeners; // Iterate backwards through the list so that most recently added listeners // get the first chance to decide for (int i = 0, z = listeners.size(); i < z; i++) { final OnOffsetChangedListener listener = listeners.get(i); if (listener != null) { listener.onOffsetChanged(layout, getTopAndBottomOffset()); } } }

而CollapsingToolbarLayout在onAttachedToWindow的時候加入
((AppBarLayout) parent).addOnOffsetChangedListener(mOnOffsetChangedListener);
其實就是注冊了1個listener,AppBarLayout滑動了,CollapsingToolbarLayout 內的mOnOffsetChangedListener就會知道并作出相應動畫,這里其實就是文字的縮小。主要代碼在CollapsingTextHelper內,主要就是根據當前AppBarLayout的offset來修改mScale。

此時CollapsingToolbarLayout和AppBarLayout1樣大小,包括statusbar 大小為256dp
mTotalScrollRange=range - getTopInset()=256dp-S=609
mDownPreScrollRange 0
mDownScrollRange =256dp=672
我曾以為mTotalScrollRange= mDownPreScrollRange+ mDownScrollRange,這里不成立了。
我試著把mDownScrollRange強行改成609,滑動仍然正常,由于下滑的時候offset是在變大的,所以不會到⑹72.

exitUntilCollapsed

再看設置了exitUntilCollapsed 以后,exitUntilCollapsed意思就是滑出直到折疊狀態,即滑出的時候最多到折疊狀態,沒法完全滑出

exitUntilCollapsed會改變上滑的范圍,上滑的范圍就是mTotalScrollRange,

private int getUpNestedPreScrollRange() { return getTotalScrollRange(); }
public final int getTotalScrollRange() { if (mTotalScrollRange != INVALID_SCROLL_RANGE) { return mTotalScrollRange; } int range = 0; for (int i = 0, z = getChildCount(); i < z; i++) { final View child = getChildAt(i); final LayoutParams lp = (LayoutParams) child.getLayoutParams(); final int childHeight = child.getMeasuredHeight(); final int flags = lp.mScrollFlags; if ((flags & LayoutParams.SCROLL_FLAG_SCROLL) != 0) { // We're set to scroll so add the child's height range += childHeight + lp.topMargin + lp.bottomMargin; if ((flags & LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED) != 0) { // For a collapsing scroll, we to take the collapsed height into account. // We also break straight away since later views can't scroll beneath // us //減去標記了SCROLL_FLAG_EXIT_UNTIL_COLLAPSED的child的最小高度 range -= ViewCompat.getMinimumHeight(child); break; } } else { // As soon as a view doesn't have the scroll flag, we end the range calculation. // This is because views below can not scroll under a fixed view. break; } } return mTotalScrollRange = Math.max(0, range - getTopInset()); }

由上可知,在算mTotalScrollRange的時候會減去標記了SCROLL_FLAG_EXIT_UNTIL_COLLAPSED的child的最小高度,這里就是減去CollapsingToolbarLayout的minHeight,但是又有個問題,CollapsingToolbarLayout我們并沒有設置minHeight,我們只是在Toolbar里設置了minHeight。CollapsingToolbarLayout在onLayout的時候會調用setMinimumHeight(getHeightWithMargins(mToolbar));,這樣CollapsingToolbarLayout就有了minHeight,這個值是toolbar的height加上下margin,跟Toolbar的minHeight沒關系。試試看把Toolbar的minHeight去掉,絕不影響。所以此時mTotalScrollRange會減去CollapsingToolbarLayout的minHeight,這樣上滑的時候就會留出1部份高度,不全部滑出,留出的高度就是CollapsingToolbarLayout的minHeight=toolbar高度+上下margin

定住toolbar

Toolbar設置app:layout_collapseMode=”pin”

這竟然可以定住toolbar,和appbarlayout的設計又有點不符合,appbarlayout是認為底部可以存在不滑動的區域,但頂部不可以,那這里怎樣做到的,實際上,他是隨著appbarlayout往上offset了,然后他自己以后又offset了1次,使得toolbar相對屏幕的位置不變。實際上,假定appbarlayout往上滑了11,那末appbarlayout的offset是⑴1,此時我們又offset了1次,把toolbar相對CollapsingToolbarLayout的offset設置為11,這樣toolbar相對屏幕就相當于沒變化,核心代碼在android.support.design.widget.CollapsingToolbarLayout.OffsetUpdateListener#onOffsetChanged

//CollapsingToolbarLayout.OffsetUpdateListener#onOffsetChanged for (int i = 0, z = getChildCount(); i < z; i++) { final View child = getChildAt(i); final LayoutParams lp = (LayoutParams) child.getLayoutParams(); final ViewOffsetHelper offsetHelper = getViewOffsetHelper(child); switch (lp.mCollapseMode) { case LayoutParams.COLLAPSE_MODE_PIN: //調劑offset使得child看起來不動 if (getHeight() - insetTop + verticalOffset >= child.getHeight()) { offsetHelper.setTopAndBottomOffset(-verticalOffset); } break; case LayoutParams.COLLAPSE_MODE_PARALLAX: //調劑offset實現視差滑動 offsetHelper.setTopAndBottomOffset( Math.round(-verticalOffset * lp.mParallaxMult)); break; } }

帶背景圖toolbar

對應case1

上滑的進程中,背景由圖片變成純色,狀態欄也由透明變成純色,這個變化是甚么時候呢?這個臨界點由getScrimTriggerOffset決定

//CollapsingToolbarLayout.OffsetUpdateListener#onOffsetChanged // Show or hide the scrims if needed if (mContentScrim != null || mStatusBarScrim != null) { setScrimsShown(getHeight() + verticalOffset < getScrimTriggerOffset() + insetTop); } /** * The additional offset used to define when to trigger the scrim visibility change. */ final int getScrimTriggerOffset() { return 2 * ViewCompat.getMinimumHeight(this); }

截了個圖,大概是這個位置,圖片可見部份的高度就是getScrimTriggerOffset的值,下1瞬間圖片就會變成純色。實際上就是在上面蓋了個mContentScrim,mContentScrim就是1個ColorDrawable ,色彩為colorPrimary.因而可知修改CollapsingToolbarLayout的minHeight就能夠修改變化瞬間的位置

變成純色的同時,狀態欄也從透明變成有色彩colorPrimaryDark。mScrimAlpha由1變成255,狀態欄變成純色,實際上是在狀態欄的位置畫了1個純色的矩形,由mStatusBarScrim來實現,mStatusBarScrim的色彩也能夠指定。

if (mStatusBarScrim != null && mScrimAlpha > 0) { final int topInset = mLastInsets != null ? mLastInsets.getSystemWindowInsetTop() : 0; if (topInset > 0) { mStatusBarScrim.setBounds(0, -mCurrentOffset, getWidth(), topInset - mCurrentOffset); mStatusBarScrim.mutate().setAlpha(mScrimAlpha); mStatusBarScrim.draw(canvas); } }

初始態覆蓋狀態欄

對應case3
給ImageView加上fitSystemWindow,為何就有效果,讓初始態覆蓋狀態欄
不加的話,ImageView會被設置1個offset(insetTop),讓他處于狀態欄下邊,如果加了,那就進不到L7,所以可以覆蓋狀態欄。

//android.support.design.widget.CollapsingToolbarLayout#onLayout if (mLastInsets != null && !ViewCompat.getFitsSystemWindows(child)) { final int insetTop = mLastInsets.getSystemWindowInsetTop(); if (child.getTop() < insetTop) { // If the child isn't set to fit system windows but is drawing within the inset // offset it down ViewCompat.offsetTopAndBottom(child, insetTop); } }

enterAlwaysCollapsed

再來看看enterAlwaysCollapsed有甚么用
我拿CollapsImageActivity3試了1下,app:layout_scrollFlags=”scroll|enterAlways|enterAlwaysCollapsed” 發現有bug,下滑pre的時候顯示以下,應當是下滑的范圍(mDownPreScrollRange)少算了個statubar。暫時沒有甚么好的解決方案,看google后期會不會修復這個bug還是放棄enterAlwaysCollapsed。

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 国产成人一区二区三区 | 久久久91精品国产一区老牛影视 | 欧美日韩亚洲成人 | 91精品久久久久久久久久 | 国产成人无遮挡在线视频 | 欧产日产国产精品视频 | 97久久超碰国产精品电影 | 一区二区三区视频在线 | 欧美精品一区二区在线观看 | 欧美不卡在线 | 久久精品久久久久 | 久久av资源网 | 国产精品99久久久久久动医院 | 欧美亚洲一二三 | 亚洲一区二区视频在线 | 色综合第一页 | 国产大片在线观看 | 日本精品久久久久久久 | 免费看片黄| 欧美综合图 | 九九热视频在线播放 | 国产精品热久久久久夜色精品三区 | www在线免费观看欧美黄 | 亚洲最大成人在线 | 国产伦精品一区二区三区视频黑人 | 91精品国产综合久久久久久 | 亚洲一区在线免费观看 | 国产激情在线观看 | 欧美激情精品久久久久久变态 | 91在线免费看 | 亚洲专区在线 | 福利电影在线播放 | 国产一区二区中文字幕 | 18av在线播放 | 国产精品一区二区久久 | 亚洲欧美日韩一区 | 麻豆传媒免费 | 99久国产| 玖玖玖精品| 日韩精品电影在线观看 | 99亚洲视频|