Android listview viewpager解决冲突 滑动

ListView中嵌套ViewPage有或者滑动手势冲突解决

在listview 上使用 addHeaderView 在第一栏添加 viewpager 当做header

如:





当触发 滑动事件 的时候容易引起 滑动冲突    (比如斜着滑动viewpager  的时候 listview会跳动)

特别是在  下拉刷新或者上拉加载 的时候 , 组件可能会传递到viewpager当中


查阅了很多的帖子  发现修改起来都非常麻烦


(1)解决方案
1. 针对viewpager 做了些修改  

替换掉support.v4当中的viewpager即可:


    package com.example.bz_viewpager;
     
    import android.content.Context;
    import android.support.v4.view.ViewPager;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.view.ViewGroup;
     
    /**
     * viewpage 和listview 相互冲突 将父view 传递到viewpage 里面
     *
     * 使用父类的方法 parent.requestDisallowInterceptTouchEvent(true);
     *
     * 当 requestDisallowInterceptTouchEvent 如果为true的时候 表示:父view 不拦截子view的touch 事件
     *
     * 这个方法只是改变flag  
     *
     * @author baozi
     *
     */
    public class DecoratorViewPager extends ViewPager {
        private ViewGroup parent;
     
        public DecoratorViewPager(Context context) {
            super(context);
            // TODO Auto-generated constructor stub
        }
     
        public DecoratorViewPager(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
     
        public void setNestedpParent(ViewGroup parent) {
            this.parent = parent;
        }
     
        @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            if (parent != null) {
                parent.requestDisallowInterceptTouchEvent(true);
            }
            return super.dispatchTouchEvent(ev);
        }
     
        @Override
        public boolean onInterceptTouchEvent(MotionEvent arg0) {
            if (parent != null) {
                parent.requestDisallowInterceptTouchEvent(true);
            }
            return super.onInterceptTouchEvent(arg0);
        }
     
        @Override
        public boolean onTouchEvent(MotionEvent arg0) {
            if (parent != null) {
                parent.requestDisallowInterceptTouchEvent(true);
            }
            return super.onTouchEvent(arg0);
        }
     
    }


2 . 在xml里面:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="#f1f1f1" >
     
        <com.example.bz_viewpager.DecoratorViewPager
            android:id="@+id/vp"
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:fadingEdge="none" />
     
    </RelativeLayout>



3. 在代码里使用

将 viewpager 的父view传递到viewpager里面  

调用:       vp.setNestedpParent((ViewGroup)vp.getParent()); 方法

如下:

            lv = (ListView) findViewById(R.id.lv);
     
            View header = LayoutInflater.from(MainActivity.this).inflate(R.layout.viewpage_layout, null);
            DecoratorViewPager vp = (DecoratorViewPager) header.findViewById(R.id.vp);
            vp.setNestedpParent((ViewGroup)vp.getParent());
     
            MyPagapter myPagapter = new MyPagapter(MainActivity.this);
            vp.setAdapter(myPagapter);
            lv.addHeaderView(header);



(2)解析:

viewgroup 当中有 一个 requestDisallowInterceptTouchEvent方法

这个方法只改变flag  当 view.requestDisallowInterceptTouchEvent 参数为true的时候  

view 不会拦截其子控件的 触摸事件


        /**
         * Called when a child does not want this parent and its ancestors to
         * intercept touch events with
         * {@link ViewGroup#onInterceptTouchEvent(MotionEvent)}.
         *
         * <p>This parent should pass this call onto its parents. This parent must obey
         * this request for the duration of the touch (that is, only clear the flag
         * after this parent has received an up or a cancel.</p>
         *
         * @param disallowIntercept True if the child does not want the parent to
         *            intercept touch events.
         */
        public void requestDisallowInterceptTouchEvent(boolean disallowIntercept);


贴上源码:

        public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
     
            if (disallowIntercept == ((mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0)) {
                // We're already in this state, assume our ancestors are too
                return;
            }
     
            if (disallowIntercept) {
                mGroupFlags |= FLAG_DISALLOW_INTERCEPT;
            } else {
                mGroupFlags &= ~FLAG_DISALLOW_INTERCEPT;
            }
     
            // Pass it up to our parent
            if (mParent != null) {
                mParent.requestDisallowInterceptTouchEvent(disallowIntercept);
            }
        }



Demo 下载地址:

http://download.csdn.net/detail/aaawqqq/8447693

 

祝福大家每日精进

谢谢


---------------------
作者:NDK-baozi
来源:CSDN
原文:https://blog.csdn.net/aaawqqq/article/details/43824631
版权声明:本文为博主原创文章,转载请附上博文链接!

posted @ 2019-06-12 18:29  天涯海角路  阅读(467)  评论(0)    收藏  举报