Android嵌套滑動沖突

android在嵌套滑動的時候會產(chǎn)生滑動沖突砾跃。之前我也碰到骏啰,但是以前的筆記本丟失了,所以只能重新再寫一章抽高。

一.會產(chǎn)生滑動沖突的情況

那么什么時候會產(chǎn)生滑動沖突呢判耕?比如你有個activity,activity的上半部分是一個布局翘骂,下半部分是一個可滑動控件(RecyclerView壁熄、ListView等),或者下半部分是個viewpager碳竟,里面的fragment布局是一個可滑動控件草丧,這樣的頁面就會產(chǎn)生滑動沖突。

二.以前的做法

雖然我以前的筆記丟失了莹桅,但是當(dāng)時的解決問題的思路我依然記得昌执。
(1)重寫一個viewpager繼承系統(tǒng)的ViewPager,至于怎么重寫的我不太記得了
(2)重寫RecyclerView繼承系統(tǒng)的RecyclerView,因為我記得會出現(xiàn)高度的原因?qū)е翿ecyclerView不設(shè)置固定高度的話會不顯示或者只顯示一個Item仙蚜,所以要重寫RecyclerView去動態(tài)衡量Item x count 的高度此洲。
當(dāng)時雖然能解決,但是最后的效果很變扭委粉。

三.現(xiàn)在的做法

現(xiàn)在我肯定不會像之前一樣做呜师,因為出了一個新控件NestedScrollView。它能夠很好的幫我們解決滑動沖突贾节,接下來我會盡我所能分析所有可能出現(xiàn)的情況汁汗。

1.布局只嵌套RecyclerView的情況

就是如下圖的情況:

image.png

這種情況最容易解決,就直接使用NestedScrollView做父布局栗涂,然后嵌套RecyclerView就行知牌。

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/m_nsv"
    android:fillViewport="true"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        >

        <TextView
            android:layout_width="match_parent"
            android:layout_height="150dp"
            android:text="Hello World!" />

        <android.support.v7.widget.RecyclerView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/c_rv"
            >
        
        </android.support.v7.widget.RecyclerView>

    </LinearLayout>

</android.support.v4.widget.NestedScrollView>

這樣就行,切記要記住兩點:
(1)在父布局NestedScrollView加android:fillViewport="true"斤程,然后RecyclerView會不顯示出來角寸,不顯示出來的原因是RecyclerView是一個動態(tài)展示的View,而直接使用的話用我之前說的話叫做會被壓扁忿墅,所以加這個屬性讓子View顯示match_parent的效果扁藕。
(2)有的人說要給RecyclerView設(shè)setNestedScrollingEnabled(false),不然滑動時會卡疚脐,這個我沒試過亿柑,我設(shè)的是true,目前感覺滑動時沒什么影響棍弄。

2.布局嵌套其它可滾動控件的情況

就是在第一種情況下把RecyclerView換成其它可滑動控件望薄。
直接說吧,你要用NestedScrollView才有用呼畸,原因是解決滑動沖突的關(guān)鍵在于NestedScrollingParent和NestedScrollingChild兩個接口(下面會詳細(xì)說)
而RecyclerView和NestedScrollView都實現(xiàn)NestedScrollingChild接口痕支,并在內(nèi)部封裝了解決滑動沖突的邏輯處理,所以只有NestedScrollView直接嵌套RecyclerView或NestedScrollView不會產(chǎn)生滑動沖突役耕。
NestedScrollView的用法和RecyclerView一樣采转,記得加那些屬性。

3.布局嵌套ViewPager瞬痘,ViewPager嵌套RecyclerView等可滑動控件的情況

這種情況處理起來比較麻煩,而很多人都是碰到這種情況板熊。如下圖:

image.png

其實我之前寫過一篇文章能解決這種情況框全,那就是使用CoordinatorLayout,使用CoordinatorLayout能解決這種情況干签。
但是津辩,我文章里也說過了,CoordinatorLayout有BUG,使用起來卡得像坨屎一樣喘沿,不管你能不能忍闸度,反正我是不能忍,所以我不會使用CoordinatorLayout蚜印。

不用CoordinatorLayout還有以下三種解決辦法:
(1)使用github上面開源的那個自定義CoordinatorLayout來解決莺禁,叫什么我忘了。

但是我們老大說了窄赋,最好別用別人的開源View哟冬。于是我只能用第二種方法。

