最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android 三級NestedScroll嵌套滾動實(shí)踐

 更新時間:2019年02月12日 11:39:53   作者:walkeer  
這篇文章主要介紹了Android 三級NestedScroll嵌套滾動實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

嵌套滾動介紹

我們知道 NestedScrolling(Parent/Child) 這對接口是用來實(shí)現(xiàn)嵌套滾動的,一般實(shí)現(xiàn)這對接口的 Parent 和 Child 沒有直接嵌套,否則直接用 onInterceptTouchEvent() 和 onTouchEvent() 這對方法實(shí)現(xiàn)就可以了。能夠越級嵌套滾動正是它的厲害之處。

嵌套滾動的接口有兩對:NestedScrolling(Parent/Child) 和 NestedScrolling(Parent2/Child2) 后者相比前者對 fling 的處理更加細(xì)致。相比第一代 Child 簡單地將 fling 拋給 Parent,第二代 Child 將 fling 轉(zhuǎn)化為 scroll 后再分發(fā)給 Parent,為了和普通的 scroll 區(qū)分增加了一個參數(shù) type, 當(dāng) type 是 ViewCompat.TYPE_TOUCH 時表示普通的 scroll,當(dāng)是 ViewCompat.TYPE_NON_TOUCH 時表示由 fling 轉(zhuǎn)化而來的 scroll。這樣做的好處是當(dāng) Child 檢測到一個 fling 時,它可以選擇將這個 fling 引起的 scroll 一部分作用在 Parent 上一部分作用在自己身上,而不是只作用在 Parent 或者 Child 上。或許你會問 fling 為什么不能選擇 Parent 和 Child 都作用,事實(shí)上你可以,但 fling 的話 Parent 沒法告訴 Child 消費(fèi)了多少,剩下多少,因?yàn)?fling 傳遞的值是速度,不像 scroll 是距離。所以通過 NestedScrolling(Parent2/Child2) 實(shí)現(xiàn)嵌套滾動時,當(dāng)你觸發(fā)了一個 fling 時,也可以做很順滑連貫的交替滾動,而 1 就很難達(dá)到相同的效果?,F(xiàn)在官方 View 的實(shí)現(xiàn)也是通過 NestedScrolling(Parent2/Child2),所以我們在實(shí)現(xiàn)自定義的嵌套滾動時盡量用 2。

上面簡單介紹了 NestedScrolling 2 和 1 的區(qū)別以及為什么要使用2。現(xiàn)在我們來看看 NestedScrolling(Parent2/Child2) 的方法,1 就不看了,和 2 差不多。

public interface NestedScrollingChild2 {

 void setNestedScrollingEnabled(boolean enabled);

 boolean isNestedScrollingEnabled();

 boolean startNestedScroll(@ScrollAxis int axes, @NestedScrollType int type);
 
 void stopNestedScroll(@NestedScrollType int type);

 boolean hasNestedScrollingParent(@NestedScrollType int type);

 boolean dispatchNestedScroll(int dxConsumed, int dyConsumed,
   int dxUnconsumed, int dyUnconsumed, @Nullable int[] offsetInWindow,
   @NestedScrollType int type);
   
	boolean dispatchNestedPreScroll(int dx, int dy, @Nullable int[] consumed,
   @Nullable int[] offsetInWindow, @NestedScrollType int type);
}
public interface NestedScrollingParent2 {

	boolean onStartNestedScroll(@NonNull View child, @NonNull View target, @ScrollAxis int axes,
   @NestedScrollType int type);
   
	void onNestedScrollAccepted(@NonNull View child, @NonNull View target, @ScrollAxis int axes,
   @NestedScrollType int type);
   
	void onStopNestedScroll(@NonNull View target, @NestedScrollType int type);

	void onNestedScroll(@NonNull View target, int dxConsumed, int dyConsumed,
   int dxUnconsumed, int dyUnconsumed, @NestedScrollType int type);

	void onNestedPreScroll(@NonNull View target, int dx, int dy, @NonNull int[] consumed,
   @NestedScrollType int type);
}

