美文网首页Android自定义View
实现View滑动的6种方式

实现View滑动的6种方式

作者: Doikki | 来源:发表于2018-05-04 20:31 被阅读32次
  • layout()方法
    View进行绘制的时候会调用onLayout()方法来设置现实的位置,因此我们同样也可以通过修改View的left、top、right、bottom这4个属性来控制View的坐标。首选我们需要自定义一个View,在onTouchEvent()方法中获取触摸点的坐标,接下来我们在ACTION_MOVE事件中计算偏移量,再调用layout()方法重新放置控件的位置即可,代码如下所示:
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()方法来重新放置控件的位置
            layout(getLeft() + offsetX, getTop() + offsetY,
                    getRight() + offsetX, getBottom() + offsetY);
            break;
    }
    return true;
}
  • offsetLeftAndRight()与offsetTopAndBottom()
    这种方法和上面的layout()方法差不多。我们将ACTION_MOVE中的代码替换成如下代码即可得到我们想要的效果。
case MotionEvent.ACTION_MOVE:
    //计算移动的距离
    int offsetX = x - lastX;
    int offsetY = y - lastY;
    offsetLeftAndRight(offsetX);
    offsetTopAndBottom(offsetY);
    break;
  • LayoutParams(改变布局参数)
    LayoutParams主要保存了一个View的布局参数,因此我们可以通过LayoutParams来改变View的布局参数从而达到改变View位置的效果。同样,将ACTION_MOVE中的代码替换成如下代码:
case MotionEvent.ACTION_MOVE:
    //计算移动的距离
    int offsetX = x - lastX;
    int offsetY = y - lastY;
    LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) getLayoutParams();
    layoutParams.leftMargin = getLeft() + offsetX;
    layoutParams.topMargin = getTop() + offsetY;
    setLayoutParams(layoutParams);
    break;

因为父控件是LinearLayout,所以我们使用了LinearLayout.LayoutParams。如果父控件是RelativeLayout,则要使用RelativeLayout.LayoutParams。除了使用布局的LayoutParams外,我们还可以使用ViewGroup.MarginLayoutParams来实现:

case MotionEvent.ACTION_MOVE:
    //计算移动的距离
    int offsetX = x - lastX;
    int offsetY = y - lastY;
    ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) getLayoutParams();
    layoutParams.leftMargin = getLeft() + offsetX;
    layoutParams.topMargin = getTop() + offsetY;
    setLayoutParams(layoutParams);
    break;
  • 动画
    可以采用动画来移动,在res目录新建anim文件夹并创建anim_translate.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fillAfter="true">
    <translate
        android:fromXDelta="0"
        android:toXDelta="300" />
</set>

接下来在Java代码中调用:

mCustomView.setAnimation(AnimationUtils.loadAnimation(this, R.anim.anim_translate));

运行程序,控件会向右平移300个像素,并停留在当前位置。
需要注意的是View动画并不能改变View的位置参数。如果对控件设置一个点击事件,此时对控件执行如上操作,点击控件停留的位置并不会触发点击事件,但我们点击控件初始位置却触发了点击事件。对于系统来说这个控件并没有改变原有的位置,所以就出现上述问题。在Android3.0的时候推出的属性动画可以解决上述问题,它不仅执行了动画,还改变了控件的位置参数。代码如下:

ObjectAnimator.ofFloat(mCustomView, "translationX", 0, 300).setDuration(1000).start();
  • scrollTo与scrollBy
    scrollTo(x,y)表示移动到一个具体的坐标点,而scrollBy(dx,dy)则表示移动的增量为dx,dy。其中,scrollBy最终也是要调用scrollTo的。scrollTo与scrollBy移动的是View的内容,如果在ViewGroup中使用,则是移动其所有的子View。我们将ACTION_MOVE中的代码替换成如下代码:
case MotionEvent.ACTION_MOVE:
    //计算移动的距离
    int offsetX = x - lastX;
    int offsetY = y - lastY;
    ((View)getParent()).scrollBy(-offsetX, -offsetY);
    break;
  • Scroller
    我们在用scrollTo/scrollBy方法进行滑动时,这个过程是瞬间完成的,所以用户体验不太好,这里我们可以使用Scroller来实现过渡效果。Scroller本身是不能滑动的,它需要与View的computeScroll()方法配合才能实现弹性滑动效果。这里我们演示一下把控件向右移动400个像素,代码如下:
public class CustomView extends View {
    public CustomView(Context context) {
        super(context);
    }

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

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

    private Scroller mScroller;

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

    public void smoothScrollTo(int destX, int destY) {
        int scrollX = getScrollX();
        int delta = destX - scrollX;
        mScroller.startScroll(scrollX, 0, delta, 0, 2000);
        invalidate();
    }
}

最后我们在activity中调用smoothScrollTo()方法:

mCustomView.smoothScrollTo(-400, 0);

相关文章

  • View的滑动

    常见的View滑动方式: 通过View本身提供的scrollTo/scrollBy方法实现滑动 通过动画实现Vie...

  • View滑动

    通过三种方式可以实现View的滑动: 通过View本身提供的scrollTo/scrollBy方法来实现滑动操作简...

  • Android View的滑动和滑动冲突

    一、View的滑动 可以通过三种方式实现滑动。 通过View本身提供的scrollTo和scrollBy方法来实现...

  • View的滑动

    一、实现View滑动的方式 offsetLeftAndRight() 和 offsetTopAndBottom()...

  • Android 开发艺术探索笔记(九) 之 View 的滑动

    View 的滑动主要有 3 种方式: 1.通过 View 本身的 scrollTo/scrollBy 方法实现滑动...

  • View的事件体系(二)View的滑动

    可通过三种方式实现View的滑动: 1、通过View本身提供的scrollTo/scrollBy方法来实现滑动 2...

  • Android View的滑动详解

    View的滑动 View的滑动主要有三种方式: 通过view本身提供的scrollTo/scrollBy方法来实现...

  • 弹性滑动

    3.3 弹性滑动 知道了View的滑动,我们还要知道如何实现View的弹性滑动,比较生硬的滑动过去,这种方式的用户...

  • View弹性滑动实现

    背景 最近在学习View的弹性滑动,View的弹性滑动有三种实现方式:1.Scroller实现2.动画实现3.延时...

  • Android View的事件体系(三) 弹性滑动

    弹性滑动 知道了View的滑动,我们还要知道如何实现View的弹性滑动,比较生硬的滑动过去,这种方式的用户体验实在...

网友评论

    本文标题:实现View滑动的6种方式

    本文链接:https://www.haomeiwen.com/subject/jiqrrftx.html