ViewGroup内嵌一个ScrollView,实现下拉回弹效果

来源:互联网 发布:json框架有哪些 编辑:程序博客网 时间:2024/06/05 03:57

首先说明,这个例子是来自这篇博客的(一个Demo带你彻底掌握View的滑动冲突),感谢博主的分享。看了该博主的文章,于是自己试了一下,也看了评论,从中得到些解决方法,有些零散,于是自己集合起来做了些修改,可以实现平滑上下移动、ViewGroup不会出现一直往上移动的bug、松手时动画回弹、还有回弹过程中手指马上进行滑动所出现的问题。本来想在博主评论区回复的,发现回复有字数限制,所以只好写在这里了微笑

效果图如下:


下面直接贴出代码吧,关键部分有解析的了

主要的两个类:

/** * Created by Gerka on 2016/12/11. */public class MyParentView extends LinearLayout {    private ScrollView scrollView;    private ValueAnimator animator;    private int mMove;    private int yDown, yMove;    private int i = 0;    private boolean isIntercept = false;    private int actionTop;    private int actionBottom;    public MyParentView(Context context) {        super(context);    }    public MyParentView(Context context, AttributeSet attrs) {        super(context, attrs);    }    public MyParentView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    public MyParentView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {        super(context, attrs, defStyleAttr, defStyleRes);    }    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        super.onLayout(changed, l, t, r, b);        scrollView = (ScrollView) getChildAt(0);    }    @Override    public boolean dispatchTouchEvent(MotionEvent ev) {//        Log.v("kaka", "------------------isIntercept = "+isIntercept+"----event = "+ev.getAction());        onInterceptTouchEvent(ev);        return super.dispatchTouchEvent(ev);    }    @Override    public boolean onInterceptTouchEvent(MotionEvent ev) {        int y = (int) ev.getY();        int mScrollY = scrollView.getScrollY();        switch (ev.getAction()) {            case MotionEvent.ACTION_DOWN:                Log.i("kaka", "------------action down");                yDown = y;                if(animator != null){                    animator.end(); //一定要加这个,让布局立刻回位,不然的话,回弹动画没结束就马上进行下一次的下拉,布局会飞走噢                }                break;            case MotionEvent.ACTION_MOVE:                yMove = y;//                Log.i("kaka", "--------------yDown = "+yDown+"-----yMove = "+yMove+"---isIntercept = "+isIntercept+"---mScrollY = "+mScrollY);                if (yMove - yDown > 0 && mScrollY == 0) {                    Log.i("kaka", "--------------isIntercept = "+isIntercept);                    if (!isIntercept) {                        yDown = (int) ev.getY();                        isIntercept = true;                    }                }                break;            case MotionEvent.ACTION_UP://                layout(getLeft(), getTop() - i, getRight(), getBottom() - i);                actionTop = getTop();                actionBottom = getBottom();                animator = ValueAnimator.ofInt(0, i);                animator.setDuration(500);                animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {                    @Override                    public void onAnimationUpdate(ValueAnimator animation) {                        int curValue = (int) animation.getAnimatedValue();                        layout(getLeft(), actionTop - curValue, getRight(), actionBottom - curValue);                    }                });                animator.start();                i = 0;                isIntercept = false;                break;        }        if (isIntercept) {            mMove = yMove - yDown;            i += mMove;            if(i < 0){  //判断少于0时,要把isIntercept至为false了,不然布局会一直往上移动,会移出去                isIntercept = false;                //这里做了 move - i 的处理,是为了要把布局刚好回位到y = 0的位置                layout(getLeft(), getTop() + mMove - i, getRight(), getBottom() + mMove - i);                i = 0;            }else {                layout(getLeft(), getTop() + mMove, getRight(), getBottom() + mMove);            }        }        return isIntercept;    }}

/** * Created by Gerka on 2016/12/11. */public class MyScrollView extends ScrollView {    public MyScrollView(Context context) {        super(context);    }    public MyScrollView(Context context, AttributeSet attrs) {        super(context, attrs);    }    public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {        super(context, attrs, defStyleAttr, defStyleRes);    }    @Override    public boolean onTouchEvent(MotionEvent ev) {        switch (ev.getAction()) {            case MotionEvent.ACTION_DOWN:                //这里很关键,如果不加这句,当ScrollView在顶端时,手指开始下滑操作,然后再往上滑时,你会发现ScrollView里面的view不会滑动                getParent().requestDisallowInterceptTouchEvent(true);                break;        }        return super.onTouchEvent(ev);    }}

布局文件,很简单

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/activity_main"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="@android:color/holo_blue_bright"    tools:context="com.readboy.gerka.myapplication.MainActivity">    <com.gerka.widget.MyParentView        android:layout_width="match_parent"        android:layout_marginTop="100dp"        android:layout_height="match_parent"        >        <com.gerka.widget.MyScrollView            android:layout_width="match_parent"            android:layout_height="match_parent"            android:background="#ff0000">            <LinearLayout                android:layout_width="match_parent"                android:layout_height="match_parent"                android:orientation="vertical">                <include layout="@layout/item_text_layout"/>                <include layout="@layout/item_text_layout"/>                <include layout="@layout/item_text_layout"/>                <include layout="@layout/item_text_layout"/>                <include layout="@layout/item_text_layout"/>                <include layout="@layout/item_text_layout"/>                <include layout="@layout/item_text_layout"/>                <include layout="@layout/item_text_layout"/>                <include layout="@layout/item_text_layout"/>                <include layout="@layout/item_text_layout"/>                <include layout="@layout/item_text_layout"/>            </LinearLayout>        </com.gerka.widget.MyScrollView>    </com.gerka.widget.MyParentView>    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="Hello World!"        android:contentDescription="@android:string/ok"        android:id="@+id/ooo"        android:layout_marginTop="38dp"        android:layout_alignParentTop="true"        android:layout_alignParentStart="true"        android:layout_marginStart="29dp" /></RelativeLayout>

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="60dp">    <TextView        android:layout_width="match_parent"        android:layout_height="match_parent"        android:text="利物浦"        android:gravity="center"        android:textSize="20sp"        /></LinearLayout>



3 0
原创粉丝点击