欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

View滑动-跟随手指移动

程序员文章站 2022-06-09 10:34:03
...

对View的移动,实现的方法有好几种,原理是通过改变View的位置来移动View,下面来实现这样的效果
View滑动-跟随手指移动

  • 动画的方法
    通过改变View的tranlationX和tranlationY的值来实现移动,首先来写一个自定义View类,重写onTouchEvent方法,实现构造方法
public class MyView extends View {
    public MyView(Context context) {
        super(context);
    }

    public MyView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return true;//这里我们要消费这个事件,所以返回了true
    }
}

关于移动的处理逻辑都在onTouchEvent方法中,下面的代码主要针对onTouchEvent方法修改,其它代码不再贴上了

首先要获取手指点击移动在屏幕上的坐标,使用

int x = (int)event.getRawX();//获取x轴上的位置 
int y = (int)event.getRawY();//获取y轴上的位置

处理事件的模板代码

switch(event.getAction()){
    case MotionEvent.ACTION_DOWN://点击事件
        break;
    case MotionEvent.ACTION_MOVE://移动事件
        break;
    case MotionEvent.ACTION_UP://离开事件
        break;
    default:
        break;
}

通过判断事件的类型,将在ACTION_MOVE事件中计算移动前后的差值来设置View的translationX和translationY值来改变View的位置,这里需要记录上次的位置,所以需要2个变量,代码如下

private int mLaxtX;
private int mLaxtY;

  @Override
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getRawX();
        int y = (int) event.getRawY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                break;
            case MotionEvent.ACTION_MOVE:
                int deltaX = x - mLastX;//计算x坐标上的差值
                int deltaY = y - mLastY;//计算y坐标上的差值
                float tranX = getTranslationX() + deltaX ;//要平移的x值
                float tranY = getTranslationY() + deltaY;//要平移的y值
                setTranslationX(tranX);//设置值
                setTranslationY(tranY);
                break;
            case MotionEvent.ACTION_UP:

                break;
            default:
                break;
        }
        mLastX = x;//记录上次的坐标
        mLastY = y;
        return true;
    }
  • layout方法
    View在绘制的时候,会调用onLayout方法来设置显示的位置,可以通过这个方法来实现移动
        //layout方法实现
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                break;
            case MotionEvent.ACTION_MOVE:
                //计算偏移量
                int offsetX = x - mLastX;
                int offsetY = y - mLastY;
                //重新布局
                layout(getLeft() + offsetX, getTop() + offsetY,
                        getRight() + offsetX, getBottom() + offsetY);
                //也可以使用下面这种方法
//                offsetLeftAndRight(offsetX);
//                offsetTopAndBottom(offsetY);
                break;
            case MotionEvent.ACTION_UP:
                break;
            default:
                break;
        }
        mLastX = x;
        mLastY = y;
  • LayoutParams
    LayoutParams保存了一个View的布局参数,通过改变这个参数,重绘View也可以实现移动
 //LayoutParams方法
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                break;
            case MotionEvent.ACTION_MOVE:
                int offsetX = x - mLastX;
                int offsetY = y - mLastY;
                //示例代码的父View是LinearLayout
                LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) getLayoutParams();
                layoutParams.leftMargin = getLeft() + offsetX;
                layoutParams.topMargin = getTop() + offsetY;
                //下面这两句都可以使用,setLayoutParams也会调用requestLayout
                //                setLayoutParams(layoutParams);
                requestLayout();
                break;
            case MotionEvent.ACTION_UP:
                break;
            default:
                break;
        }

这里先介绍这几种方法~~~
完整代码如下:

public class MyView extends View {
    public MyView(Context context) {
        super(context);
    }

    public MyView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    private int mLastX;
    private int mLastY;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getRawX();
        int y = (int) event.getRawY();
        //动画实现移动代码
        //--------------------------------------------------
//        switch (event.getAction()) {
//            case MotionEvent.ACTION_DOWN:
//
//                break;
//            case MotionEvent.ACTION_MOVE:
//                int delaltax = x - mLastX;
//                int delaltaY = y - mLastY;
//                float tranX = getTranslationX() + delaltax;
//                float tranY = getTranslationY() + delaltaY;
//                setTranslationX(tranX);
//                setTranslationY(tranY);
//                break;
//            case MotionEvent.ACTION_UP:
//
//                break;
//            default:
//                break;
//        }
        //-----------------------------------------------

        //layout方法实现
//        switch (event.getAction()) {
//            case MotionEvent.ACTION_DOWN:
//                break;
//            case MotionEvent.ACTION_MOVE:
//                //计算偏移量
//                int offsetX = x - mLastX;
//                int offsetY = y - mLastY;
//                //重新布局
//                layout(getLeft() + offsetX, getTop() + offsetY,
//                        getRight() + offsetX, getBottom() + offsetY);
//                //也可以使用下面这种方法
////                offsetLeftAndRight(offsetX);
////                offsetTopAndBottom(offsetY);
//                break;
//            case MotionEvent.ACTION_UP:
//                break;
//            default:
//                break;
//        }
        //---------------------------------------------

        //LayoutParams方法
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                break;
            case MotionEvent.ACTION_MOVE:
                int offsetX = x - mLastX;
                int offsetY = y - mLastY;
                //示例代码的父View是LinearLayout
                LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) getLayoutParams();
                layoutParams.leftMargin = getLeft() + offsetX;
                layoutParams.topMargin = getTop() + offsetY;
                //下面这两句都可以使用,setLayoutParams也会调用requestLayout
                //                setLayoutParams(layoutParams);
                requestLayout();
                break;
            case MotionEvent.ACTION_UP:
                break;
            default:
                break;
        }

        mLastX = x;
        mLastY = y;
        return true;
    }
}