Android开发Android开发经验谈Android技术知识

Android开发艺术笔记 | View的滑动(三种普遍实现方式

2020-03-23  本文已影响0人  凌川江雪

滑动在Android开发中具有很重要的作用,
不管一些滑动效果多么绚丽,
归根结底,它们都是由不同的滑动外加一些特效所组成的。
因此,掌握滑动的方法是实现绚丽的自定义控件的基础。

The 1. 使用scrollTo/scrollBy

View提供了专门的方法来实现滑动
scrollTo()scrollBy(),这两个方法的实现如下:

    /**
      * Set the scrolled position of your view. This will cause a call to
      * {@link #onScrollChanged(int,int,int,int)} and the view will be
      * invalidated.
      * @param x the x position to scroll to
      * @param y the y position to scroll to
      */
    public void scrollTo(int x,int y) {
        if (mScrollX != x || mScrollY != y) {
                int oldX = mScrollX;
                int oldY = mScrollY;
                mScrollX = x;
                mScrollY = y;
                invalidateParentCaches();
                onScrollChanged(mScrollX,mScrollY,oldX,oldY);
                if (!awakenScrollBars()) {
                        postInvalidateOnAnimation();
                }
        }
    }
     /**
      * Move the scrolled position of your view. This will cause a call to
      * {@link #onScrollChanged(int,int,int,int)} and the view will be
      * invalidated.
      * @param x the amount of pixels to scroll by horizontally
      * @param y the amount of pixels to scroll by vertically
      */
    public void scrollBy(int x,int y) {
        scrollTo(mScrollX + x,mScrollY + y);
    }

The 2. 使用动画

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:fillAfter="true"
         android:zAdjustment="normal" >
         <translate
             android:duration="100"
             android:fromXDelta="0"
             android:fromYDelta="0"
             android:interpolator="@android:anim/linear_interpolator"
             android:toXDelta="100"
             android:toYDelta="100" />
    </set>
ObjectAnimator.ofFloat(targetView,"translationX",0,100).setDuration(100).start();

The 3. 改变布局参数

MarginLayoutParams params = (MarginLayoutParams)mButton1.getLayoutParams();
params.width += 100;
params.leftMargin += 100;
mButton1.requestLayout();//或mButton1.setLayoutParams(params);

各种滑动效果实现方式的对比

The 1. scrollTo/scrollBy:

The 2. 动画:

The 3. 改变布局参数

实战

The 1. scrollTo/scrollBy

public class DragView4 extends View {

    private int lastX;
    private int lastY;

    public DragView4(Context context) {
        super(context);
        ininView();
    }

    public DragView4(Context context, AttributeSet attrs) {
        super(context, attrs);
        ininView();
    }

    public DragView4(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        ininView();
    }

    private void ininView() {
        setBackgroundColor(Color.BLUE);
    }

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

The 2. 动画

或参考以下博客:

The 3. 改变布局参数

public class DragView3 extends View {

    private int lastX;
    private int lastY;

    public DragView3(Context context) {
        super(context);
        ininView();
    }
    public DragView3(Context context, AttributeSet attrs) {
        super(context, attrs);
        ininView();
    }
    public DragView3(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        ininView();
    }

    private void ininView() {
        setBackgroundColor(Color.BLUE);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // 记录触摸点坐标
                lastX = (int) event.getX();
                lastY = (int) event.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                // 计算偏移量
                int offsetX = x - lastX;
                int offsetY = y - lastY;

                ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) getLayoutParams();
//                LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) getLayoutParams();
                layoutParams.leftMargin = getLeft() + offsetX;
                layoutParams.topMargin = getTop() + offsetY;
                setLayoutParams(layoutParams);
                break;
        }
        return true;
    }
}
上一篇 下一篇

猜你喜欢

热点阅读