Android View的滑动

View的滑动

概述

View滑动的思想类似,当触摸事件传到View时,记录触摸点到坐标,标记手指移动后到触摸的坐标,并计算出偏移量,通过偏移量修改View的坐标。

实现View的滑动通常有六种方法:layout()、offsetLeftAndRight()和offsetTopAndBottom()、LayoutParams、动画、scollTo和scollBy()、Scroller。

layout()

通过layout()修改View的left top right bottom坐标实现滑动效果。

package com.example.viewslidedemo.sample1;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Scroller;

import androidx.annotation.Nullable;

public class MyView extends View {
    
    
    private int lastX;
    private int lastY;
    private Scroller mScroller;

    public MyView(Context context) {
    
    
        this(context, null);
    }

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

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

    @Override
    public boolean onTouchEvent(MotionEvent event) {
    
    
        int x = (int) event.getX();
        int y = (int) event.getY();
        switch (event.getAction()) {
    
    
            case MotionEvent.ACTION_DOWN:
                lastX = x;
                lastY = y;
                break;
            case MotionEvent.ACTION_MOVE:
                int offsetX = x - lastX;
                int offsetY = y - lastY;

                layout(getLeft() + offsetX, getTop() + offsetY, getRight() + offsetX, getBottom() + offsetY);
                break;
        }
        return true;
    }
}

offsetLeftAndRight和offsetTopAndBottom

layout()类似。

offsetLeftAndRight(offsetX);
offsetTopAndBottom(offsetY);

scrollTo和scrollBy

  • scollTo()表示移动到具体的坐标点。
  • scrollBy()表示移动的增量为offsetX、offsetY。
((View) getParent()).scrollBy(-offsetX, -offsetY);

Scroller

可以通过Scroller类实现平滑移动。

private Scroller mScroller;

public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    
    
    mScroller = new Scroller(context);
}

/**
     * @param dx       x轴移动距离
     * @param dy       y轴移动距离
     * @param duration 持续时间
     */
public void smoothScrollTo(int dx, int dy, int duration) {
    
    
    int scrollX = getScrollX();
    int scrollY = getScrollY();
    mScroller.startScroll(scrollX, scrollY, dx, dy, duration);
    invalidate();
}

@Override
public void computeScroll() {
    
    
    super.computeScroll();
    if (mScroller.computeScrollOffset()) {
    
    
        ((View) getParent()).scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
        invalidate();
    }
}
  myView.smoothScrollTo(-300, -300, 1000)

LayoutParams

通过LayoutParams可以设置宽高和外边距实现View的滑动效果。

FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) getLayoutParams();
params.leftMargin = getLeft() + offsetX;
params.topMargin = getTop() + offsetY;
setLayoutParams(params);

动画

使用动画移动View。

补间动画

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
     android:fillAfter="true">
    <translate
               android:duration="1000"
               android:fromXDelta="0"
               android:toXDelta="300" />
</set>
myView.startAnimation(AnimationUtils.loadAnimation(context, R.anim.anim_translate))

属性动画

ObjectAnimator.ofFloat(myView, "translationX", 0, 300).setDuration(1000).start()

猜你喜欢

转载自blog.csdn.net/qq_14876133/article/details/113576277
今日推荐