实现View滑动的七种方式记录

原创 2017年01月03日 20:22:46

实现View滑动的七种方式记录

效果图:由于每种实现方式的效果基本上是一模一样的,所以只演示一个效果图

实现方式都是采用自定义View的方法,监听onTouchEvent方法,计算位移,然后采用不同的方式来将View进行位移

一 . layout方法

实现原理:

View在其父组件的位置是由父组件的onLayout方法确定的,其实View本身也可以通过相同的方法确定本身的位置,这个方法就是layout,参数与onLayout一样。而View当前的坐标可由getLeft,getTop,getRight,getBottom来确定,再加上偏移值即可确定滑动之后的位置。

onTouchEvent方法实现代码

private int mLastX = 0;
    private int mLastY = 0;
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                //记住开始时候的坐标
                mLastX = x;
                mLastY = y;
                break;
            case MotionEvent.ACTION_MOVE:
                //获取坐标偏移值
                int offsetX = x - mLastX;
                int offsetY = y - mLastY;
                layout(getLeft() + offsetX, getTop() + offsetY, getRight() + offsetX, getBottom() + offsetY);
                break;
        }
        return true;
    }

二.offsetLeftAndRight()``和offsetTopAndBottom()“方法

此方法相当于对layout方法的方向上的封装,实现原理与第一种方式一样,直接贴代码:

private int mLastX = 0;
    private int mLastY = 0;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mLastX = x;
                mLastY = y;
                break;
            case MotionEvent.ACTION_MOVE:
                int offsetX = x - mLastX;
                int offsetY = y - mLastY;
                offsetLeftAndRight(offsetX);
                offsetTopAndBottom(offsetY);
                break;
        }
        return true;
    }

三 .LayoutParams方法

LayoutParams保存的是View的布局参数,因此可以通过改变LayoutParams的参数来改变View的位置。原理与第一种方法一样,不同的只是对偏移量的处理,处理偏移量的代码如下:

ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) getLayoutParams();
params.leftMargin = getLeft() + offsetX;
params.topMargin = getTop() + offsetY;
setLayoutParams(params);

四.scrollTo , scrollBy方法

scrollTo()``所需要的参数是要滚动到位置的绝对坐标,scrollBy()`所需参数是与当前坐标的偏移坐标。但是这种方式作用的对象不是View`本身,而是其父组件,并且父组件移动的方式与View的方式不一样,因为当父组件移动的时候,其内部的其他View也是在一起移动的,所以想使View向右移动的话需要将父组件向左移动,上下移动也是一样的。

处理坐标偏移量的代码:

 ((View) getParent()).scrollBy(-offsetX, -offsetY);

五.Scroller方法

Scroller能实现平滑移动的效果,所以这个例子实现的是手指拖动来移动,然后松开手指的时候平滑移动到原本的位置,与scrollTo方法一样,Scroller作用的也是其父组件。

Scroller的使用步骤:

1.初始化Scroller

mScroller = new Scroller(context);

