1. 程式人生 > >Android 事件分發實踐(一),解決ScrollView巢狀ListView滑動的問題

Android 事件分發實踐(一),解決ScrollView巢狀ListView滑動的問題

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

<com.example.xujiang.viewlearn.touchConfict.MyScrollView xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:tools="http://schemas.android.com/tools"
            android:id="@+id/scrollView"
android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.xujiang.viewlearn.touchConfict.TouchConflictActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"
android:orientation="vertical"> <ImageView android:src="@drawable/chongwu0703" android:layout_width="match_parent" android:scaleType="fitXY" android:layout_height="300dp"/> <ListView android:id="@+id/listView"
android:layout_width="match_parent" android:layout_height="300dp" android:layout_marginRight="80dp"/> <ImageView android:src="@drawable/jianbihua0703" android:layout_width="match_parent" android:scaleType="fitXY" android:layout_height="300dp"/> </LinearLayout> </com.example.xujiang.viewlearn.touchConfict.MyScrollView>

這裡自定義了一個ScrollView,只是為了檢視Log,MyScrollView的程式碼:

public class MyScrollView extends ScrollView{
    public static  String TAG="MyScrollView";
    public MyScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        boolean result=super.onInterceptTouchEvent(ev);
        Log.i(TAG,"onInterceptTouchEvent result== "+result);
        return result;
    }
}

最後在Activity裡面幫ListView繫結資料後,如果不做處理,ListView是不能滑動的,至於原因,從Log可以看出,ScrollView的onInterceptTouchEvent返回的是true,這樣,就會攔截事件,ListView接收不到事件,當然也就不能滑動。
這裡寫圖片描述
尋找解決方法,要從ViewGroup事件的過程中尋找,ViewGroup的dispatchTouchEvent有這麼一段程式碼:

 final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
                if (!disallowIntercept) {
                    intercepted = onInterceptTouchEvent(ev);
                    ev.setAction(action); // restore action in case it was changed
                } else {
                    intercepted = false;
                }

ScrollView攔截事件是因為執行了intercepted = onInterceptTouchEvent(ev)這句程式碼,導致intercepted 的值為true,在下面事件分發時有判斷
if (!canceled && !intercepted),這裡就不會走下去,事件分發結束,ListView不會再收到事件。我們可以改變disallowIntercept 的值,不讓ScrollView執行onInterceptTouchEvent的方法,ViewGroup提供了一個讓子View不讓父View攔截事件的方法:

public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {

        if (disallowIntercept == ((mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0)) {
            // We're already in this state, assume our ancestors are too
            return;
        }

        if (disallowIntercept) {
            mGroupFlags |= FLAG_DISALLOW_INTERCEPT;
        } else {
            mGroupFlags &= ~FLAG_DISALLOW_INTERCEPT;
        }

        // Pass it up to our parent
        if (mParent != null) {
            mParent.requestDisallowInterceptTouchEvent(disallowIntercept);
        }
    }

為ListView和ScrollView註冊onTouch事件,在裡面呼叫requestDisallowInterceptTouchEvent方法:

  mListView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                mListView.getParent().requestDisallowInterceptTouchEvent(true);
                return false;
            }
        });
        mScrollView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                mListView.getParent().requestDisallowInterceptTouchEvent(false);
                return false;
            }
        });

這樣處理後,ListView就可以滑動了:
這裡寫圖片描述

相關推薦

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

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

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

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

解決ScrollViewListView滑動只顯示ListView滑到頂部問題

問題:在ScrollView中巢狀ListView,出現的效果是ListView只顯示一行,無論高度設定的是match_parent還是wrap_content。五種任你選。 1、設定ListView的高度為固定值 這樣ListView可以滑動,整體Sc

android進階-----解決scrollviewlistview的問題

在android開發中,經常會碰到在ScrollView中巢狀ListView的介面的開發,在ScrollView中巢狀ListView會帶來幾個問題,經過反覆的實踐,總結出完美解決的辦法如下: 1.繼承ListView 複寫其中的方法 @Override public void onMeasu

解決ScrollViewRecyclerView滑動不流暢ScrollviewRecyclerview的坑

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

解決ScrollViewListView或GridView置頂顯示問題

今天無意間發現一個小小的問題,當我們使用ScrollView裡面巢狀ListView或GridView的時候頁面顯示會停留在ListView的item當前,而不是置頂顯示整個頁面,不要慌,解決辦法來了。 1.在java程式碼中ListView或GridView初始化後面新增以下程式碼: sc

