1. 程式人生 > >橫豎橫ScrollView巢狀時滑動衝突解決

橫豎橫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裡面巢

ScrollViewEditText 滑動衝突

重寫EditText 的方法dispatchTouchEvent例: @Override public boolean dispatchTouchEvent(MotionEvent ev

利用事件分發機制解決ScrollViewListView滑動衝突

記得以前面試的時候,面試官問了ScrollView巢狀ListView使用的問題。那麼ScrollView巢狀ListView使用會出現什麼效果呢? 如佈局檔案如下: <?xml version="1.0" encoding="utf-8"?>

ScrollView ViewPager導致滑動衝突解決方案

開發是遇到類似淘寶產品介紹的介面 存在srollView也ViewPager滑動衝突的問題,使用者體驗不好。 於是對srollView做了自定義控制元件,解決了該問題,處理思想:如果滑動左右滑動大於

ScrollViewRecyclerView滑動衝突相關問題

最近實際應用中遇到了滑動衝突的相關問題,在解決過程中,有些需要注意的問題,特別記錄一下。 一、應用場景 在解決具體問題之前,先介紹下實際應用場景及問題狀況。 從圖中可以看出,一個ScrollView內部巢狀三個RecyclerView,其中

scrollView recyclerView 滑動粘合解決

我用半個小時做總結    昨天下午5店發現這個問題,就在剛剛才解決。 解決辦法很簡單,而且從昨天到現在 在我眼前飄了不少於10次才被我識別出它的強大 需求描述: 首頁是一個很長的內容豐滿的頁面, 裡面有兩個卡片,此二卡片有個列表可展開,列表展開後卡片鋪滿一頁,重點是,當

scrollviewlistview滑動,上拉重新整理,衝突等問題

谷歌官方是不推薦巢狀的,但是我們現在有好多佈局這樣做會很方便,所以,沒辦法自能自己研究怎麼巢狀嘍,當然不是我研究的,我只是學習別人的,在這紀錄一下,網上其實有好多辦法,比如重寫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 ViewpagerViewpager滑動衝突

場景:tablayout繫結viewpager,viewpager巢狀fragement,其中一個fragment中嵌套了一個子viewpager,導致不能正常滑動。 解決方法: 重寫viewpager的canScroll()方法。 @Override protected bo

解決AppBarLayoutWebView滑動衝突的問題

首先,自定義WebView import android.content.Context; import android.util.AttributeSet; import android.view.GestureDetector; import android.view.GestureDete

Android ScrollviewRecycleView滑動不流暢,卡頓問題

最近在做專案時,需要仿QQ那樣的彈性動畫效果。於是就用ScrollView加RecycleView開始了。 <com.dten.assistant.ui.view.MyScrollView android:layout_width="ma

ScrollView RecyclerView 滑動到底端 在滑動的時候出現卡頓(絕對管用)

         商城專案功能基本結束了,終於可以改改BUG了 。         在做首頁的時候就出現了ScrollVeiw 巢狀RecycleView  滑動卡頓的的問題,百度了 好多,千篇一律 各種Copy 找不到好的解決辦法,什麼不要設定RecycleView 複用

解決ScrollViewRecyclerView 滑動卡頓和多個RecyclerView 顯示不全的問題

ScrollView巢狀RecyclerView ,滑動會卡頓,解決方法是: //防止滑動卡頓 GridLayoutManager gridLayoutManager=new GridLayoutManager(this, 4){

解決ConstraintLayout 與ScrollView ScrollView 內容沒有完全顯示

ConstraintLayout 佈局中有ScrollView 時,ScrollView 的寬高要設定為0dp 才可以正確的約束佈局 <ScrollView android

Android 事件分發實踐(一),解決ScrollViewListView滑動的問題

需要在ScrollView裡面巢狀一個ListView,讓ScrollView和它裡面的ListView都能滑動(ListView寬度沒有佔滿ScrollView),先貼上佈局程式碼: <com.example.xujiang.viewlearn.tou

HorizontalScrollView 中 viewpager滑動衝突解決

在 HorizontalScrollView 中巢狀 viewpager,viewpager不會隨手勢滑動,所以要複寫viewpager public class MyViewpager extends ViewPager { MyViewpager viewpage

解決ScrollViewRecyclerView滑動不流暢,ScrollviewRecyclerview的坑

谷歌不建議使用ScrollView巢狀RecyclerView,但是有時候會有這種情況。每當遇到這種情況就導致RecyclerView滑動很不流暢。解決方法如下: recyclerView.setLayoutManager(new GridLayoutManager(mCo