天天看點

layout布局_Android 持續滑動布局 ConsecutiveScrollerLayout 的使用

code小生 一個專注大前端領域的技術平台公衆号回複

Android

加入安卓技術群

作者:donkingliang

連結:https://www.jianshu.com/p/0783b0a37fa1

聲明:本文已獲

donkingliang

授權發表,轉發等請聯系原作者授權

在開發項目的時候,有時候會遇到一些比較複雜的頁面,需要多個不同的清單或者滑動布局、甚至是

WebView

,組成一個完整的頁面。要實作這樣一個複雜的頁面,在以前我們可能會通過布局嵌套的方式,在一個大的

ScrollView

下嵌套多個

RecyclerView

WebView

ScrollView

來實作。但是這種嵌套的方式不僅會嚴重影響布局的性能,而且處理滑動事件的沖突也是一件頭疼的事,處理不好會嚴重影響使用者操作的體驗。

ConsecutiveScrollerLayout

正是為了解決這個難題而設計的滑動布局,它可以同時嵌套多個滑動布局(RecyclerView、WebView、ScrollView等)和普通控件(TextView、ImageView、LinearLayou、自定義View等),它把所有的子View看作是一個整體,由

ConsecutiveScrollerLayout

來統一處理布局的滑動,使得多個滑動布局就像一個整體一樣連續滑動,它的效果就像是一個

ScrollView

一樣。而且它支援嵌套所有的View,具有很好的通用性。

使用者不需要關心它是如何滑動的,也不需要考慮滑動的沖突問題,并且不用擔心它會影響子

View

的性能。

下面是對

ConsecutiveScrollerLayout

的使用介紹和一寫注意事項。

項目位址:https://github.com/donkingliang/ConsecutiveScroller

ConsecutiveScroller的設計思路和源碼分析:https://www.jianshu.com/p/34d2c5cdb3fb

效果圖

layout布局_Android 持續滑動布局 ConsecutiveScrollerLayout 的使用

sample.gif

layout布局_Android 持續滑動布局 ConsecutiveScrollerLayout 的使用

sticky.gif

引入依賴

在Project的build.gradle在添加以下代碼

在Module的build.gradle在添加以下代碼

注意:如果你準備使用這個庫,請務必認真閱讀下面的文檔。它能讓你了解ConsecutiveScrollerLayout可以實作的功能,以及避免不必要的錯誤。

基本使用

ConsecutiveScrollerLayout的使用非常簡單,把需要滑動的布局作為ConsecutiveScrollerLayout的直接子View即可。

關于margin

ConsecutiveScrollerLayout支援左右margin,但是不支援上下margin,子View間的間距可以通過Space設定。

布局對齊方式

ConsecutiveScrollerLayout

的布局方式類似于垂直的

LinearLayout

,但是它沒有gravity和子

view layout_gravity

屬性。

ConsecutiveScrollerLayout

為它的子view提供了

layout_align

屬性,用于設定子view和父布局的對齊方式。layout_align有三個值:左對齊(LEFT) 、右對齊(RIGHT) 和中間對齊(CENTER)。

嵌套Fragment

要想把一個

Fragment

嵌套在

ConsecutiveScrollerLayout

裡。通常我們需要一個布局容器來承載我們的Fragment,或者直接把Fragment寫在activity的布局裡。如果Fragment是垂直滑動的,那麼承載Fragment的容器需要是

ConsecutiveScrollerLayout

,以及Fragment的根布局也需要是垂直滑動的。我們推薦使用

ConsecutiveScrollerLayout

或者其他可垂直滑動的控件(比如:RecyclerView、NestedScrollView)作為Fragment的根布局。如果你的Fragment不是垂直滑動的,則可以忽略這個限制。

布局吸頂

要實作布局的吸頂效果,在以前,我們可能會寫兩個一摸一樣的布局,一個隐藏在頂部,一個嵌套在

ScrollView

下,通過監聽

ScrollView

的滑動來顯示和隐藏頂部的布局。這種方式實作起來既麻煩也不優雅。

ConsecutiveScrollerLayout

内部實作了子View吸附頂部的功能,隻要設定一個屬性,就可以實作吸頂功能。而且支援設定多個子View吸頂,後面的View要吸頂時會把前面的吸頂View推出螢幕。

常駐吸頂

如果你不希望吸頂的view被後面的吸頂view頂出螢幕,而且多個吸頂view排列吸附在頂部,你可以設定常駐吸頂模式:app:isPermanent="true"。

關于吸頂功能的其他方法

局部滑動

ConsecutiveScrollerLayout

将所有的子View視作一個整體,由它統一處理頁面的滑動事件,是以它預設會攔截可滑動的子View的滑動事件,由自己來分發處理。并且會追蹤使用者的手指滑動事件,計算調整

ConsecutiveScrollerLayout

滑動偏移。如果你希望某個子View自己處理自己的滑動事件,可以通過設定

layout_isConsecutive

屬性來告訴父View不要攔截它的滑動事件,這樣就可以實作在這個View自己的高度内滑動自己的内容,而不會作為

ConsecutiveScrollerLayout

的一部分來處理。

在這個例子中

NestedScrollView

希望在自己的高度裡滑動自己的内容,而不是跟随

ConsecutiveScrollerLayout

滑動,隻要給它設定

layout_isConsecutive="false"

就可以了。而

LinearLayout

雖然不是滑動布局,但是在下面嵌套了個滑動布局

RecyclerView

,是以它也需要設定

layout_isConsecutive="false"

