Android ScrollView粘性頭部代碼分享
前言,一天在點(diǎn)外賣的時(shí)候,注意到餓了么列表頁的滑動(dòng)效果不錯(cuò),但是覺得其中的手勢(shì)滑動(dòng)還是挺復(fù)雜的,正好又碰到了在熟悉Touch事件的理解當(dāng)中,所以就抽空對(duì)著餓了么的列表頁面嘗試寫寫這個(gè)效果
1.先貼一個(gè)實(shí)現(xiàn)的效果圖
邏輯是當(dāng)外部的ScrollView沒有滑到底部的時(shí)候,往上滑動(dòng)的時(shí)候,是滑動(dòng)外部的ScrollView,當(dāng)外部的ScrollView到達(dá)底部的時(shí)候,我們?cè)倬W(wǎng)上滑,就是滑動(dòng)內(nèi)部的列表了,另外在左右滑動(dòng)的時(shí)候,當(dāng)左右滑動(dòng)的距離大于minPageSlop的話,那么就執(zhí)行左右滑動(dòng)。
如下是仿餓了么的列表頁的效果圖:
2.引入
在項(xiàng)目根目錄的build.gradle文件下增加jitpack的repo地址 allprojects { repositories { jcenter() maven { url "https://jitpack.io" } } } 在需要引入的module中引入library dependencies { implementation 'com.github.WelliJohn:StickScrollView:0.0.3' }
3.界面的布局說明
<wellijohn.org.stickscrollview.ScrollViewWithStickHeader android:id="@+id/stick_scroll_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1"> <LinearLayout android:id="@+id/ll" android:layout_width="match_parent" android:layout_height="match_parent" android:descendantFocusability="blocksDescendants" android:focusableInTouchMode="true" android:orientation="vertical"> //這里是header部分,可以隨便自定義 </LinearLayout> <LinearLayout android:id="@+id/ll_stick_list" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <android.support.design.widget.TabLayout android:id="@+id/order_manager_tabs" android:layout_width="match_parent" android:layout_height="50dp" android:background="#FFFFFF" tools:tabGravity="fill" tools:tabMode="fixed" /> <android.support.v4.view.ViewPager android:id="@+id/vp" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> </LinearLayout> </wellijohn.org.stickscrollview.ScrollViewWithStickHeader>
比如我們看到的仿餓了么的列表頁界面,我們就需要在ViewPager設(shè)置Fragment,fragment中是左右兩個(gè)列表,看下fragment的xml設(shè)置:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/ll" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <wellijohn.org.stickscrollview.ChildRecyclerView android:id="@+id/child_recyclerview" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:background="#EEEEEE" /> <wellijohn.org.stickscrollview.ChildRecyclerView android:id="@+id/child_recyclerview_right" android:layout_width="0dp" android:layout_height="wrap_content" android:background="#FFFFFF" android:layout_weight="3" /> </LinearLayout>
4.注意事項(xiàng)
ScrollViewWithStickHeader內(nèi)部目前支持放置ViewPager,ScrollView,RecyclerView,WebView ScrollView,RecyclerView,WebView需要對(duì)應(yīng)使用ChildScrollView,ChildRecyclerView,ChildWebView 我們?cè)谑褂玫臅r(shí)候,需要調(diào)用mStickScrollView.setContentView(mContentView);mLLStickList就是我們需要StickHeader+列表的部分,如果你沒有StickHeader的話,那么直接設(shè)置列表進(jìn)來也可以,總之,你想滑動(dòng)到哪個(gè)位置接下來滑動(dòng)就是單純下面的部分滑動(dòng),那你就把下面的View整體設(shè)置為mContentView。剛剛那個(gè)的ContentView是id為ll_stick_list的View。另外在這里ScrollViewWithStickHeader增加autoscroll屬性,默認(rèn)是關(guān)閉的,如果autoscroll:true的話,在我們手指放開的時(shí)候,contentView會(huì)判斷是否自動(dòng)滑動(dòng)到頂部還是隱藏不見。
5.0.0.3版本修復(fù)當(dāng)有底部有操作欄的時(shí)候,界面的滾動(dòng)出現(xiàn)錯(cuò)亂的問題。
當(dāng)我們底部有view需要固定的時(shí)候,我們需要通過mStickScrollView.setBottomView(mViewBottom);就可以了,如下所示:
6.任何控件的使用我們最好都知道它的實(shí)現(xiàn)方式,所以在這里簡單介紹下這款控件的設(shè)計(jì)思路(ChildScrollView,ChildRecyclerView,ChildWebView下面的都稱為子ScrollView)? 6.1.我們什么時(shí)候應(yīng)該讓外部的ScrollView執(zhí)行滑動(dòng)事件,什么時(shí)候讓子ScrollView執(zhí)行滑動(dòng)。在Android中我們有一個(gè)方法getParent().requestDisallowInterceptTouchEvent(true);就是讓view獲取到對(duì)應(yīng)的事件。 6.2.既然我們知道了怎么讓view的touch事件,接下來我們就要明白在什么情況下我們應(yīng)該讓父view執(zhí)行滾動(dòng)事件,什么時(shí)候讓子view執(zhí)行滾動(dòng)事件。如下,我列了表格:
父ScrollVIew
子ScrollView
在這里當(dāng)父ScrollView不在底部的時(shí)候,不會(huì)出現(xiàn)子ScrollView不在頂部的情況,所以在這里就不分析了。
6.3.分析了,在什么情況我們應(yīng)該讓子ScrollVIew還是父ScrollView捕獲滑動(dòng)事件了,我們就可以在我們的子ScrollView中編寫對(duì)應(yīng)的代碼處理了?
如下面是一段ChildScrollView的onTouchEvent方法的重寫,其他的ChildRecyclerView和ChildWebView處理也是一樣的:
@Override public boolean onTouchEvent(MotionEvent event) { if (mScrollViewWithStickHeader == null) return super.onTouchEvent(event); int action = event.getAction(); if (action == MotionEvent.ACTION_DOWN) { mLastX = event.getX(); mLastY = event.getY(); //首先判斷外層ScrollView是否滑動(dòng)到底部 if (mScrollViewWithStickHeader.isBottom()) { getParent().requestDisallowInterceptTouchEvent(true); return super.onTouchEvent(event); } else { //攔截事件 本身不處理 getParent().requestDisallowInterceptTouchEvent(false); return false; } } if (action == MotionEvent.ACTION_MOVE) { float nowY = event.getY(); if (!mScrollViewWithStickHeader.isBottom() && !isScrolledToTop && nowY - mLastY > 0) { if (Math.abs(event.getX() - mLastX) < minPageSlop) { getParent().requestDisallowInterceptTouchEvent(true); return super.onTouchEvent(event); } else { getParent().requestDisallowInterceptTouchEvent(true); return false; } } else if (mScrollViewWithStickHeader.isBottom() && !isScrolledToBottom && nowY - mLastY < 0) { if (Math.abs(event.getX() - mLastX) < minPageSlop) { getParent().requestDisallowInterceptTouchEvent(true); return super.onTouchEvent(event); } else { getParent().requestDisallowInterceptTouchEvent(true); return false; } } else if (mScrollViewWithStickHeader.isBottom() && !isScrolledToTop && nowY - mLastY > 0) { if (Math.abs(event.getX() - mLastX) < minPageSlop) { getParent().requestDisallowInterceptTouchEvent(true); return super.onTouchEvent(event); } else { getParent().requestDisallowInterceptTouchEvent(true); return false; } } else { getParent().requestDisallowInterceptTouchEvent(false); } } if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { getParent().requestDisallowInterceptTouchEvent(false); } return super.onTouchEvent(event); }
這樣的話,我們就能實(shí)現(xiàn)固定頭部的ScrollView了。
7.github地址。
以上就是本次小編整理的全部內(nèi)容,感謝你對(duì)腳本之家的支持。
- android開發(fā)仿ios的UIScrollView實(shí)例代碼
- 詳解Android ScrollView嵌套EditText出現(xiàn)的滑動(dòng)問題
- android ScrollView實(shí)現(xiàn)下拉放大頭部圖片
- Android自定義scrollView實(shí)現(xiàn)頂部圖片下拉放大
- Android給scrollView截圖超過屏幕大小形成長圖
- Android沉浸式狀態(tài)欄 + actionBar漸變 + scrollView頂部伸縮效果
- Android開發(fā)基于ScrollView實(shí)現(xiàn)的漸變導(dǎo)航欄效果示例
- Android自定義ScrollView使用自定義監(jiān)聽
- Android開發(fā)實(shí)現(xiàn)ScrollView中嵌套兩個(gè)ListView的方法
- Android開發(fā)實(shí)現(xiàn)標(biāo)題隨scrollview滑動(dòng)變色的方法詳解
- Android Webview與ScrollView的滾動(dòng)兼容及留白處理的方法
- Android 自定義 HorizontalScrollView 打造多圖片OOM 的橫向滑動(dòng)效果(實(shí)例代碼)
相關(guān)文章
Android 中對(duì)于圖片的內(nèi)存優(yōu)化方法
Android 中對(duì)于圖片的內(nèi)存優(yōu)化方法,需要的朋友可以參考一下2013-03-03Android 適配器模式應(yīng)用及設(shè)計(jì)原理
這篇文章主要介紹了Android 適配器模式應(yīng)用及設(shè)計(jì)原理的相關(guān)資料,Android開發(fā)者應(yīng)該都知道適配器會(huì)用,但是不是多清楚原理,這里幫大家分析下原理,需要的朋友可以參考下2016-10-10Android編程獲取包名,版本信息及VersionName名稱的方法
這篇文章主要介紹了Android編程獲取包名,版本信息及VersionName名稱的方法,涉及Android包及版本相關(guān)操作函數(shù)使用技巧,需要的朋友可以參考下2016-10-10Android 數(shù)據(jù)庫文件存取至儲(chǔ)存卡的方法
這篇文章主要介紹了Android 數(shù)據(jù)庫文件存取至儲(chǔ)存卡的方法的相關(guān)資料,需要的朋友可以參考下2016-03-03Android編程實(shí)現(xiàn)從字符串中查找電話號(hào)碼的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)從字符串中查找電話號(hào)碼的方法,涉及Android針對(duì)字符串的匹配與查找相關(guān)技巧,需要的朋友可以參考下2016-03-03Android利用Canvas標(biāo)點(diǎn)畫線并加入位移動(dòng)畫(1)
這篇文章主要為大家詳細(xì)介紹了Android利用Canvas標(biāo)點(diǎn)畫線并加入位移動(dòng)畫的第一篇,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-09-09