安卓多個RecyclerView滑動與顯示問題


 最近在項目遇到這樣的問題:在一線性垂直布局內,有兩個垂直的RecyclerView,如果直接高度直接設置wrap-content,
 通常會導致滑動沖突或是內容顯示不全。

首先說下解決的思路,就是在最外面嵌套一層自定義的ScrollView,重寫其相關方法,判斷若為垂直滑動則攔截下來,不交由RecyclerView來處理。
這樣的話,滑動沖突就能解決,並且是很流暢的。

不過這樣在有些設備可能還會出現個問題, 就是內容顯示不全。這里可以通過在顯示不全的RecyclerView外面套一層RelativeLayout,即:


           <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    >
                    <!-- 和項目為androidx無關 -->

                    <androidx.recyclerview.widget.RecyclerView
                        android:id="@+id/recyclerview"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content" />
           </RelativeLayout>


這樣的話, 內容就可以顯示完全了。

下面繼續ScrollView的滑動事件


自定義一個view,並繼承自ScrollView, 再重寫onInterceptTouchEvent方法;

具體內容則是:


    @Override
    public boolean onInterceptTouchEvent(MotionEvent e) {
        int action = e.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                // downX = (int) e.getRawX();
                downY = (int) e.getRawY();
                break;
            case MotionEvent.ACTION_MOVE:
                int moveY = (int) e.getRawY();
                if (Math.abs(moveY - downY) > touchSlop) {
                    return true;
                }
        }
        return super.onInterceptTouchEvent(e);
    }


獲取觸屏開始和結束位置坐標的Y值,取相減的絕對值,再與touchSlop比較,大於這個值則判斷此次為滑動事件,則攔截。
其中touchSlop 是判斷是否滑動的參考值。官方給出的解釋是

/**
 *  Distance in pixels a touch can wander before we think the user is scrolling
 */

大體過程就是這樣,下面貼上自定義ScrollView的全部代碼:



package com.asche.wetalk.helper;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.widget.ScrollView;

/**
 *  攔截滑動事件,不由recyclerview處理
 */
public class MyScrollViewScroll extends ScrollView {
    // private int downX;
    private int downY;
    private int touchSlop;

    public MyScrollViewScroll(Context context) {
        super(context);
        touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
    }

    public MyScrollViewScroll(Context context, AttributeSet attrs) {
        super(context, attrs);
        touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
    }

    public MyScrollViewScroll(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent e) {
        int action = e.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                // downX = (int) e.getRawX();
                downY = (int) e.getRawY();
                break;
            case MotionEvent.ACTION_MOVE:
                int moveY = (int) e.getRawY();
                if (Math.abs(moveY - downY) > touchSlop) {
                    return true;
                }
        }
        return super.onInterceptTouchEvent(e);
    }

    @Override
    protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
        super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
    }
}





免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM