(转载) Scrollview 嵌套 RecyclerView 及在Android 5.1版本滑动时 惯性消失问题

Scrollview 嵌套 RecyclerView 及在Android 5.1版本滑动时 惯性消失问题

标签: scrollviewandroid滑动嵌套

2015-07-16 17:24 11126人阅读 评论(17) 收藏 举报

 分类:

Android进阶(19) 

版权声明:本文为博主原创文章,未经博主允许不得转载。

scrollview 嵌套recyclerview 时,recyclerview不显示,这就需要我们自己计算recyclerview的高度,比如:

 ViewGroup.LayoutParams mParams = recyclerView.getLayoutParams();
        mParams.height = (CommonUtils.getScreenWidthPX(getActivity()) * 480 / 720 + CommonUtils.dipToPixels(40)) * num + CommonUtils.dipToPixels(8);
        mParams.width = CommonUtils.getScreenWidthPX(getActivity());
        recyclerView.setLayoutParams(mParams);
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

这中方法适合item高度比较好计算的情形,但要遇到里面的item高度不一定这就需要我们重写recyclerview的高度了,以前嵌套listview的时候我们只需重写listview 然后重写

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // TODO Auto-generated method stub
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
                MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

但是这种方法在recyclerview重写不管用。 
我们此时要重写的的是LinearLayoutManager或GridLayoutManager

public class FullyLinearLayoutManager extends LinearLayoutManager {

    private static final String TAG = FullyLinearLayoutManager.class.getSimpleName();

    public FullyLinearLayoutManager(Context context) {
        super(context);
    }

    public FullyLinearLayoutManager(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);

        Log.i(TAG, "onMeasure called. \nwidthMode " + widthMode
                + " \nheightMode " + heightSpec
                + " \nwidthSize " + widthSize
                + " \nheightSize " + heightSize
                + " \ngetItemCount() " + getItemCount());

        int width = 0;
        int height = 0;
        for (int i = 0; i < getItemCount(); i++) {
            measureScrapChild(recycler, i,
                    View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
                    View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
                    mMeasuredDimension);

            if (getOrientation() == HORIZONTAL) {
                width = width + mMeasuredDimension[0];
                if (i == 0) {
                    height = mMeasuredDimension[1];
                }
            } else {
                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:
        }

        setMeasuredDimension(width, height);
    }

    private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,
                                   int heightSpec, int[] measuredDimension) {
        try {
            View view = recycler.getViewForPosition(0);//fix 动态添加时报IndexOutOfBoundsException

            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);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92

=======

public class FullyGridLayoutManager extends GridLayoutManager {

    private int mwidth = 0;
    private int mheight = 0;

    public FullyGridLayoutManager(Context context, int spanCount) {
        super(context, spanCount);
    }

    public FullyGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) {
        super(context, spanCount, orientation, reverseLayout);
    }

    private int[] mMeasuredDimension = new int[2];

    public int getMwidth() {
        return mwidth;
    }

    public void setMwidth(int mwidth) {
        this.mwidth = mwidth;
    }

    public int getMheight() {
        return mheight;
    }

    public void setMheight(int mheight) {
        this.mheight = mheight;
    }

    @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;
        int count = getItemCount();
        int span = getSpanCount();
        for (int i = 0; i < count; i++) {
            measureScrapChild(recycler, i,
                    View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
                    View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
                    mMeasuredDimension);

            if (getOrientation() == HORIZONTAL) {
                if (i % span == 0) {
                    width = width + mMeasuredDimension[0];
                }
                if (i == 0) {
                    height = mMeasuredDimension[1];
                }
            } else {
                if (i % span == 0) {
                    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:
        }
        setMheight(height);
        setMwidth(width);
        setMeasuredDimension(width, height);
    }

    private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,
                                   int heightSpec, int[] measuredDimension) {
        if (position < getItemCount()) {
            try {
                View view = recycler.getViewForPosition(0);//fix 动态添加时报IndexOutOfBoundsException
                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);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105

重写完之后,用就好说了,在adapter的onBindview和平常一样用就可以了

 final FullyGridLayoutManager manager = new FullyGridLayoutManager(context.getActivity(), 3);
        manager.setOrientation(GridLayoutManager.VERTICAL);
        manager.setSmoothScrollbarEnabled(true);
        viewHolder.recyclerView.setLayoutManager(manager);
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

此种方法在4.x系统上好用,能显示滑动也流畅,但是在5.x上虽然显示正常,但是滑动的时候好像被粘住了,没有惯性效果。。。。然后郁闷了一下午。。。。 
最后解决方法是重写最外层的Scrollview

**
 * 屏蔽 滑动事件
 * Created by fc on 2015/7/16.
 */
public class MyScrollview extends ScrollView {
    private int downX;
    private int downY;
    private int mTouchSlop;

    public MyScrollview(Context context) {
        super(context);
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
    }

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

    public MyScrollview(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mTouchSlop = 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) > mTouchSlop) {
                    return true;
                }
        }
        return super.onInterceptTouchEvent(e);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

这样就可以了,暴力屏蔽。。。。5以上的事件直接传递给了内层的recyclerview,所以我们把滑动事件拦截就好了。。。 
 

4

1
时间: 2024-10-12 18:56:13

(转载) Scrollview 嵌套 RecyclerView 及在Android 5.1版本滑动时 惯性消失问题的相关文章

Scrollview 嵌套 RecyclerView 及在Android 5.1版本滑动时 惯性消失问题

scrollview 嵌套recyclerview 时,recyclerview不显示,这就需要我们自己计算recyclerview的高度,比如: ViewGroup.LayoutParams mParams = recyclerView.getLayoutParams(); mParams.height = (CommonUtils.getScreenWidthPX(getActivity()) * 480 / 720 + CommonUtils.dipToPixels(40)) * num

Android Scrollview嵌套RecyclerView导致滑动卡顿问题解决

一个比较长的界面一般都是Scrollview嵌套RecyclerView来解决.不过这样的UI并不是我们开发人员想看到的,实际上嵌套之后.因为Scrollview和RecyclerView都是滑动控件.会有一点滑动上的冲突.导致滑动起来有些卡顿.这个时候.我们重写一下LayoutManager就行了 例如: [java] view plain copy LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getAct

Android 解决ScrollView嵌套RecyclerView导致滑动不流畅的问题

最近做的项目中遇到了ScrollView嵌套RecyclerView,刚写完功能测试,直接卡出翔了,后来通过网上查找资料和 自己的实践,找出了两种方法解决这个问题. 首先来个最简单的方法: recyclerView.setNestedScrollingEnabled(false); 这个方法就可以解决这一问题. 既然有首先那肯定有第二种解决的办法,只不过相对于第一种方法来说就太麻烦了. 我们知道ScrollView嵌套listView或者GridView的时候需要自定义listView或者是Gr

解决ScrollView嵌套RecyclerView的显示及滑动问题

项目中时常需要实现在ScrollView中嵌入一个或多个RecyclerView.这一做法通常会导致如下几个问题 页面滑动卡顿 ScrollView高度显示不正常 RecyclerView内容显示不全 本文将利用多种方式分别解决上述问题 滑动卡顿解决方案 若只存在滑动卡顿这一问题,可以采用如下两种简单方式快速解决 利用RecyclerView内部方法 recyclerView.setHasFixedSize(true); recyclerView.setNestedScrollingEnable

ScrollView嵌套recyclerView出现的滑动问题

记得以前在解决scrollView与ListView嵌套问题时,那个时候是自定义了listView去测量listView高度,今天项目中刚 好碰到了要用recycerView,同样也是嵌套在scrollView中,但是按照以前listView方法居然不显示了,后来发现原来是要重写的是 LayoutManager... 在此说明,这是copy大神的,我只是为了学习啊!大神真的很牛啊! 原创博客:http://blog.csdn.net/u010623588/article/details/5026

scrollview嵌套上下拉控件嵌套recyclerview

相信会碰到很多类似的需求,一个列表控件,然后控件上方的一个头部需要自定义,这样就不好有时候也不能加在列表控件的头部了,那必须得嵌套一层scrollview了,没毛病,那么一般的列表控件都是有上拉下拉的操作,而且一般也是在 github 上找寻一个收藏量高的 来做为一个全局通用的上下拉控件,这里问题就来了,一般的 scrollview 嵌套 recyclerview 或者 listview 都毕竟容易解决,可是在加上一层上下拉控件呢?上下拉控件肯定会有它自己的触摸处理机制,这样你改起来也很麻烦,这

RecyclerView使用 及 滑动时加载图片优化方案

RecyclerView使用 及 滑动时加载图片优化方案 简述 本篇博文主要给大家分享关于RecyclerView控件的使用及通过继承RecyclerView来实现滑动时加载图片的优化方案,也同样能解决防止图片乱序的问题,之前有在网上有看到大神对Android中ListView异步加载图片乱序问题进行过分析,并深入剖析原理后分别给出了3种对应的解决方案:一 .使用findViewWithTag.二.使用弱引用关联.三.使用Volley框架提供的NetworkImageView. 看了之后思索了很

RecyclerView和ScrollView嵌套使用

我们的recyclerView有多个layoutmanager,通过重写layoutmanager的方法就可以让recyclerView和ScrollView嵌套了.但是请注意,如果recyclerView很长那么强烈不建议去做嵌套,因为这样recyclerView会在展示的时候立刻展示所有内容,效率极低. 本文的两部分代码来自一个博主的博客,另一个是我自己写的,正好可以完全适用于现有的layoutmanager.大家需要的化可以试试,应该问题不大. 原博主的demo:https://githu

Android仿小米商城商品详情界面UI,ScrollView嵌套ScrollView/WebView/ListView

最近公司没事,研究了下多嵌套滚动组件的事件分发,虽然以前也接触过,但都是拿网上的用,也是特别简单的,正好朋友也需要,就研究了下 这个Demo也不是很完善,放上来也是让各位大牛给指点一下,优化优化 使用情景: 小米商城商品详情界面,界面看似ScrollView,但当正常滚动到底部时,提示继续上拉显示更多详情,上拉后直接滚动到第二屏,第二屏是个ViewPager,ViewPager里面的各个pager有的是WebView有的是ListView,有的是ScrollView,一开始想想就特别头晕,后来理