從這兩個接口的方法可以看出這些方法都是一一對應(yīng)的,比如 startNestedScroll 和 onStartNestedScroll,stopNestedScroll 和 onStopNestedScroll 等。從這些方法的命名上也能看出來嵌套滾動的交互順序是 Child 主動觸發(fā),Parent 被動接受,所以決定是否打開嵌套滾動的方法 setNestedScrollingEnabled 由 Child 實(shí)現(xiàn),決定開始和結(jié)束的方法 startNestedScroll 和 stopNestedScroll 也由 Child 實(shí)現(xiàn)。

這里用一個圖來表示嵌套滾動流程

整個過程大概分為兩部分:綁定和滾動分發(fā)。綁定部分可以理解為 Child 向上遍歷找 NestedScrollingParent2 的過程,找到后調(diào)用它的 onStartNestedScroll 方法,如果返回 true 則說明這個 Parent 想接收 nested scroll,Child 會緊接著調(diào) onNestedScrollAccepted 方法表示同意 Parent 處理自己分發(fā)的 nested scroll,對應(yīng)上圖中的 1 2 3。滾動分發(fā)部分 Child 將自己的 scroll 分為三個階段 before scroll after,before 和 after 分發(fā)給 parent 消費(fèi),scroll 階段讓自己消費(fèi),這三個階段是按順序進(jìn)行的,換句話說如果前一步消耗完了 scroll,那后面的階段就沒有 scroll 可以消費(fèi)。這樣做的好處是讓 Parent 可以在自己消費(fèi)之前或者之后消費(fèi) scroll,如果 Parent 想在 Child 之前消費(fèi)就在 onNestedPreScroll 方法里處理,否則就在 onNestedScroll 方法里,對應(yīng)上圖中的 4 5 步。上面介紹到的一些通用邏輯被封裝在 NestedScrollingChildHelper 和 NestedScrollingParentHelper 中,在 NestedScrolling(Parent2/Child2) 的方法中可以調(diào)用 Helper 類中的同名方法,比如 NestedScrollingChild2.startNestedScroll 方法中實(shí)現(xiàn)了向上遍歷尋找 NestedScrollingParent 的邏輯。

三級嵌套滾動

一個常見的嵌套滾動例子是 CoordinatorLayout/AppbarLayout - RecyclerView, 實(shí)現(xiàn)的效果是向上滑動列表時,會先將 AppbarLayout 向上滑動直到完全折疊,向下滑動至列表最頂部后會展開 AppbarLayout, 如下圖:

這里實(shí)現(xiàn) NestedScrollingParent2 的是 CoordinatorLayout/AppbarLayout, 實(shí)現(xiàn) NestedScrollingChild2 的是 RecyclerView。對于這種兩級嵌套滾動的需求使用 CoordinatorLayout 幾乎都能實(shí)現(xiàn),如果遇到特殊的業(yè)務(wù)需求基于 CoordinatorLayout 和 RecyclerView 的實(shí)現(xiàn)改改也能實(shí)現(xiàn)。

我這里遇到的需求是即刻首頁的樣式(可參考即刻5.4.2版本),除了要有 AppbarLayout 折疊效果之外還要在 AppbarLayout 頂部展示搜索框和刷新動畫。這里的滑動邏輯是:

  • 向上滑動時,最先折疊刷新動畫,向下滑動時最后展開刷新動畫。
  • 向上滑動列表時先折疊 AppbarLayout,AppbarLayout 完全折疊后再折疊搜索框。
  • 向下滑動列表時在展開 AppbarLayout 之前先展開搜索框。
  • 列表沒滑動到頂部時可以通過觸發(fā)一定速度的向下 fling 來展開搜索框。

可以發(fā)現(xiàn)這里除了 CoordinatorLayout/AppbarLayout - RecyclerView 這對嵌套滾動的 Parent 和 Child 之外還多了搜索框和刷新動畫,而這三者之間的滑動邏輯需要通過嵌套滾動實(shí)現(xiàn),只是傳統(tǒng)的兩級嵌套滾動不能滿足,所以需要實(shí)現(xiàn)三級嵌套滾動。

