日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【译文】AppBarLayout的越界滚动行为

發(fā)布時間:2025/4/5 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【译文】AppBarLayout的越界滚动行为 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
  • 原文鏈接 : Overscroll AppBarLayout Behavior
  • 原文作者 : Nikola Despotoski
  • 譯文出自 : 開發(fā)技術(shù)前線 www.devtf.cn。未經(jīng)允許,不得轉(zhuǎn)載!
  • 譯者 : liuling07
  • 校對者: desmond1121
  • 狀態(tài) : 完成

很不幸,Youtube音樂應(yīng)用在我們國家不可使用,我嘗試著通過各種盜版網(wǎng)站來獲取該應(yīng)用,但我仍然無法看到在這個應(yīng)用上發(fā)生了什么。感謝這位redditor,在我的請求下,他在/r/materialdesign打開了一個thread并且發(fā)表一段錄制的視頻,我才有機會看到這個行為。

Youtube視頻app的真實截圖,可能的行為

根據(jù)我所看到的,我首先想到的就是專輯封面是放到一個AppBarLayout里面,并且在滾動區(qū)域拖到邊界的時候尺寸會發(fā)生變化。讓我們假定這個 猜想是正確的并且用“Behavior”這個術(shù)語表示它。依鄙人之見,如果我的猜想是正確的,谷歌應(yīng)該會在Material Design文檔的滾動部分提供一個越界滾動的使用說明。

我們的目標就是保證AppBarLayout.Behavior的完整性,在此基礎(chǔ)上再創(chuàng)建一個擴展的行為。因此:

public class OverscrollScalingViewAppBarLayoutBehavior extends AppBarLayout.ScrollingViewBehavior

因為這是默認的AppBarLayout.Behavior,所以建議只有在依賴視圖是AppBarLayout的時候起作用。

@Override public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {return dependency instanceof AppBarLayout; }

接下來,我們需要獲取想要在拖到邊界時要改變尺寸的視圖的一個實例。最好的方法就是在onLayoutChild()方法中獲取:

@Override public boolean onLayoutChild(CoordinatorLayout parent ....) {boolean superLayout = super.onLayoutChild(parent, abl, layoutDirection);if (mTargetScalingView == null) {mTargetScalingView = parent.findViewByTag(TAG);if(mTargetScalingView != null){mScaleImpl.obtainInitialValues();}}return superLayout; }

而且我們需要保證只有在垂直滾動的時候起作用:

@Override public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout,... int nestedScrollAxes) {return nestedScrollAxes == View.SCROLL_AXIS_VERTICAL; }

如果我們先前沒有在程序中顯示設(shè)置,會設(shè)置ViewScaler為默認的Scaler。

在內(nèi)容滾動的瞬間,真正重要的問題就有頭緒了。CoordinatorLayout.Behavior提供了一個onNestedScroll() 方法,當(dāng)滾動進行的時候這個方法會被調(diào)用,并且當(dāng)內(nèi)容滾動到邊界的時候也會調(diào)用。最后兩個參數(shù)dyUnconsumed和dxUnconsumed提供了 未被該行為的目標視圖填滿的像素值。

這個方法對我們實現(xiàn)尺寸改變來說太重要了。所以我列出了哪些情況需要改變尺寸,哪些情況不需要:

需要改變尺寸

  • 存在未填滿的像素,如dyUnconsumed小于0
  • AppBarLayout是展開的,getTopAndBottomOffset() >= mScaleImpl.getInitialParentBottom()
  • 不需要改變尺寸

  • AppBarLayout中沒有子視圖可以改變尺寸
  • 有填充的像素,如dyConsumed不等于

  • @Override public void onNestedScroll(CoordinatorLayout ... int dxUnconsumed, int dyUnconsumed) {if (mTargetScalingView == null || dyConsumed != 0) {mScaleImpl.cancelAnimations();super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);return;}if (dyUnconsumed < 0 && getTopAndBottomOffset() >= mScaleImpl.getInitialParentBottom()) {int absDyUnconsumed = Math.abs(dyUnconsumed);mTotalDyUnconsumed += absDyUnconsumed;mTotalDyUnconsumed = Math.min(mTotalDyUnconsumed, mTotalTargetDyUnconsumed);mScaleImpl.updateViewScale();} else {mTotalDyUnconsumed = 0;mScaleImpl.setShouldRestore(false);if (dyConsumed != 0) {mScaleImpl.cancelAnimations();}super.onNestedScroll(coordinatorLayout, .... dxUnconsumed, dyUnconsumed);} }

    當(dāng)嵌套的overscroll停止的時候,我們需要將視圖的邊界和大小重置到它們的原始值。

    @Override public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target) {mScaleImpl.retractScale();super.onStopNestedScroll(coordinatorLayout, child, target);}

    ViewScaler

    這個類實現(xiàn)了AppBarLayout應(yīng)該如何改變它的底部以及視圖應(yīng)該 如何改變尺寸的邏輯。大多數(shù)行為都依賴累積的未填充的像素。我們可以為最大累積值設(shè)置一個約束值,這樣可以很容的找到要如何改變AppBarLayout 底部和改變視圖的尺寸。ParentScaler是ViewScaler的父類,它能讓AppBarLayout近乎平滑的改變尺寸。我就不在這里貼大量 代碼了,如果你有興趣,可以從這里獲取代碼。

    Bonus

    大神們,這里有個MatrixScaler類,我沒有時間去完成它。如果想要改變尺寸的視圖是ImageView,并且設(shè)置了ScaleType為MATRIX,這個類將可以用使用矩陣的方式來改變圖像的尺寸。

    Demo

    總結(jié)

    以上是生活随笔為你收集整理的【译文】AppBarLayout的越界滚动行为的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。