1. 程式人生 > >解決view 滑動事件衝突(實戰篇-內部攔截法)

解決view 滑動事件衝突(實戰篇-內部攔截法)

出處 Android開發藝術探索

說明:本文用的方法是(內部攔截法)

首先說下一個普遍的需求:
這個需求很普遍;像今日頭條,網易新聞什麼的都是這樣
1:底部有四個按鈕點選可以切換;左右滑可以切換(不用想用viewpager)
2:點選某個底部按鈕裡面又是需要三個按鈕點選可以切換,左右滑可以切換(不用想也是viewpager)
3:然後在第二個viewpager裡的某個fragment裡的頁面佈局是:頂部固定某些內容(比如3個button)然後下面是個列表;這個頁面我的做法是:NestedScrollView+RecyclerView;為什麼用它們兩個呢,因為google為我們解決了以前最頭疼的一件事:scrollview巢狀listview,listview不能顯示全的問題,還是複用問題;用NestedScrollView+RecyclerView首先不用考慮RecyclerView不能顯示全的問題;還有RecyclerView功能比Listview功能更強大不多說; 然而問題來了,在這個頁面會出現非常嚴重的頁面滑動卡頓的問題,雖然google幫我們幹了許多事,但是有些還是需要自己去實現

總結一下總的佈局就是:
viewpager+viewpager(NestedScrollView+RecyclerView)

直接看那個卡頓佈局的xml程式碼:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation
="vertical">
<android.support.v4.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="match_parent" android:descendantFocusability="beforeDescendants"> <org.jokar.eventconflict.widget.MyLinearLayout android:layout_width
="match_parent" android:layout_height="match_parent" android:orientation="vertical">
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <Button android:id="@+id/button1" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="button1" /> <Button android:id="@+id/button2" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="button2" /> <Button android:id="@+id/button3" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="button3" /> </LinearLayout> <org.jokar.eventconflict.widget.MyRecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" /> </org.jokar.eventconflict.widget.MyLinearLayout> </android.support.v4.widget.NestedScrollView> </LinearLayout>

如上程式碼並沒有特別之處;只有三處不同:
1.NestedScrollView 加上descendantFocusability(去掉好像也可以,因為寫的demo快速滑動時候不卡但是慢速滑動的時候感覺有時候會卡一下;這是個遺留的問題暫時沒有找到解決方法)

 <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
      android:descendantFocusability="beforeDescendants">

2.就是重寫的兩個view

public class MyLinearLayout extends LinearLayout {
    public MyLinearLayout(Context context) {
        this(context, null);
    }

    public MyLinearLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        if (action == MotionEvent.ACTION_DOWN) {
            return false;
        } else {
            return true;
        }
    }
}
public class MyRecyclerView extends RecyclerView {
    private static final String TAG = "MyRecyclerView";

    public MyRecyclerView(Context context) {
        this(context, null);
    }

    // 分別記錄上次滑動的座標(onInterceptTouchEvent)
    private int mLastXIntercept = 0;
    private int mLastYIntercept = 0;

    public MyRecyclerView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        int x = (int) ev.getX();
        int y = (int) ev.getY();
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN: {
                getParent().requestDisallowInterceptTouchEvent(true);
                break;
            }
            case MotionEvent.ACTION_MOVE: {
                int deltaX = x - mLastXIntercept;
                int deltaY = y - mLastYIntercept;
                //如果是左右滑動
                if (Math.abs(deltaX) > Math.abs(deltaY)) {
                    getParent().requestDisallowInterceptTouchEvent(false);
                }
                break;
            }
            case MotionEvent.ACTION_UP: {
                getParent().requestDisallowInterceptTouchEvent(false);
                break;
            }
        }
        mLastXIntercept = x;
        mLastYIntercept = y;
        return super.dispatchTouchEvent(ev);
    }
}

程式碼很簡單,首先就是重寫父view的onInterceptTouchEvent,然後重寫子view的dispatchTouchEvent在上下滑動的時候獲取滑動事件;這樣就行了;

這裡要注意一個問題,因為把父view的事件全部攔截了父view不會進行事件分發了,所以子view沒有重寫dispatchTouchEvent的話是無法進行點選事件的;

效果如下:
這裡寫圖片描述

相關推薦

解決view 滑動事件衝突實戰-內部攔截

出處 Android開發藝術探索 說明:本文用的方法是(內部攔截法) 首先說下一個普遍的需求: 這個需求很普遍;像今日頭條,網易新聞什麼的都是這樣 1:底部有四個按鈕點選可以切換;左右滑可以切換(不用想用viewpager) 2:點選某個底部按鈕裡面又

ScrollView與viewpager滑動事件衝突,與點選事情衝突解決方案

在產品適配的時候我加了ScrollView,但是產品提出了一個向上輪播需求 首先把豎直向上的viewpager粘出來: package com.cfiigroup.zhehui.hepaidai.view; import android.view.MotionEvent; impo

解決ScrollView巢狀viewPager中巢狀listView滑動事件衝突問題(水平方向)

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

Android——View事件體系View滑動

主要介紹內容: View的基礎知識 View的位置引數 MotionEvent 和 TouchSlope VelocityTracker、GestureDetector 和 Scroller View的滑動 使用scrollTo/scrollBy 使用動

SwipeRefreshLayout與ViewPager滑動事件衝突解決

問題描述:開發中發現,SwipeRefreshLayout的下拉重新整理,與ViewPager開發的banner的左右滑動事件有一點衝突,導致banner的左右滑動不夠順暢。很容易在banner的左右滑動的過程中,觸發SwipeRefreshLayout的下拉重新整理,從而導

解決android中viewpager和內嵌html滑動事件衝突

           這幾天專案迭代,有個大的板塊是整體套用H5來做。由於H5裡還有好多小模組,需要一個滑動切換的效果,而android端只是提供一個空的fragment,佔據著viewpager的一個板塊。最開始的效果滑動起來分外尷尬。。           解決思路是這

完美解決HorizontalScrollView與ListView滑動事件衝突

HorizontalScrollView與ListView滑動事件衝突,導致ListView下拉不靈敏。下面給出一種比較完美的實現方式,如果是縱向的ScrollView,對應改一下就好了~~上程式碼pa

android 滑動事件衝突解決 Touch事件處理機制

android中的事件型別分為按鍵事件和螢幕觸控事件,Touch事件是螢幕觸控事件的基礎事件,有必要對它進行深入的瞭解。 一個最簡單的螢幕觸控動作觸發了一系列Touch事件:ACTION_DOWN->ACTION_MOVE->ACTION_MOVE->AC

android 控制元件的滑動事件與點選事件衝突GestureDetector,SimpleOnGestureListener

首先拿我的一個需求來舉例子:我有一個寫了一個小說閱讀器,在小說閱讀介面我想實現 可以點選翻頁,也可滑動翻頁這個就需要我們來處理點選與滑動的衝突了。 我們使用GestureDetector這個類來解決 首先建立一個GestureDetector物件,他

02_HTML5+CSS3詳解第五天實戰之HTML5制作企業網站

shu 文檔 href baidu mindjet mmap .mm 如何 鏈接 Details 一、Xmind部分 xmind教程:http://www.jianshu.com/p/7c488d5e4bdf xmind安裝破解(百度網盤鏈接:https://pan.ba

Android onTouch、OnLongClick、onClick及ScrollView滑動事件衝突

        最近要實現一個長按錄音,鬆開手指結束錄音的功能,在專案中,弄來弄去繞暈了,寫個demo來梳理下。順便研究下android事件呼叫機制。   先上效果介面: 佈局:     <Relat

Android自定義View系列:標籤LabelView實戰

前言部分 本文主要介紹如何自定義一個常見的labels標籤,功能上主要支援,單選、多選、點選三種模式。因為這個使用率很高,並且這個是比較典型學習自定義ViewGroup的例子,所以特意動手實踐,加深對Android的認識。這個專案主要是為了自己學習使用,所以並不是很完善,先上一個效果

效能環境之Jenkins+Maven自動化部署SpringBoot壓測環境實戰

文章目錄 前言 整體設計 先決條件 Step 1:安裝sun jdk1.8環境 Step 2:安裝Maven 3.5 Step 3:安裝Jenkins Step 4:安裝Jenkins外掛 Step

阿里雲clouder認證—雲資料庫管理與資料遷移實戰

阿里雲clouder認證—雲資料庫管理與資料遷移   由於關於雲資料庫管理與資料遷移理論知識太多,我已上傳了資源,有需要的可以下載看下    簡單的在這裡說下一些專有名詞:             R

CoordinatorLayout+ViewPager+SwipeRefreshLayout滑動事件衝突的處理

只是一個搬運工 連結 參考 程式碼(自己加的註釋,好多不懂,勿噴) public class NestedScrollSwipeRefreshLayout extends SwipeRefreshLayout implements Nes

實戰SSM三大框架整合詳細教程Spring+SpringMVC+MyBatis

<pre class="html" name="code" snippet_file_name="blog_20170402_1_8023453" code_snippet_id="2295822"><span style="font-size:14px;"><project x

Android自定義View圓盤滑動控制元件已適配多種解析度

好久沒寫部落格了,最近在寫一個專案時需要一個可以調節檔位的圓盤, 首先實現這個圓盤自定義View,首先在構造方法中定義畫筆,重寫onDraw(Canvas canvas)方法,進行繪製,首先繪製一個大圓,然後我這個大圓周圍的錶盤顯示一共有9個檔位,為了美觀,每個

Android 下拉重新整理 左右滑動 事件衝突

截獲listview和refreshlayout的dispatchTouchEvent方法,針對不同滑動通知父容器是否通知子控制元件獲取事件 CusMaterialRefreshLayout float xDown = -1,yDown=-1; @Overrid

android原始碼分析之View事件分發

1、View的繼承關係圖 View的繼承關係圖如下: 其中最重要的子類為ViewGroup,View是所有UI元件的基類,而ViewGroup是容納這些元件的容器,同時它也是繼承於View類。而UI元件的繼承關係如上圖,比較常用的元件類用紅色字型標出

Web安全測試中常見邏輯漏洞解析實戰

*文章原創作者: [email protected]漏洞盒子安全研究團隊,轉載請註明來自FreeBuf黑客與極客(FreeBuf.COM)  邏輯漏洞挖掘一直是安全測試中“經久不衰”的話題。相比SQL注入、XSS漏洞等傳統安全漏洞,現在的攻擊者更傾向於利用業務