(2)放棄使用ViewPager
為什么忆绰,因為系統(tǒng)的ViewPager做不到浩峡,上面有說到能解決沖突是因為NestedScrollingParent和NestedScrollingChild,并且NestedScrollingChild的ViewGroup要是實現(xiàn)NestedScrollingParent接口的View错敢,NestedScrollingParent的ChildView要是實現(xiàn)NestedScrollingChild接口的View翰灾。
而圖中的父布局和RecyclerView隔著一個ViewPager,也就是說NestedScrollingParent的ChildView是ViewPager稚茅,NestedScrollingChild的ViewGroup是ViewPager预侯。所以說直接嵌套一層ViewPager的情況是無法解決滑動沖突的。
那有一個很直接的辦法就是不用ViewPager峰锁,用FragmentManager萎馅,這樣就能實現(xiàn)解決滑動沖突。

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:fillViewport="true"
    android:id="@+id/nsv"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    xmlns:android="http://schemas.android.com/apk/res/android">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <LinearLayout
                android:descendantFocusability="blocksDescendants"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@color/white"
                android:orientation="horizontal"
                android:minHeight="10dp"
                android:padding="10dp"
                android:id="@+id/ll_header">

                .........................................

              </LinearLayout>
           </LinearLayout>


            <android.support.v4.widget.NestedScrollView
                android:layout_marginTop="15dp"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fillViewport="true"
                android:id="@+id/c_nsv"
                >
                <FrameLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:id="@+id/fl_content"
                    >

                </FrameLayout>

            </android.support.v4.widget.NestedScrollView>

        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>

這里的FrameLayout就是給FragmentManager來顯示FrameLayout虹蒋。
這樣做就能解決一個activity多個fragment的情況下的滑動沖突糜芳。

但是有的朋友說不嘛,我就要Viewpager魄衅,我就要酷酷的滑動動畫效果峭竣。唉,那你就用最實在的第三中方法吧晃虫。

(3)自定義
沒辦法了皆撩,那就用自定義吧,自定義一個VIewGroup實現(xiàn)NestedScrollingParent接口哲银,然后自定義一個View實現(xiàn)NestedScrollingChild接口扛吞。或者你可以外層使用NestedScrollView,內(nèi)層自定義ViewPager來實現(xiàn)NestedScrollingChild接口荆责。

你以為這樣就完啦滥比?當(dāng)然沒這么簡單。在NestedScrollingChild接口中有這些方法做院。

image.png

你需要在這些方法里面自己寫上處理滑動沖突的邏輯盲泛,你可以參考RecyclerView的去寫濒持,也可以在網(wǎng)上找,網(wǎng)上有一些大神是真的有介紹寺滚,但也有一些人要么瞎JB抄別人的又不抄完柑营,要么只會說用CoordinatorLayout。我其實也不是很會里面的細(xì)節(jié)處理村视,只是知道流程而已官套,所以也不裝X了。

四.其它使用時的問題

并非解決滑動沖突就沒有其它問題蓖议。

1.NestedScrollView(RecyclerView)重新加載數(shù)據(jù)時會自動滾動到底部虏杰。

如果你碰到這種情況,只要給父布局的NestedScrollView設(shè).scrollTo(0, 0)就行勒虾,和ScrollView一樣的纺阔。

2.禁止滑動。

如果你想在某些情況下禁止NestedScrollView滑動修然,可以像處理ScrollView一樣笛钝,在父布局的NestedScrollView加入監(jiān)聽,例如我這:

public void isScroll(boolean bol){
        Nsv.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return !bol;
            }
        });
    }

這個方法是設(shè)置可滑動和不可滑動愕宋。

3.記得設(shè)android:fillViewport="true"

如果你嵌套的布局沒有顯示玻靡,那有可能你忘了給父布局NestedScrollView設(shè)置android:fillViewport屬性。

目前就碰到這些問題中贝,有什么以后再接著補(bǔ)充吧囤捻。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市邻寿,隨后出現(xiàn)的幾起案子蝎土,更是在濱河造成了極大的恐慌,老刑警劉巖绣否,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件誊涯,死亡現(xiàn)場離奇詭異,居然都是意外死亡蒜撮,警方通過查閱死者的電腦和手機(jī)暴构,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來段磨,“玉大人取逾,你說我怎么就攤上這事∞崩#” “怎么了菌赖?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長沐序。 經(jīng)常有香客問我琉用,道長,這世上最難降的妖魔是什么策幼? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任邑时,我火速辦了婚禮,結(jié)果婚禮上特姐,老公的妹妹穿的比我還像新娘晶丘。我一直安慰自己,他們只是感情好唐含,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布浅浮。 她就那樣靜靜地躺著,像睡著了一般捷枯。 火紅的嫁衣襯著肌膚如雪滚秩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天淮捆,我揣著相機(jī)與錄音郁油,去河邊找鬼。 笑死攀痊,一個胖子當(dāng)著我的面吹牛桐腌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播苟径,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼案站,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了棘街?” 一聲冷哼從身側(cè)響起蟆盐,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蹬碧,沒想到半個月后舱禽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡恩沽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年誊稚,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片罗心。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡里伯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出渤闷,到底是詐尸還是另有隱情疾瓮,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布飒箭,位于F島的核電站狼电,受9級特大地震影響蜒灰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜肩碟,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一强窖、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧削祈,春花似錦翅溺、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至吨拍,卻和暖如春褪猛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背密末。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工握爷, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人严里。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓新啼,卻偏偏與公主長得像,于是被迫代替她去往敵國和親刹碾。 傳聞我的和親對象是個殘疾皇子燥撞,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容