解決ScrollViewListView顯示不完全和滑動衝突的問題

</pre>在開發中我們往往會遇到這樣奇葩的需求,讓一個ScrollView巢狀ListView,那麼我們就會遇到這樣一個問題,就是listView 顯示不完全和滾動衝突的問題。下面就來解決一下這個問題</p><p></p>&

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

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

四種方案解決ScrollViewListView問題

以下文章轉自@安卓泡麵 在工作中,曾多次碰到ScrollView巢狀ListView的問題,網上的解決方法有很多種,但是雜而不全。我試過很多種方法,它們各有利弊。 在這裡我將會從使用ScrollView巢狀ListView結構的原因、這個結構碰到的問題、幾種解決方案和

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

谷歌官方是不推薦巢狀的,但是我們現在有好多佈局這樣做會很方便,所以,沒辦法自能自己研究怎麼巢狀嘍,當然不是我研究的,我只是學習別人的,在這紀錄一下,網上其實有好多辦法,比如重寫listview或重寫scrollview,但是感覺太麻煩啦,在網上找了半天找到一個相

Android事件分發機制 系統預設機制

1.為什麼要了解Android事件機制? 背景:我在做Android專案的時候遇到一個Activity->Fragment->ScrollView->Button這樣的巢狀關係,當一切都準備就緒,程式啟動後點擊Button的時候系統異常崩潰了,騰訊Bugl

Android事件分發機制事件是如何到達activity的?

> 事件分發,真的一定從Activity開始嗎? ## 前言 很高興遇見你~ 事件分發,android中一個老生常談的話題了。基本的流程我們也都知道是從Activity開始分發,但有一個關鍵問題是:**事件是如何到達Activity的** ? 你以為我接下來要開始講原始碼、系統底層了?不不不,本文不講

解決ScrollView嵌套ListView僅僅顯示一行的問題

eas divide lis params etl name pos rac getcount /** * 解決ScrollView嵌套ListView僅僅顯示一行的問題 * * @param listView */ private void se

ScrollViewListView顯示不全和位置不是頂部的解決辦法

(1)首先寫一個listview的頁面,用ScrollView進行巢狀,注意ScrollView裡面只能有一個佈局屬性,多個可以用Linearout進行包含 <?xml version="1.0" encoding="utf-8"?> <RelativeL

Android ScrollviewRecycleView滑動不流暢卡頓問題

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

Android那些事》——ScrollViewListView只顯示一行的問題的解決方法

在實際開發過程中,經常會碰到ScrollView中巢狀ListView的情景 可是如果直接使用ScrollView巢狀ListView的話,我們會發現,ListView只能顯示一行 對於這個問題網上有很多解決方案, 1.手動設定ListView的高度,但ListView中的資料

解決ScrollViewviewPager中listView滑動事件衝突問題(水平方向)

我們在開發中經常會碰到view滑動衝突的情況。滑動衝突的解決辦法就兩種:1.外部攔截法:是指在點選事件先經過父容器的攔截處理,如果父容器需要處理此事件就進行攔截,如果不需要此事件就不攔截,這樣就可以解決滑動衝突的問題,外部攔截法需要重寫父容器的onInterceptTouch

ScrollViewRecyclerView、ScrollViewListviewScrollView各種佈局預設不在頂部和回到頂部的解決方法;

如果:ScrollView.scrollTo(0,0);ScrollView.fullScroll(View.FOCUS_UP) ;ScrollView.smoothScrollTo(0, 0);這三種方法都解決不了你的問題,那麼請往下看;佈局有點複雜:最外層是SwipeRe

ScrollViewListView或GridView等使得其高度自適應解決方案

這類的文章有很多,寫此文的目的是為了備忘吧。ScrollView裡面巢狀ListView或GridView等,兩個View都有滾動的效果,在巢狀使用時起了衝突,一般不建議兩者套用。解決的方案有很多但是

解決ScrollviewRecyclerviewGridview等出現內容顯示不全等為

在自定義View和ViewGroup的時候,我們經常會遇到int型的MeasureSpec來表示一個元件的大小,這個變數裡面不僅有元件的尺寸大小,還有大小的模式。 這個大小的模式,有點難以理解。在系統中元件的大小模式有三種: 1.精確模式(MeasureSpec.EXAC