实现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滑动效果的七种实现方式

关于android中可以滑动的控件可以说数不胜数,而同一个效果的实现方式也是非常多的,今天先用最简单的几种方式来感受下自定义控件滑动效果的产生,先上效果图布局都是一样的 ...
  • zly921112
  • zly921112
  • 2015年12月30日 18:06
  • 2476

七种排序的实现

1. 冒泡排序 2. 选择排序 3. 快速排序 4. 归并排序 5. 插入排序 6. 希尔排序 7. 堆排序...
  • ggmfengyangdi
  • ggmfengyangdi
  • 2016年07月20日 21:52
  • 574

View滑动的七种方法

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

Android实现滑动的七种方法

Android群英传第五章 实现滑动的七种方法简要笔记
  • afei__
  • afei__
  • 2016年07月27日 16:26
  • 946

滑动效果的七种方式

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

Android中实现View滑动的几种方式

view滑动
  • sinat_31057219
  • sinat_31057219
  • 2017年01月06日 11:17
  • 363

Android Scroller类详解--实现View内容弹性滑动

概述Scroller类封装了滚动,我们可以使用Scroller 类来收集滑动动画过程中的数据,例如为了响应快速滚动动画。当View的位置发生变化的时候,Scroller会自动追踪scrollX 和sc...
  • hpk1994
  • hpk1994
  • 2016年04月22日 22:26
  • 515

Android自定义View之仿知乎滑动删除Activity

先看下具体的实现效果: 上面图片里包含两种效果,一个是向右滑动删除Activity,这个大家可以参考夏神的文章http://blog.csdn.net/xiaanming/article/detai...
  • happy_horse
  • happy_horse
  • 2016年05月16日 19:07
  • 1171

Android实现滑动的几种方法

下面通过一个例子来总结实现滑动的几种方式,例子的主要功能就是让我们的自定义View能够随着手指的移动而移动。 布局文件如下: ...
  • shakespeare001
  • shakespeare001
  • 2016年06月13日 15:17
  • 10300

实现view跟着手指滑动的效果(实现方式三)

第三种方式就是通过改变LayoutParams的方式实现该效果(这种方法是整个父布局跟着一起动) 我们都知道LayoutParams保存了一个view的布局参数。因此可以在程序中,通过改变Layou...
  • sweetzhangxue
  • sweetzhangxue
  • 2016年11月22日 17:17
  • 314
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:实现View滑动的七种方式记录
举报原因:
原因补充:

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