Android View滑动进阶

package com.example.view;

import android.animation.ObjectAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.Scroller;

import androidx.annotation.Nullable;

public class CoustomView extends View {
    private int mLastX;//用来标记起始点x
    private int mLastY;//用来标记起始点y
    private Scroller scroller;
    public CoustomView(Context context) {
        this(context,null);
    }

    public CoustomView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CoustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        scroller = new Scroller(context);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getX();//这是相对与当前view的父容器的水平坐标
        int y = (int) event.getY();//这是相对与当前view的父容器的垂直坐标
        switch (event.getAction()){
            //根据event的类型来判断如何处理
            case MotionEvent.ACTION_DOWN:
                mLastX = x;
                mLastY = y;
                //当点击的一瞬间,记录起始位置
                break;
             case MotionEvent.ACTION_MOVE:
                 //当发生滑动事件如何处理
                 //我们希望当前的view能跟随我们的滑动轨迹一起滑动
                 int deltaX = x-mLastX;//当前手指所指向的坐标减去起始坐标的水平方向的偏移量;
                 int deltaY = y-mLastY;//当前手指所指向的坐标减去起始坐标的垂直方向的偏移量;

                 //1.layout(getLeft()+deltaX,getTop()+deltaY,getRight()+deltaX,getBottom()+deltaY);      //getLeft 等是绝对坐标系

                 //2.offsetLeftAndRight(deltaX);//水平偏移
                 //  offsetTopAndBottom(deltaY);//垂直偏移

                 //3.LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) getLayoutParams(); //设置params
                 //  params.leftMargin+=deltaX;
                 //  params.topMargin+=deltaY;
                 //  setLayoutParams(params);

                 //4.((View) getParent()).scrollBy(-deltaX, -deltaY);//通过scrollBy移动的是View的Content,那么我们要移动控件,就必须要直到当前控件属于哪个view
                 //的内容,这样才能移动控件

                 //5.smoothScroller(-deltaX,-deltaY);//通过Scroller实现弹性滑动

                 //6.使用动画
                 ObjectAnimator.ofFloat(this,"translationX",mLastX,deltaX).setDuration(500).start();
                 ObjectAnimator.ofFloat(this,"translationY",mLastY,deltaY).setDuration(500).start();
                 break;
        }
        return true;
    }

    private void smoothScroller(int dx, int dy) {
                scroller.startScroll(scroller.getFinalX(), scroller.getFinalY(), dx,dy,500);
        invalidate();
    }

    @Override
    public void computeScroll() {
        super.computeScroll();
        //调用重新绘制时这个方法会被执行
        if(scroller.computeScrollOffset()){
            //判断滑动是否执行完毕
            //没有执行完毕就继续执行
            ((View) getParent()).scrollTo(scroller.getCurrX(), scroller.getCurrY());
            invalidate();
        }
    }
}

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:id="@+id/line1"
    android:background="@color/colorPrimaryDark"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ViewActivity">
    <com.example.view.CoustomView
        android:id="@+id/cv"
        android:layout_marginLeft="20px"
        android:background="@color/colorAccent"
        android:layout_width="100px"
        android:layout_height="100px"/>
</LinearLayout>

六种滑动方式,其中只有属性动画改变了View的真实属性。其他的只是改变了位置。
详情请参考View滑动

猜你喜欢

转载自blog.csdn.net/weixin_43927892/article/details/105597739