View的滑动方式及滑动冲突解决方法(事件分发)

之前写过一个小球随手指滑动的demo,很简单,复写onTouchEvent,事件传递进来,得到手指触点位置,通知重绘invalidate, 复写onDraw方法,传入触点坐标。这是不断画图的过程。总结一下不画图的几种滑动方式。

1、layout方法

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        float rawX = event.getRawX();
        float x = event.getX();
        float y = event.getY();

        Log.e("mrpeng","raw:::"+rawX+"rawY::::"+x);

        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:

                break;

            case MotionEvent.ACTION_MOVE:

                float offsetX=x-lastX;

                float offsetY=y-lastY;
                break;
            case MotionEvent.ACTION_UP:
                break;
        }
        lastX = x;
        Log.e("mrpeng","lastX::::"+ lastX);
        lastY = y;
        return true;
    }

2、offsetLeftAndRight
系统提供一个对左右上下移动的API方法

View myView = findViewById(R.id.myView);
myView.offsetLeftAndRight(offsetX);

3、LayoutParams

LinearLayout.LayoutParams layoutParams =
                (LinearLayout.LayoutParams) myView.getLayoutParams();
layoutParams.leftMargin= myView.getLeft()+offsetX;
layoutParams.topMargin=myView.getTop()+offsetY;

4、scrollTo scrollBy
注意,此处移动的是View的content,即让View 的内容移动,如果ViewGroup调用此方法,那么移动的将是所有子View,如果View中使用移动的是View中的内容物,如果是TextView,则移动text,ImageView,则为drawable对象。

myView.getParent().scrollBy(-offsetX,-offsetY);

5、Scroller

Scroller mScroller=new Scroller(mContex);
    public void smoothScrollTo(int destX,int destY){
        int scrollX = getScrollX();
        int delta=destX-scrollX;
        mScroller.startScroll(scrollX,0,delta,0,1000);
        invalidate();
    }
 /**
   * 系统会在绘制View的时候在draw()方法中调用该方法,实际就是使用scrollTo()方法,
   */
    @Override
    public void computeScroll() {
        super.computeScroll();
        if (mScroller.computeScrollOffset()){
            scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
            postInvalidate();
        }
    }

6、动画
demo\codes\AnimationDrawable\app\src\main\res\anim\my_anim.xml

<?xml version="1.0" encoding="UTF-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/linear_interpolator"
    android:duration="5000">

    <!-- 定义位移变换 -->
    <translate android:fromXDelta="10"
        android:toXDelta="130"
        android:fromYDelta="30"
        android:toYDelta="-80"
        android:duration="2000"/>
</set>

属性动画
bulabula
时间分发,用一段伪代码展示其关系

public void dispatchTouchEvent(MotionEvent ev){
        boolean consume=false;
        if (onInterceptTouchEvent(ev)){
            consume=onTouchEvent(ev);
        }else {
            consume=child.diapatchTouchEvent(ev);
        }
        return consume;
    }

坑人的滑动冲突
1、父View左右滑,子View上下滑
2、父View上下滑,子View也上下滑
3、爷爷…………………… 万变不离其宗。。。
ViewPager+ListView本来是有滑动冲突的,但是强大的VoewPager已经处理过了,如果是横向ScrollView 嵌套ListView

第一种方法,父容器拦截处理,重写onInterceptTouchEvent
第二种方法,内部拦截处理,重写子元素的dispatchTouchEvent

@Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        boolean intercepted = false;
        int x = (int) event.getX();
        int y = (int) event.getY();

        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN: {
            intercepted = false;
            if (!mScroller.isFinished()) {
                mScroller.abortAnimation();
                intercepted = true;
            }
            break;
        }
        case MotionEvent.ACTION_MOVE: {
            int deltaX = x - mLastXIntercept;
            int deltaY = y - mLastYIntercept;
            if (Math.abs(deltaX) > Math.abs(deltaY)) {
                intercepted = true;
            } else {
                intercepted = false;
            }
            break;
        }
        case MotionEvent.ACTION_UP: {
            intercepted = false;
            break;
        }
        default:
            break;
        }

        Log.d(TAG, "intercepted=" + intercepted);
        mLastX = x;
        mLastY = y;
        mLastXIntercept = x;
        mLastYIntercept = y;

        return intercepted;
    }

第二种方法

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();

        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN: {
            getParent().requestDisallowInterceptTouchEvent(true);
            break;
        }
        case MotionEvent.ACTION_MOVE: {
            int deltaX = x - mLastX;
            int deltaY = y - mLastY;
            Log.d(TAG, "dx:" + deltaX + " dy:" + deltaY);
            if (Math.abs(deltaX) > Math.abs(deltaY)) {
                getParent().requestDisallowInterceptTouchEvent(false);
            }
            break;
        }
        case MotionEvent.ACTION_UP: {
            break;
        }
        default:
            break;
        }

        mLastX = x;
        mLastY = y;
        return super.dispatchTouchEvent(event);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值