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

相关文章

MySQL 横向衍生表(Lateral Derived Tables)的实现

《MySQL横向衍生表(LateralDerivedTables)的实现》横向衍生表适用于在需要通过子查询获取中间结果集的场景,相对于普通衍生表,横向衍生表可以引用在其之前出现过的表名,本文就来... 目录一、横向衍生表用法示例1.1 用法示例1.2 使用建议前面我们介绍过mysql中的衍生表(From子句

MySQL 设置AUTO_INCREMENT 无效的问题解决

《MySQL设置AUTO_INCREMENT无效的问题解决》本文主要介绍了MySQL设置AUTO_INCREMENT无效的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参... 目录快速设置mysql的auto_increment参数一、修改 AUTO_INCREMENT 的值。

关于跨域无效的问题及解决(java后端方案)

《关于跨域无效的问题及解决(java后端方案)》:本文主要介绍关于跨域无效的问题及解决(java后端方案),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录通用后端跨域方法1、@CrossOrigin 注解2、springboot2.0 实现WebMvcConfig

Go语言中泄漏缓冲区的问题解决

《Go语言中泄漏缓冲区的问题解决》缓冲区是一种常见的数据结构,常被用于在不同的并发单元之间传递数据,然而,若缓冲区使用不当,就可能引发泄漏缓冲区问题,本文就来介绍一下问题的解决,感兴趣的可以了解一下... 目录引言泄漏缓冲区的基本概念代码示例:泄漏缓冲区的产生项目场景:Web 服务器中的请求缓冲场景描述代码

Java死锁问题解决方案及示例详解

《Java死锁问题解决方案及示例详解》死锁是指两个或多个线程因争夺资源而相互等待,导致所有线程都无法继续执行的一种状态,本文给大家详细介绍了Java死锁问题解决方案详解及实践样例,需要的朋友可以参考下... 目录1、简述死锁的四个必要条件:2、死锁示例代码3、如何检测死锁?3.1 使用 jstack3.2

解决JSONField、JsonProperty不生效的问题

《解决JSONField、JsonProperty不生效的问题》:本文主要介绍解决JSONField、JsonProperty不生效的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录jsONField、JsonProperty不生效javascript问题排查总结JSONField

github打不开的问题分析及解决

《github打不开的问题分析及解决》:本文主要介绍github打不开的问题分析及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、找到github.com域名解析的ip地址二、找到github.global.ssl.fastly.net网址解析的ip地址三

MySQL版本问题导致项目无法启动问题的解决方案

《MySQL版本问题导致项目无法启动问题的解决方案》本文记录了一次因MySQL版本不一致导致项目启动失败的经历,详细解析了连接错误的原因,并提供了两种解决方案:调整连接字符串禁用SSL或统一MySQL... 目录本地项目启动报错报错原因:解决方案第一个:第二种:容器启动mysql的坑两种修改时区的方法:本地

springboot加载不到nacos配置中心的配置问题处理

《springboot加载不到nacos配置中心的配置问题处理》:本文主要介绍springboot加载不到nacos配置中心的配置问题处理,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录springboot加载不到nacos配置中心的配置两种可能Spring Boot 版本Nacos

Java中JSON格式反序列化为Map且保证存取顺序一致的问题

《Java中JSON格式反序列化为Map且保证存取顺序一致的问题》:本文主要介绍Java中JSON格式反序列化为Map且保证存取顺序一致的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未... 目录背景问题解决方法总结背景做项目涉及两个微服务之间传数据时,需要提供方将Map类型的数据序列化为co