兒童做的小游戲下載網(wǎng)站市場(chǎng)seo是什么意思
一、NestedScrollView
1. 什么是 NestedScrollView
NestedScrollView
是 Android 中一個(gè)用于處理垂直方向滾動(dòng)的布局組件,它繼承自 FrameLayout
,同時(shí)支持嵌套滑動(dòng)(Nested Scrolling)機(jī)制。相比于傳統(tǒng)的 ScrollView
,NestedScrollView
專為解決嵌套滾動(dòng)沖突問題設(shè)計(jì),能夠與其他支持嵌套滑動(dòng)的子視圖(如 RecyclerView
、ViewPager
等)協(xié)同工作。
2. 定義
NestedScrollView
是 Android Jetpack 中的組件,用于容納能夠垂直滾動(dòng)的視圖。當(dāng)頁面布局的內(nèi)容超過屏幕高度時(shí),可以通過滾動(dòng)展示全部?jī)?nèi)容。同時(shí),NestedScrollView
在滾動(dòng)的過程中與子視圖可以進(jìn)行事件協(xié)作。
3. 與ScrollView的區(qū)別
NestedScrollView
和 ScrollView
的主要區(qū)別在于它具備“嵌套滑動(dòng)”(Nested Scrolling)功能。在 Android 中,嵌套滑動(dòng)是一種滾動(dòng)沖突處理機(jī)制,允許父視圖和子視圖協(xié)同工作,共同處理滑動(dòng)事件。這種機(jī)制非常有用,特別是當(dāng)你在一個(gè)滾動(dòng)視圖中嵌套另一個(gè)滾動(dòng)視圖時(shí),它能夠有效避免滑動(dòng)沖突。
ScrollView
:不支持嵌套滑動(dòng),通常會(huì)出現(xiàn)父子滑動(dòng)視圖的事件沖突,導(dǎo)致滑動(dòng)體驗(yàn)不佳。NestedScrollView
:內(nèi)置嵌套滑動(dòng)機(jī)制,能夠更好地處理父子視圖的滾動(dòng)事件,使頁面更加流暢。
4. 常見使用場(chǎng)景
- 表單頁面:在一個(gè)頁面中,可能會(huì)有許多輸入框、按鈕等,當(dāng)這些內(nèi)容超過屏幕時(shí),使用
NestedScrollView
可以讓整個(gè)頁面可滾動(dòng)。 - 嵌套滾動(dòng)視圖:當(dāng)你在一個(gè)滾動(dòng)視圖(如
RecyclerView
)中嵌套了另一個(gè)滾動(dòng)視圖(如ViewPager
或HorizontalScrollView
)時(shí),NestedScrollView
能避免滑動(dòng)事件沖突。 - 與
CoordinatorLayout
結(jié)合:NestedScrollView
可以與CoordinatorLayout
搭配使用,處理如CollapsingToolbarLayout
、AppBarLayout
等復(fù)雜的滾動(dòng)聯(lián)動(dòng)效果。
5. 簡(jiǎn)單使用方法
下面是一個(gè)CoordinatorLayout中使用NestedScrollView并嵌套R(shí)ecyclerView的簡(jiǎn)單用法:
<androidx.coordinatorlayout.widget.CoordinatorLayout android:layout_width="match_parent"android:layout_height="match_parent"xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"><androidx.core.widget.NestedScrollViewandroid:layout_width="match_parent"android:layout_height="match_parent"app:layout_behavior="@string/appbar_scrolling_view_behavior"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/recyclerView"android:layout_width="match_parent"android:layout_height="wrap_content"android:nestedScrollingEnabled="false" /></LinearLayout></androidx.core.widget.NestedScrollView></androidx.coordinatorlayout.widget.CoordinatorLayout>
CoordinatorLayout
是整個(gè)布局的容器,用于協(xié)調(diào)多個(gè)滾動(dòng)視圖的交互,盡管當(dāng)前只涉及了NestedScrollView
。NestedScrollView
管理頁面的垂直滾動(dòng),并能夠與其他支持嵌套滾動(dòng)的視圖配合使用。它容納了RecyclerView
并負(fù)責(zé)控制滾動(dòng)。RecyclerView
展示的是具體的滾動(dòng)內(nèi)容,使用android:nestedScrollingEnabled="false"
讓NestedScrollView
完全負(fù)責(zé)滾動(dòng)處理,避免滾動(dòng)沖突。
二、滾動(dòng)沖突和滑動(dòng)沖突
1. 區(qū)別
滾動(dòng)沖突(Scroll Conflict):
? 滾動(dòng)沖突發(fā)生在嵌套滾動(dòng)視圖中。例如,一個(gè) ScrollView
內(nèi)部嵌套了一個(gè) RecyclerView
,或者一個(gè) ViewPager
內(nèi)嵌了一個(gè) ScrollView
。當(dāng)用戶在一個(gè)滾動(dòng)視圖上滑動(dòng)時(shí),系統(tǒng)需要決定哪個(gè)視圖應(yīng)該接收滾動(dòng)事件,從而可能導(dǎo)致滾動(dòng)沖突。
滑動(dòng)沖突(Touch Conflict):
? 滑動(dòng)沖突通常發(fā)生在多個(gè)視圖或組件嘗試處理相同的觸摸事件時(shí)。例如,一個(gè) ViewPager
和一個(gè) RecyclerView
都可以響應(yīng)滑動(dòng)手勢(shì),這會(huì)導(dǎo)致滑動(dòng)沖突?;瑒?dòng)沖突通常涉及觸摸事件的處理,而不是滾動(dòng)事件的嵌套。
2. 處理方式
處理滾動(dòng)沖突
滾動(dòng)沖突通常發(fā)生在嵌套的滾動(dòng)視圖中,例如在一個(gè) ScrollView
中嵌套了一個(gè) RecyclerView
。以下是幾種常見的解決方法:
- 禁用子視圖的嵌套滾動(dòng)
-
描述:禁用子視圖的嵌套滾動(dòng)功能,讓父視圖完全控制滾動(dòng)行為。
-
示例:
<androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/recyclerView"android:layout_width="match_parent"android:layout_height="wrap_content"android:nestedScrollingEnabled="false" />
- 自定義
Behavior
-
描述:創(chuàng)建自定義的
Behavior
類,控制滾動(dòng)行為和滾動(dòng)事件的傳遞。 -
示例:
package com.example.nestedscrollviewtest;import android.content.Context; import android.util.AttributeSet; import android.view.View;import androidx.annotation.NonNull; import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.core.view.ViewCompat; import androidx.core.widget.NestedScrollView;public class CustomBehavior extends CoordinatorLayout.Behavior<NestedScrollView> {public CustomBehavior() {super();}public CustomBehavior(Context context, AttributeSet attrs) {super(context, attrs);}@Overridepublic boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull NestedScrollView child, @NonNull View directTargetChild, @NonNull View target, int axes, int type) {// 控制是否響應(yīng)嵌套滑動(dòng)return axes == ViewCompat.SCROLL_AXIS_VERTICAL;}@Overridepublic void onNestedPreScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull NestedScrollView child, @NonNull View target, int dx, int dy, @NonNull int[] consumed, int type) {// 處理嵌套滑動(dòng)前的事件} }
<androidx.coordinatorlayout.widget.CoordinatorLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"><androidx.core.widget.NestedScrollViewandroid:layout_width="match_parent"android:layout_height="match_parent"app:layout_behavior="com.example.nestedscrollviewtest.CustomBehavior"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/recyclerView"android:layout_width="match_parent"android:layout_height="wrap_content"android:nestedScrollingEnabled="false" /></LinearLayout></androidx.core.widget.NestedScrollView></androidx.coordinatorlayout.widget.CoordinatorLayout>
處理滑動(dòng)沖突
1. 外部攔截(onInterceptTouchEvent
)
- 作用:用于攔截觸摸事件,決定是否由當(dāng)前視圖處理該事件。
- 如何工作:在父視圖的
onInterceptTouchEvent
方法中,父視圖會(huì)決定是否攔截事件并交給自己處理。如果返回true
,父視圖將處理事件;如果返回false
,事件將傳遞給子視圖處理。
NestedScrollView
中的外部攔截
NestedScrollView
作為一個(gè)容器視圖,通常會(huì)處理其內(nèi)部的滾動(dòng)事件。為了確保它能夠正確處理滾動(dòng)事件,可以重寫 NestedScrollView
的 onInterceptTouchEvent
方法來攔截觸摸事件,并決定是否讓其處理:
package com.example.nestedscrollviewtest;import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;import androidx.core.widget.NestedScrollView;public class CustomNestedScrollView extends NestedScrollView {public CustomNestedScrollView(Context context) {super(context);}public CustomNestedScrollView(Context context, AttributeSet attrs) {super(context, attrs);}public CustomNestedScrollView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {// 根據(jù)需要判斷是否攔截事件// 例如,可以根據(jù)事件的類型或滾動(dòng)方向來決定是否攔截return super.onInterceptTouchEvent(ev);}
}
2. 內(nèi)部攔截(onTouchEvent
)
- 作用:用于處理視圖接收到的觸摸事件。
- 如何工作:在子視圖的
onTouchEvent
方法中,子視圖會(huì)處理傳遞給它的事件。如果子視圖無法處理事件,它可以將事件傳遞給父視圖或其他視圖。
RecyclerView
的 onTouchEvent
方法負(fù)責(zé)處理其自己的觸摸事件。通常,你不需要對(duì) RecyclerView
的 onTouchEvent
進(jìn)行特別處理,但要確保它正常工作。
public class CustomRecyclerView extends RecyclerView {public CustomRecyclerView(Context context) {super(context);}public CustomRecyclerView(Context context, AttributeSet attrs) {super(context, attrs);}public CustomRecyclerView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}@Overridepublic boolean onTouchEvent(MotionEvent e) {// 默認(rèn)情況下,RecyclerView 處理自己的觸摸事件return super.onTouchEvent(e);}
}
3.攔截機(jī)制
滾動(dòng)沖突和攔截機(jī)制
當(dāng)你處理滾動(dòng)沖突時(shí)(例如ScrollView
中嵌套 RecyclerView
),內(nèi)部攔截和外部攔截的目的都是在父視圖和子視圖之間決定誰來處理滾動(dòng)事件。在這種情況下,使用攔截機(jī)制是為了解決多個(gè)滾動(dòng)視圖對(duì)事件的爭(zhēng)奪。
- 內(nèi)部攔截法:子視圖決定是否處理事件。
- 適用于子視圖滾動(dòng)邏輯復(fù)雜的情況,通常用于滾動(dòng)沖突。
- 外部攔截法:父視圖決定是否處理事件。
- 適用于父視圖需要優(yōu)先處理事件的情況,常用于解決滾動(dòng)沖突。
滑動(dòng)沖突和攔截機(jī)制
滑動(dòng)沖突是由多個(gè)視圖組件對(duì)觸摸事件的競(jìng)爭(zhēng)引發(fā)的,而不是滾動(dòng)事件的嵌套。在滑動(dòng)沖突的場(chǎng)景下,攔截機(jī)制也同樣適用。比如在ViewPager
和RecyclerView
這類視圖中,事件分發(fā)的沖突會(huì)涉及滑動(dòng)方向和手勢(shì)的識(shí)別。
- 內(nèi)部攔截法:子視圖根據(jù)觸摸事件的方向和類型,決定是否繼續(xù)處理觸摸事件或傳遞給父視圖。
- 適用于需要子視圖有更多自定義處理的滑動(dòng)場(chǎng)景。
- 外部攔截法:父視圖判斷當(dāng)前手勢(shì)是否屬于自己的處理范圍,例如 ViewPager 判斷是水平滑動(dòng),則攔截事件。
- 常用于父視圖需要根據(jù)手勢(shì)類型做判斷的滑動(dòng)沖突場(chǎng)景。
以上就是本篇博客的所有內(nèi)容
已經(jīng)到底啦!!