所謂三級嵌套滾動是在兩級嵌套滾動之上再添加一個 Parent,這里為了表述方便將三級嵌套滾動的三級由上到下分別稱為 Grand Parent Child。具體是由兩對 NestedScrolling(Parent2/Child2) 接口實(shí)現(xiàn),Grand 實(shí)現(xiàn)第一對接口的 Parent,Parent 實(shí)現(xiàn)第一對接口的 Child 和第二對接口的 Parent,Child 實(shí)現(xiàn)第二對接口的 Child。與兩級嵌套滾動相比三級嵌套的 Grand 和 Child 和兩級的 Parent 和 Child 區(qū)別不大,變化比較大的是三級的 Parent 既要實(shí)現(xiàn)兩級的 Parent 接口又要實(shí)現(xiàn) Child 接口,示意圖如下:

在即刻首頁這個例子里,CoordinatorLayout/AppbarLayout 屬于三級嵌套的 Parent 實(shí)現(xiàn)了第二對接口的 NestedScrollingParent2,RecyclerView 屬于 Child 實(shí)現(xiàn)了第二對接口的 NestedScrollingChild2。這里我們需要做的是實(shí)現(xiàn)第一對嵌套接口,新建一個自定義 Layout 實(shí)現(xiàn) NestedScrollingParent2 接口作為三級嵌套的 Grand,負(fù)責(zé)搜索框和刷新動畫的折疊和展開。再新建一個自定義 Layout 繼承 CoordinatorLayout 實(shí)現(xiàn) NestedScrollingChild2 接口,負(fù)責(zé)攔截列表分發(fā)上來的滾動事件或者處理 AppbarLayout 消費(fèi)后剩下的滾動事件。

二級嵌套滾動可以理解為給 Parent 提供了攔截 Child 滾動事件和處理 Child 剩余滾動事件的能力,具體邏輯可參考本文最開始介紹嵌套滾動的部分。相應(yīng)的三級嵌套滾動給 Grand 提供了攔截 Parent 和處理剩余滾動事件的能力,只是攔截和處理的時機(jī)多了一些,如下圖:

二級嵌套滾動對滾動處理時機(jī)只有三個階段:preScroll、scroll 和 afterScroll。而三級嵌套滾動的處理時機(jī)就多一些,有七個階段:prePreScroll、preScroll、afterPreScroll、scroll、preAfterScroll、afterScroll 和 afterAfterScroll,可以看出相比二級嵌套多了 prePreScroll、afterPreScroll、preAfterScroll 和 afterAfterScroll 這四個階段,多出的這幾個階段都是給 Grand 用的。到這里可以發(fā)現(xiàn) NestedScrollingParent2 其實(shí)不能完全描述 Grand 的能力,確實(shí)最理想的方案應(yīng)該是新建一對接口 NestedScrollingGrand2 和 NestedScrollingGrandChild2 來描述新增的四個對滾動事件的處理階段,但考慮到我這里的例子 Grand 對 Parent 的處理沒有那么精細(xì)化,所以還是通過復(fù)用 NestedScrolling(Parent2/Child2) 和一些附加方法來實(shí)現(xiàn)。以后如果實(shí)現(xiàn)了 NestedScrolling(Grand2/GrandChild2) 接口,也會及時更新。根據(jù)上圖即刻首頁滑動的實(shí)現(xiàn)思路就很簡單了:

  • onPrePreScroll 中執(zhí)行折疊刷新動畫的邏輯,onAfterAfterScroll 中執(zhí)行展開刷新動畫的邏輯。
  • onPreScroll 中執(zhí)行折疊 AppbarLayout 的邏輯,onAfterPreScroll 中執(zhí)行搜索框折疊的邏輯。
  • onAfterScroll 中執(zhí)行展開 AppbarLayout 的邏輯,onPreAfterScroll 中執(zhí)行搜索框展開的邏輯。
  • 列表沒滑到頂部根據(jù) fling 展開搜索框的邏輯單獨(dú)在 Parent 的 onNestedPreFling 里做,這條算是一個特殊處理。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Mac Android Studio 3.0 Terminal 中文亂碼問題處理

    Mac Android Studio 3.0 Terminal 中文亂碼問題處理

    本文給大家分享的是在更新Android Studio 3.0之后,使用Terminal時,發(fā)現(xiàn) git log 命令查看歷史 log會亂碼,以及最后的解決方法,推薦給小伙伴們
    2017-11-11
  • Android自定義EditText右側(cè)帶圖片控件

    Android自定義EditText右側(cè)帶圖片控件

    這篇文章主要為大家詳細(xì)介紹了Android自定義EditText右側(cè)帶圖片控件的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • Android模擬器中窗口截圖存成文件實(shí)現(xiàn)思路及代碼

    Android模擬器中窗口截圖存成文件實(shí)現(xiàn)思路及代碼

    Android模擬器內(nèi)容是用OpenGL渲染的,所以用一般的編程截圖(如PrintWindow()等)會是黑屏。這是因?yàn)楫嫷臇|西放在framebuffer里 接下來介紹如何實(shí)現(xiàn)Android模擬器中窗口截圖存成文件,感興趣的朋友可以了解下哦
    2013-01-01
  • Android自定義軟鍵盤的步驟記錄

    Android自定義軟鍵盤的步驟記錄

    Android軟鍵盤這塊從我入職到現(xiàn)在,是一個一直糾纏我的問題,這篇文章主要給大家介紹了關(guān)于Android自定義軟鍵盤的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2021-08-08
  • Android使用CountDownTimer實(shí)現(xiàn)倒計(jì)時效果

    Android使用CountDownTimer實(shí)現(xiàn)倒計(jì)時效果

    這篇文章主要為大家詳細(xì)介紹了Android使用CountDownTimer實(shí)現(xiàn)倒計(jì)時效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • Kotlin 中范圍操作符的使用示例代碼(范圍操作符不同用法)

    Kotlin 中范圍操作符的使用示例代碼(范圍操作符不同用法)

    Kotlin中的范圍操作符(in、step、downTo、until)在Android開發(fā)中非常實(shí)用,通過這些操作符,可以簡潔地遍歷整數(shù)范圍,實(shí)現(xiàn)各種遍歷需求,提高代碼的可讀性和可維護(hù)性,本文介紹Kotlin 中范圍操作符的使用示例,感興趣的朋友一起看看吧
    2025-03-03
  • Android如何獲取視頻首幀圖片

    Android如何獲取視頻首幀圖片

    這篇文章主要為大家詳細(xì)介紹了Android如何獲取視頻首幀圖片的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • Android中Item實(shí)現(xiàn)點(diǎn)擊水波紋效果

    Android中Item實(shí)現(xiàn)點(diǎn)擊水波紋效果

    這篇文章主要給大家介紹了關(guān)于Android中Item實(shí)現(xiàn)點(diǎn)擊水波紋效果的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對各位Android開發(fā)者們具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-11-11
  • Android視頻/音頻緩存框架AndroidVideoCache(Okhttp)詳解

    Android視頻/音頻緩存框架AndroidVideoCache(Okhttp)詳解

    這篇文章主要為大家詳細(xì)介紹了Android視頻、音頻緩存框架AndroidVideoCache,實(shí)現(xiàn)邊下邊播功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-07-07
  • Android 判斷是否是是全漢字、全字母、全數(shù)字、數(shù)字和字母等(代碼)

    Android 判斷是否是是全漢字、全字母、全數(shù)字、數(shù)字和字母等(代碼)

    這篇文章主要介紹了Android 判斷是否是是全漢字、全字母、全數(shù)字、數(shù)字和字母等的實(shí)例代碼,需要的朋友可以參考下
    2016-12-12

最新評論

深圳市| 镇原县| 红桥区| 柏乡县| 汶川县| 崇义县| 凤山县| 曲阳县| 原平市| 龙海市| 平度市| 永州市| 会同县| 齐齐哈尔市| 丽水市| 建昌县| 沁源县| 高阳县| 曲靖市| 宁南县| 石棉县| 高唐县| 海城市| 社会| 东城区| 宜宾市| 崇阳县| 新民市| 德保县| 松原市| 曲松县| 上饶县| 昌平区| 德清县| 高雄县| 栖霞市| 清原| 綦江县| 梨树县| 达州市| 陇西县|