2.重写computeScroll()``方法,实现方式还是父组件的scrollTo方法,但是可以通过Scroller获取当前应该移动到的坐标点,移动之后需要调用重绘,因为computeScroll方法只会在onDraw()内被调用,当Scroller`判断移动完毕的时候就会停止移动。

@Override
    public void computeScroll() {
        super.computeScroll();
        if (mScroller.computeScrollOffset()) {
            View parent = (View) getParent();
            parent.scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            //通过重绘来不断调用computeScroll
            invalidate();
        }
    }

3.开启滚动:

开启滚动的方法如下:

public void startScroll(int startX , int startY , int dx , int dy , int duration);
public void startScroll(int startX , int startY , int dx , int dy );

参数分别为:当前X上的滚动值,当前Y上的滚动值,要滚动的X上的偏移值,要滚动的Y上的偏移值,滑动持续的时间。

View滚动到原本的位置的代码:

case MotionEvent.ACTION_UP:
                View parent = (View) getParent();
                mScroller.startScroll(parent.getScrollX(), parent.getScrollY() ,- parent.getScrollX(), -parent.getScrollY(),2500);
                //激活滑动操作
                invalidate();
                break;

六.属性动画

效果图:

这个不用多说,不能像之前一样随手指一动(就算可以实现我想应该没人会这样做),演示效果是点击View之后View自动平滑的向下移动。

动画xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:fromXDelta="0%"
        android:fromYDelta="0%"
        android:toXDelta="60%p"
        android:toYDelta="60%p"/>
</set>

动画的使用代码:

mView.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               Animation animation = AnimationUtils.loadAnimation(mContext, R.anim.trans_back);
               animation.setDuration(2500);
               mView.startAnimation(animation);
           }
       });

七.ViewDragHelper方法

ViewDragHelper在自定义ViewGroup中应用很多,功能非常强大,官方的DrawerLayoutSlidePaneLayout就主要是ViewDragHelper实现的。

本次实现的效果还是跟随手指移动,是自定义ViewGroup。步骤如下:

Activity的布局中会在这个ViewGroup中添加一个View用于演示滑动,在开始以下步骤之前进行其他处理,如View的位置和初始化等的。

1.初始化ViewDrahHelper

mHelper = ViewDragHelper.create(this, new ViewDragHelper.Callback() {
            //决定那个View参与滑动
            @Override
            public boolean tryCaptureView(View child, int pointerId) {
                return child == mView;
            }
            //指定当滑动的坐标变化的时候要滑动的View在X坐标上应该怎么样变化
            @Override
            public int clampViewPositionVertical(View child, int top, int dy) {
                return top;
            }
            //指定当滑动的坐标变化的时候要滑动的View在Y坐标上应该怎么样变化
            @Override
            public int clampViewPositionHorizontal(View child, int left, int dx) {
                return left;
            }
        });

2.拦截事件

@Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return mHelper.shouldInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mHelper.processTouchEvent(event);
        return true;
    }

3.处理computeScroll

@Override
    public void computeScroll() {
        if (mHelper.continueSettling(true)) {
            ViewCompat.postInvalidateOnAnimation(this);
        }
    }

完毕。

ViewGroup的完整代码

public class MethodView7 extends ViewGroup {
    private View mView;
    private ViewDragHelper mHelper;

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

    public MethodView7(Context context, AttributeSet attrs) {
        super(context, attrs);
        mHelper = ViewDragHelper.create(this, new ViewDragHelper.Callback() {
            @Override
            public boolean tryCaptureView(View child, int pointerId) {
                return child == mView;
            }

            @Override
            public int clampViewPositionVertical(View child, int top, int dy) {
                return top;
            }

            @Override
            public int clampViewPositionHorizontal(View child, int left, int dx) {
                return left;
            }
        });
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        mView = getChildAt(0);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return mHelper.shouldInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mHelper.processTouchEvent(event);
        return true;
    }

    @Override
    public void computeScroll() {
        if (mHelper.continueSettling(true)) {
            ViewCompat.postInvalidateOnAnimation(this);
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        mView.layout(16, 16,  216, 216);
    }
}

七种方法完毕.

Demo地址

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

View滑动的七种方法

最近总是感觉自己力不从心,好多都不会啊,都不会,所以想从基础学起一些东西,总结一下自定义view滑动的方式。这里以可以随手指滑动的textview 为例子: 上效果图:直接上源码: 第一种方式:p...

Android-实现View滑动的6种方式

Android实现view滑动的6中方式

Android面试整理之UI部分——实现View的弹性滑动的三种方式(一)

一.使用Scroller   1.为什么有弹性滑动的需求?    用View提供的原生方法scrollTo/scrollBy,虽然是专用于View的滑动,操作简单,能比较方便地实现滑动效果并且不影响内...

滑动效果的七种方式

滑动效果的产生滑动一个view,本质上就是说移动一个view。改变其当前所处的位置,他的原则与动画效果的实现非常相似,都是通过不断地改变view的坐标来实现这一效果。因此,要实现view滑动,就必须监...

View 的滑动原理和实现方式

开发中,为了增加更多炫丽的效果,我们经常在应用中添加滑动效果,今天就来分析一下 View 中滑动效果的实现原理以及几种常见的实现方式。一、滑动原理1. Android 中的坐标系在 View 基础 中...

Android面试整理之UI部分——实现View的弹性滑动的三种方式(二)

上次讲述了Scroller,今天继续整理View的另外两种弹性滑动方式,并对三种方式加以总结对比异同点。 一.利用动画特性实现类似于Scroller的弹性滑动效果 1.如何用动画实现滑动?   ...

view的其中滑动方式源码

  • 2017-01-15 11:32
  • 38KB
  • 下载

七种不同的tab实现方式

  • 2015-08-06 17:36
  • 517KB
  • 下载

Android自定义View你所要知道的(三):View滑动实现方式

滑动,让用户体验更加友好。与用户交互时让整个界面都多了一分灵性。这篇文章从View滑动三种的实现方式,来做简要的分析。 一丶scrollTo/scrollBy scrollTo和scrollB...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)