android HorizontalScrollView嵌套RecyclerView横向不能滑动问题

本文主要是介绍android HorizontalScrollView嵌套RecyclerView横向不能滑动问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

开发场景:在 HorizontalScrollView内嵌套RecyclerView和其他内容,要求其他控件和RecyclerView一起横向滑动,而RecyclerView自身滑动事件不响应。

问题分析:1.HorizontalScrollView内嵌套RecyclerView,发现HorizontalScrollView不能横向滑动;

                2.RecyclerView于HorizontalScrollView的滑动冲突。

这个需求所面临的问题里面,第二个问题的解决方案很多,例如重写HorizontalScrollView,阻止滑动事件的传递。

首先来看第一个问题的解决方案:

第一,当我把HorizontalScrollView内嵌RecyclerView工程跑起来后,发现不能够滑动,重写RecyclerView的LinearLayoutManager,主要重写onMeasure方法,来计算出width和height。示例代码如下:

public class MyLinearLayoutManager extends LinearLayoutManager {public MyLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {super(context, orientation, reverseLayout);
    }private int[] mMeasuredDimension = new int[2];

    @Override
    public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state,
                          int widthSpec, int heightSpec) {final int widthMode = View.MeasureSpec.getMode(widthSpec);
        final int heightMode = View.MeasureSpec.getMode(heightSpec);
        final int widthSize = View.MeasureSpec.getSize(widthSpec);
        final int heightSize = View.MeasureSpec.getSize(heightSpec);
        int width = 0;
        int height = 0;
        for (int i = 0; i <getItemCount(); i++) {if (getOrientation() == HORIZONTAL) {measureScrapChild(recycler, i,
                        View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
                        heightSpec,
                        mMeasuredDimension);

                width = width + mMeasuredDimension[0];
                if (i == 0) {height = mMeasuredDimension[1];
                }} else {measureScrapChild(recycler, i,
                        widthSpec,
                        View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
                        mMeasuredDimension);
                height = height + mMeasuredDimension[1];
                if (i == 0) {width = mMeasuredDimension[0];
                }}}switch (widthMode) {case View.MeasureSpec.EXACTLY:width = widthSize;
            case View.MeasureSpec.AT_MOST:case View.MeasureSpec.UNSPECIFIED:}switch (heightMode) {case View.MeasureSpec.EXACTLY:height = heightSize;
            case View.MeasureSpec.AT_MOST:case View.MeasureSpec.UNSPECIFIED:}width += 30 * getItemCount();

        setMeasuredDimension(width, height);
    }private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,
                                   int heightSpec, int[] measuredDimension) {View view = recycler.getViewForPosition(position);
        recycler.bindViewToPosition(view, position);
        if (view != null) {RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
            int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec,
                    getPaddingLeft() + getPaddingRight(), p.width);
            int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec,
                    getPaddingTop() + getPaddingBottom(), p.height);
            view.measure(childWidthSpec, childHeightSpec);
            measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin;
            measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin;
            recycler.recycleView(view);
        }}
}
 

解释下为什么会有下面这一句,因为设置了RecyclerView的间距,重写了RecyclerView.ItemDecoration方法,每一个item的间距设置了30px,所以,为了让ui显示完整,得加上下面这句代码,如果不需要设置间距,删除下面代码。

感慨下,代码还是比较简陋的,毕竟是demo

width += 30 * getItemCount();

另外,使用控件的时候,还需要给控件设置下面的属性
recyclerView.setNestedScrollingEnabled(false)

第二,重写RecyclerView,来阻止事件的分发,从而达到recyclerView不能滑动的问题,示例代码如下:

