文章目录
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()