橫豎橫ScrollView巢狀時滑動衝突解決
以前其實解決過類似的問題,當時是ViewPager巢狀的衝突問題,沒有做記錄,所以這次又費力研究半天,想想還是把程式碼和思路記錄下來方便以後參考。
首先是最外層的HorizontalScrollView(後面簡稱HS)中的控制,當內部有一個豎向的ScrollView(後面簡稱VS)的時候,如果HS對上下滑動的事件做了吸收或者部分處理,就會導致HS不能滑動或者滑動卡頓的情況,事實也的確是如此,所以我們需要在HS中做如下處理:
private GestureDetector mGestureDetector;
private void init()
{
setHorizontalScrollBarEnabled(false );
mGestureDetector = new GestureDetector(getContext(), new HScrollDetector());
}
// Return false if we're scrolling in the y direction
class HScrollDetector extends SimpleOnGestureListener
{
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY)
{
if (Math.abs(distanceX) > Math.abs(distanceY))
{
return true;
}
return false;
}
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev)
{
switch (ev.getAction())
{
case MotionEvent.ACTION_DOWN:
downX = (int ) ev.getX();
break;
}
return super.onInterceptTouchEvent(ev) && mGestureDetector.onTouchEvent(ev);
}
init方法會在我們覆寫的HS中被呼叫,在這個地方我們new了一個GestureDetector,這裡我們自定義了一個HScrollDetector,回撥方法中捕捉了橫向的滑動事件。然後看HS中的onInterceptTouchEvent方法,當為橫向的滑動事件的時候,mGestureDetector.onTouchEvent(ev)返回為true,所有的邏輯和HS原有的邏輯一樣,事件被攔截然後有HS自己處理;但是當滑動為縱向的時候,mGestureDetector.onTouchEvent(ev)返回為false,也就是不攔截當前事件,所有的事件就會傳到下面的VS中,由VS消耗掉,不會再發生卡頓的情況。
這時候需求要求我們VS裡又要巢狀一個HorizontalScrollView(下面簡稱IHS),這時候我們會發現上面的HS已經把橫向的滑動事件吸收掉了,IHS基本拿不到事件,所以又會導致不能滑動的問題。怎麼辦呢,我們想到了api裡的requestDisallowInterceptTouchEvent方法,可以理解為這個方法的優先順序,高於父View自己的onInterceptTouchEvent,上程式碼:
public class InnerHScrollView extends HorizontalScrollView
{
public InnerHScrollView(Context p_context, AttributeSet p_attrs)
{
super(p_context, p_attrs);
}
public InnerHScrollView(Context context)
{
super(context);
}
private boolean mCanScroll = true;
private float mDownX;
@Override
public boolean onTouchEvent(MotionEvent ev)
{
ViewParent viewParent =
getParent().getParent().getParent().getParent().getParent();
if (ev.getAction() == MotionEvent.ACTION_DOWN)
{
mDownX = ev.getX();
}
if (ev.getAction() == MotionEvent.ACTION_MOVE)
{
int scrollx = getScrollX();
if ((scrollx == 0 && mDownX - ev.getX() <= -10) ||
(getChildAt(0).getMeasuredWidth() <= (scrollx + Constants.HOME_VIEW_WIDTH) && mDownX - ev.getX() >= 10))
{
mCanScroll = false;
}
}
if (ev.getAction() == MotionEvent.ACTION_UP
|| ev.getAction() == MotionEvent.ACTION_CANCEL)
{
mCanScroll = true;
}
if (this.mCanScroll)
{
// 此句程式碼是為了通知他的父ViewPager現在進行的是本控制元件的操作,不要對我的操作進行干擾
viewParent.requestDisallowInterceptTouchEvent(true);
return super.onTouchEvent(ev);
}
else
{
viewParent.requestDisallowInterceptTouchEvent(false);
return false;
}
}
}
viewParent那裡寫死了,要動態的話讓外面把parent的層級通過數字傳進來就可以了,這裡就不改了,原理是一樣的。當確認是正常的X軸滑動的時候,mCanScroll為true,viewParent.requestDisallowInterceptTouchEvent(true);該方法會讓parent把時間傳遞給IHS自己處理,不做任何攔截。否則,交由上層HS自己處理。
原理不復雜,前提還是各位要充分理解安卓的touchEvent的分發機制。
相關推薦
橫豎橫ScrollView巢狀時滑動衝突解決
以前其實解決過類似的問題,當時是ViewPager巢狀的衝突問題,沒有做記錄,所以這次又費力研究半天,想想還是把程式碼和思路記錄下來方便以後參考。 首先是最外層的HorizontalScrollView(後面簡稱HS)中的控制,當內部有一個豎向的Scrol
android ListView/GridView與ScrollView巢狀的滑動衝突解決
首先說一下思路,主要就是去掉子ListView/GridView的內容全部顯示出來,使其不需要滑動。然後用ScrollView將其包裹在其中,接管滑動事件,達到整個佈局的滑動效果。 實際做法需要將ListView/GridView 與 ScrollView 覆
ScrollView 巢狀ViewPager滑動衝突解決
這篇部落格主要講解一下幾個問題粗略地介紹一下View的事件分發機制解決事件滑動衝突的思路及方法ScrollView 裡面巢狀ViewPager導致的滑動衝突ViewPager裡面巢狀ViewPager 導致的滑動衝突輪播圖的幾種實現方式先看一下效果圖ScrollView裡面巢
ScrollView巢狀EditText 滑動衝突
重寫EditText 的方法dispatchTouchEvent例: @Override public boolean dispatchTouchEvent(MotionEvent ev
利用事件分發機制解決ScrollView巢狀ListView滑動衝突
記得以前面試的時候,面試官問了ScrollView巢狀ListView使用的問題。那麼ScrollView巢狀ListView使用會出現什麼效果呢? 如佈局檔案如下: <?xml version="1.0" encoding="utf-8"?>
ScrollView ViewPager巢狀導致滑動衝突解決方案
開發是遇到類似淘寶產品介紹的介面 存在srollView也ViewPager滑動衝突的問題,使用者體驗不好。 於是對srollView做了自定義控制元件,解決了該問題,處理思想:如果滑動左右滑動大於
ScrollView巢狀RecyclerView滑動衝突相關問題
最近實際應用中遇到了滑動衝突的相關問題,在解決過程中,有些需要注意的問題,特別記錄一下。 一、應用場景 在解決具體問題之前,先介紹下實際應用場景及問題狀況。 從圖中可以看出,一個ScrollView內部巢狀三個RecyclerView,其中
scrollView 巢狀recyclerView 滑動粘合解決
我用半個小時做總結 昨天下午5店發現這個問題,就在剛剛才解決。 解決辦法很簡單,而且從昨天到現在 在我眼前飄了不少於10次才被我識別出它的強大 需求描述: 首頁是一個很長的內容豐滿的頁面, 裡面有兩個卡片,此二卡片有個列表可展開,列表展開後卡片鋪滿一頁,重點是,當
scrollview巢狀listview滑動,上拉重新整理,衝突等問題
谷歌官方是不推薦巢狀的,但是我們現在有好多佈局這樣做會很方便,所以,沒辦法自能自己研究怎麼巢狀嘍,當然不是我研究的,我只是學習別人的,在這紀錄一下,網上其實有好多辦法,比如重寫listview或重寫scrollview,但是感覺太麻煩啦,在網上找了半天找到一個相
豎向ScrollView巢狀橫向滑動佈局衝突
當外層豎向滑動ScrollView裡面巢狀橫向的滑動佈局時,會發先內層橫向滑動很卡頓 原因:左右滑動操作被外層的scrollView處理掉了 解決:只要讓scrollview對左右滑動事件不監聽,讓其子控制元件處理左右滑動事件 即可,需要重寫scrollview的onInt
NavigationView headerLayout中巢狀RecyclerView滑動衝突問題
<?xml version="1.0" encoding="utf-8"?> <com.vechain.vecar.ui.view.MyDrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
Android Viewpager巢狀Viewpager滑動衝突。
場景:tablayout繫結viewpager,viewpager巢狀fragement,其中一個fragment中嵌套了一個子viewpager,導致不能正常滑動。 解決方法: 重寫viewpager的canScroll()方法。 @Override protected bo
解決AppBarLayout巢狀WebView滑動衝突的問題
首先,自定義WebView import android.content.Context; import android.util.AttributeSet; import android.view.GestureDetector; import android.view.GestureDete
Android Scrollview巢狀RecycleView滑動不流暢,卡頓問題
最近在做專案時,需要仿QQ那樣的彈性動畫效果。於是就用ScrollView加RecycleView開始了。 <com.dten.assistant.ui.view.MyScrollView android:layout_width="ma
ScrollView 巢狀 RecyclerView 滑動到底端 在滑動的時候出現卡頓(絕對管用)
商城專案功能基本結束了,終於可以改改BUG了 。 在做首頁的時候就出現了ScrollVeiw 巢狀RecycleView 滑動卡頓的的問題,百度了 好多,千篇一律 各種Copy 找不到好的解決辦法,什麼不要設定RecycleView 複用
解決ScrollView巢狀RecyclerView 滑動卡頓和巢狀多個RecyclerView 顯示不全的問題
ScrollView巢狀RecyclerView ,滑動會卡頓,解決方法是: //防止滑動卡頓 GridLayoutManager gridLayoutManager=new GridLayoutManager(this, 4){
解決ConstraintLayout 與ScrollView 巢狀時ScrollView 內容沒有完全顯示
ConstraintLayout 佈局中有ScrollView 時,ScrollView 的寬高要設定為0dp 才可以正確的約束佈局 <ScrollView android
Android 事件分發實踐(一),解決ScrollView巢狀ListView滑動的問題
需要在ScrollView裡面巢狀一個ListView,讓ScrollView和它裡面的ListView都能滑動(ListView寬度沒有佔滿ScrollView),先貼上佈局程式碼: <com.example.xujiang.viewlearn.tou
HorizontalScrollView 中巢狀 viewpager滑動衝突的解決
在 HorizontalScrollView 中巢狀 viewpager,viewpager不會隨手勢滑動,所以要複寫viewpager public class MyViewpager extends ViewPager { MyViewpager viewpage
解決ScrollView巢狀RecyclerView滑動不流暢,Scrollview巢狀Recyclerview的坑
谷歌不建議使用ScrollView巢狀RecyclerView,但是有時候會有這種情況。每當遇到這種情況就導致RecyclerView滑動很不流暢。解決方法如下: recyclerView.setLayoutManager(new GridLayoutManager(mCo