Android ScrollView粘性頭部代碼分享
前言,一天在點(diǎn)外賣(mài)的時(shí)候,注意到餓了么列表頁(yè)的滑動(dòng)效果不錯(cuò),但是覺(jué)得其中的手勢(shì)滑動(dòng)還是挺復(fù)雜的,正好又碰到了在熟悉Touch事件的理解當(dāng)中,所以就抽空對(duì)著餓了么的列表頁(yè)面嘗試寫(xiě)寫(xiě)這個(gè)效果
1.先貼一個(gè)實(shí)現(xiàn)的效果圖
邏輯是當(dāng)外部的ScrollView沒(méi)有滑到底部的時(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)。
如下是仿餓了么的列表頁(yè)的效果圖:

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.界面的布局說(shuō)明
<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>
比如我們看到的仿餓了么的列表頁(yè)界面,我們就需要在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+列表的部分,如果你沒(méi)有StickHeader的話,那么直接設(shè)置列表進(jìn)來(lái)也可以,總之,你想滑動(dòng)到哪個(gè)位置接下來(lái)滑動(dòng)就是單純下面的部分滑動(dòng),那你就把下面的View整體設(shè)置為mContentView。剛剛那個(gè)的ContentView是id為ll_stick_list的View。另外在這里ScrollViewWithStickHeader增加autoscroll屬性,默認(rèn)是關(guān)閉的,如果autoscroll:true的話,在我們手指放開(kāi)的時(shí)候,contentView會(huì)判斷是否自動(dòng)滑動(dòng)到頂部還是隱藏不見(jiàn)。
5.0.0.3版本修復(fù)當(dāng)有底部有操作欄的時(shí)候,界面的滾動(dòng)出現(xiàn)錯(cuò)亂的問(wèn)題。
當(dāng)我們底部有view需要固定的時(shí)候,我們需要通過(guò)mStickScrollView.setBottomView(mViewBottom);就可以了,如下所示:

6.任何控件的使用我們最好都知道它的實(shí)現(xiàn)方式,所以在這里簡(jiǎ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事件,接下來(lái)我們就要明白在什么情況下我們應(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中編寫(xiě)對(duì)應(yīng)的代碼處理了?
如下面是一段ChildScrollView的onTouchEvent方法的重寫(xiě),其他的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地址。
以上就是本次小編整理的全部?jī)?nèi)容,感謝你對(duì)腳本之家的支持。
- android開(kāi)發(fā)仿ios的UIScrollView實(shí)例代碼
- 詳解Android ScrollView嵌套EditText出現(xiàn)的滑動(dòng)問(wèn)題
- android ScrollView實(shí)現(xiàn)下拉放大頭部圖片
- Android自定義scrollView實(shí)現(xiàn)頂部圖片下拉放大
- Android給scrollView截圖超過(guò)屏幕大小形成長(zhǎng)圖
- Android沉浸式狀態(tài)欄 + actionBar漸變 + scrollView頂部伸縮效果
- Android開(kāi)發(fā)基于ScrollView實(shí)現(xiàn)的漸變導(dǎo)航欄效果示例
- Android自定義ScrollView使用自定義監(jiān)聽(tīng)
- Android開(kāi)發(fā)實(shí)現(xiàn)ScrollView中嵌套兩個(gè)ListView的方法
- Android開(kāi)發(fā)實(shí)現(xiàn)標(biāo)題隨scrollview滑動(dòng)變色的方法詳解
- Android Webview與ScrollView的滾動(dòng)兼容及留白處理的方法
- Android 自定義 HorizontalScrollView 打造多圖片OOM 的橫向滑動(dòng)效果(實(shí)例代碼)
相關(guān)文章
Android AsyncTask完全解析 帶你從源碼的角度徹底理解
這篇文章主要是針對(duì)Android AsyncTask進(jìn)行完全解析,帶你從源碼的角度徹底理解,感興趣的小伙伴們可以參考一下2016-04-04
源碼解析Android Jetpack組件之ViewModel的使用
Jetpack 是一個(gè)豐富的組件庫(kù),它的組件庫(kù)按類別分為 4 類,分別是架構(gòu)(Architecture)、界面(UI)、 行為(behavior)和基礎(chǔ)(foundation)。本文將從源碼和大家講講Jetpack組件中ViewModel的使用2023-04-04
基于Android XML解析與保存的實(shí)現(xiàn)
本篇文章小編為大家介紹,基于Android XML解析與保存的實(shí)現(xiàn)。需要的朋友參考下2013-04-04
Android 通過(guò)webservice上傳多張圖片到指定服務(wù)器詳解
這篇文章主要介紹了Android 通過(guò)webservice上傳多張圖片到指定服務(wù)器詳解的相關(guān)資料,需要的朋友可以參考下2017-02-02
Flutter檢查連接網(wǎng)絡(luò)connectivity_plus實(shí)現(xiàn)步驟
這篇文章主要為大家介紹了Flutter檢查連接網(wǎng)絡(luò)connectivity_plus實(shí)現(xiàn)步驟,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06
Android實(shí)現(xiàn)Back功能代碼片段總結(jié)
今天把在公司實(shí)現(xiàn)某功能所用到的Back鍵功能模塊代碼片段做一個(gè)整理。方便以后直接拿出來(lái)使用2014-09-09