public class MyScollView extends HorizontalScrollView {public MyScollView(Context context) {super(context);
    }public MyScollView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);
    }public MyScollView(Context context, @Nullable AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);
    }private float lastX, lastY;

    @Override
    public boolean onInterceptTouchEvent(MotionEvent e) {boolean intercept = super.onInterceptTouchEvent(e);

        switch (e.getAction()) {case MotionEvent.ACTION_DOWN:lastX = e.getX();
                lastY = e.getY();
                break;
            case MotionEvent.ACTION_MOVE:// 只要横向大于竖向,就拦截掉事件。
                // 部分机型点击事件(slopx==slopy==0),会触发MOVE事件。
                // 所以要加判断(slopX > 0 || sloy > 0)
                float slopX = Math.abs(e.getX() - lastX);
                float slopY = Math.abs(e.getY() - lastY);
                //  Log.log("slopX=" + slopX + ", slopY="  + slopY);
                if((slopX > 0 || slopY > 0) && slopX >= slopY){requestDisallowInterceptTouchEvent(true);
                    intercept = true;
                }break;
            case MotionEvent.ACTION_UP:intercept = false;
                break;
        }// Log.log("intercept"+e.getAction()+"=" + intercept);
        return intercept;
    }
}

在布局的时候记得使用自定义的ScollView,另外再说一下在开发的时候还遇到一个问题:

recyclerview嵌在ScollView里面,发现recyclerView不显示,查了查资料,通过设置了ScollView的width,height为match_parent,另外,还有一个重要属性需要设置

android:fillViewport="true"

这篇关于android HorizontalScrollView嵌套RecyclerView横向不能滑动问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/655049

相关文章

Pyserial设置缓冲区大小失败的问题解决

《Pyserial设置缓冲区大小失败的问题解决》本文主要介绍了Pyserial设置缓冲区大小失败的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录问题描述原因分析解决方案问题描述使用set_buffer_size()设置缓冲区大小后,buf

resultMap如何处理复杂映射问题

《resultMap如何处理复杂映射问题》:本文主要介绍resultMap如何处理复杂映射问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录resultMap复杂映射问题Ⅰ 多对一查询:学生——老师Ⅱ 一对多查询:老师——学生总结resultMap复杂映射问题

java实现延迟/超时/定时问题

《java实现延迟/超时/定时问题》:本文主要介绍java实现延迟/超时/定时问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java实现延迟/超时/定时java 每间隔5秒执行一次,一共执行5次然后结束scheduleAtFixedRate 和 schedu

在Android平台上实现消息推送功能

《在Android平台上实现消息推送功能》随着移动互联网应用的飞速发展,消息推送已成为移动应用中不可或缺的功能,在Android平台上,实现消息推送涉及到服务端的消息发送、客户端的消息接收、通知渠道(... 目录一、项目概述二、相关知识介绍2.1 消息推送的基本原理2.2 Firebase Cloud Me

如何解决mmcv无法安装或安装之后报错问题

《如何解决mmcv无法安装或安装之后报错问题》:本文主要介绍如何解决mmcv无法安装或安装之后报错问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mmcv无法安装或安装之后报错问题1.当我们运行YOwww.chinasem.cnLO时遇到2.找到下图所示这里3.

浅谈配置MMCV环境,解决报错,版本不匹配问题

《浅谈配置MMCV环境,解决报错,版本不匹配问题》:本文主要介绍浅谈配置MMCV环境,解决报错,版本不匹配问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录配置MMCV环境,解决报错,版本不匹配错误示例正确示例总结配置MMCV环境,解决报错,版本不匹配在col

Vue3使用router,params传参为空问题

《Vue3使用router,params传参为空问题》:本文主要介绍Vue3使用router,params传参为空问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录vue3使用China编程router,params传参为空1.使用query方式传参2.使用 Histo

SpringBoot首笔交易慢问题排查与优化方案

《SpringBoot首笔交易慢问题排查与优化方案》在我们的微服务项目中,遇到这样的问题:应用启动后,第一笔交易响应耗时高达4、5秒,而后续请求均能在毫秒级完成,这不仅触发监控告警,也极大影响了用户体... 目录问题背景排查步骤1. 日志分析2. 性能工具定位优化方案:提前预热各种资源1. Flowable

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

Android中Dialog的使用详解

《Android中Dialog的使用详解》Dialog(对话框)是Android中常用的UI组件,用于临时显示重要信息或获取用户输入,本文给大家介绍Android中Dialog的使用,感兴趣的朋友一起... 目录android中Dialog的使用详解1. 基本Dialog类型1.1 AlertDialog(