ConsecutiveScrollerLayout

支援

NestedScrolling

機制,如果你的局部滑動的view實作了

NestedScrollingChild

接口(如:RecyclerView、NestedScrollView等),它滑動完成後會把滑動事件交給父布局。如果你不想你的子view或它的下級view與父布局嵌套滑動,可以給子view設定

app:layout_isNestedScroll="false"

。它可以禁止子view與

ConsecutiveScrollerLayout

的嵌套滑動

滑動子view的下級view

ConsecutiveScrollerLayout

預設情況下隻會處理它的直接子view的滑動,但有時候需要滑動的布局可能不是

ConsecutiveScrollerLayout

的直接子view,而是子view所嵌套的下級view。比如

ConsecutiveScrollerLayout

嵌套

FrameLayout

,

FrameLayout

嵌套

ScrollView

,我們希望

ConsecutiveScrollerLayout

也能正常處理ScrollView的滑動。為了支援這種需求,

ConsecutiveScroller

提供了一個接口:

IConsecutiveScroller

。子view實作

IConsecutiveScroller

接口,并通過實作接口方法告訴ConsecutiveScrollerLayout需要滑動的下級view,

ConsecutiveScrollerLayout

就能正确地處理它的滑動事件。

IConsecutiveScroller

需要實作兩個方法:

在前面提到的例子中,我們可以這樣實作:

public class MyFrameLayout extends FrameLayout implements IConsecutiveScroller {

    @Override
    public View getCurrentScrollerView() {
        // 傳回需要滑動的ScrollView
        return getChildAt(0);
    }

    @Override
    public List getScrolledViews() {
        // 傳回需要滑動的ScrollView
        List views = new ArrayList<>();
        views.add(getChildAt(0));return views;
    }
}
           

這樣

ConsecutiveScrollerLayout

就能正确地處理

ScrollView

的滑動。這是一個簡單的例子,在實際的需求中,我們一般不需要這樣做。

注意:

1、getCurrentScrollerView()和getScrolledViews()必須正确地傳回需要滑動的view,這些view可以是經過多層嵌套的,不一定是直接子view。是以使用者應該按照自己的實際場景去實作者兩個方法。

2、滑動的控件應該跟嵌套它的子view的高度保持一緻,也就是說滑動的控件高度應該是match_parent,并且包裹它的子view和它本身都不要設定上下邊距(margin和ppadding)。寬度沒有這個限制。

對ViewPager的支援

如果你的

ViewPager

承載的子布局(或Fragment)不是可以垂直滑動的,那麼使用普通的

ViewPager

即可。如果是可以垂直滑動的,那麼你的ViewPager需要實作

IConsecutiveScroller

接口,并傳回需要滑動的view對象。架構裡提供了一個實作了

IConsecutiveScroller

接口自定義控件:

ConsecutiveViewPager

。使用這個控件,然後你的

ConsecutiveViewPager

的子view(或Fragment的根布局)是可垂直滑動的view,如:RecyclerView、NestedScrollView、ConsecutiveScrollerLayout即可。這樣你的

ViewPager

就能正确地跟

ConsecutiveScrollerLayout

一起滑動了。

布局吸頂時會覆寫在下面的布局的上面,有時候我們希望TabLayout吸頂懸浮在頂部,但是不希望它覆寫遮擋ViewPager的内容。ConsecutiveViewPager提供了setAdjustHeight調整自己的布局高度,讓自己不被TabLayout覆寫。注意:隻有ConsecutiveScrollerLayout是ConsecutiveScrollerLayout的最低部時才能這樣做。

其他注意事項

1、WebView在加載的過程中如果滑動的布局,可能會導緻WebView與其他View在顯示上斷層,使用下面的方法一定程度上可以避免這個問題。

2、

SmartRefreshLayout

SwipeRefreshLayout

等重新整理控件可以嵌套

ConsecutiveScrollerLayout

實作下拉重新整理功能,但是

ConsecutiveScrollerLayout

内部嵌套它們來重新整理子view,因為子view時

ConsecutiveScrollerLayout

滑動内容等一部分。除非你給

SmartRefreshLayout

或者

SwipeRefreshLayout

設定

app:layout_isConsecutive="false"

3、繼承AbsListView的布局(ListView、GridView等),在滑動上可能會與使用者的手指滑動不同步,推薦使用RecyclerView代替。

4、

ConsecutiveScroller

minSdkVersion

是 19,如果你的項目支援19 以下,可以設定:

但是不要在

minSdkVersion

小于 19 的項目使用

AbsListView

的子類,因為

ConsecutiveScrollerLayout

使用了隻有19以上才有的

AbsListView API

5、使用

ConsecutiveScrollerLayout

提供的

setOnVerticalScrollChangeListener()

方法監聽布局的滑動事件。View所提供的

setOnScrollChangeListener()

方法已無效。

6、通過

getOwnScrollY()

方法擷取

ConsecutiveScrollerLayout

的垂直滑動距離,View的

getScrollY()

方法擷取的不是

ConsecutiveScrollerLayout

的整體滑動距離。

相關閱讀

1 利用 Android 嵌套滑動機制輕松實作頂部布局置頂

2 玩轉仿探探卡片式滑動效果

3 不使用第三方庫,Bitmap 的優化政策

4 Android 中使用 APT 簡化代碼

5 Android MVP && MVVM深度解析

layout布局_Android 持續滑動布局 ConsecutiveScrollerLayout 的使用

如果你有寫部落格的好習慣歡迎投稿

點個在看,小生感恩❤️