Android动画--移动View的几种方式

原创 2015年11月19日 23:54:10

— Android群英传读书笔记

概述


View位置的变化和触控操作都涉及到MotionEvent类,MotionEvent中封装了一些与触摸相关的东西,比如触摸事件Action,触摸坐标等。移动View无疑就是改变其位置,通常有以下几种方式。

layout


View 类中,我们知道有一个layout方法是给View定位的 ,结合onTouchEvent方法 ,我们可以很好的实现一个View的移动.

int lastX, lastY;

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        int rawX = (int) event.getRawX();
        int rawY = (int) event.getRawY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:

                lastX = rawX;
                lastY = rawY;

                break;

            case MotionEvent.ACTION_MOVE:

                int offsetX = rawX - lastX;
                int offsetY = rawY - lastY;

                 layout(getLeft()+offsetX,
                 getTop()+offsetY,
                 getRight()+offsetX,
                 getBottom()+offsetY);

                lastX = rawX;
                lastY = rawY;

                break;
        }

        return true;
    }

这里面使用了绝对坐标,使用绝对坐标的时候,需要在每次ACTION_MOVE后重新设置初始坐标.

offsetLeftAndRight()


使用offsetLeftAndRight();offsetTopAndBottom();方法,通过设置偏移量来滑动View


    int lastX, lastY;

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        int rawX = (int) event.getRawX();
        int rawY = (int) event.getRawY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:

                lastX = rawX;
                lastY = rawY;

                break;

            case MotionEvent.ACTION_MOVE:

                int offsetX = rawX - lastX;
                int offsetY = rawY - lastY;

                //layout(getLeft()+offsetX,
                // getTop()+offsetY,
                // getRight()+offsetX,
                // getBottom()+offsetY);

                offsetLeftAndRight(offsetX);
                offsetTopAndBottom(offsetY);
                lastX = rawX;
                lastY = rawY;

                break;
        }

        return true;
    }

过offset值改变View的getTop()、getBottom(),getRight(),getLeft()的值

LayoutParams


LayoutParams,使用LayoutParams滑动View,通过改变布局参数来达到滑动View的目的.

 int lastX, lastY;

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        int rawX = (int) event.getRawX();
        int rawY = (int) event.getRawY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:

                lastX = rawX;
                lastY = rawY;

                break;

            case MotionEvent.ACTION_MOVE:

                int offsetX = rawX - lastX;
                int offsetY = rawY - lastY;

                // layout(getLeft()+offsetX,
                // getTop()+offsetY,
                // getRight()+offsetX,
                // getBottom()+offsetY);

//                offsetLeftAndRight(offsetX);
//                offsetTopAndBottom(offsetY);

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

                lastX = rawX;
                lastY = rawY;

                break;
        }

        return true;
    }

ScrollTo() ScrollBy()


使用ScrollTo() 和ScrollBy() 方法来改变View 的位置.


    int lastX, lastY;

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        int rawX = (int) event.getRawX();
        int rawY = (int) event.getRawY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:

                lastX = rawX;
                lastY = rawY;

                break;

            case MotionEvent.ACTION_MOVE:

                int offsetX = rawX - lastX;
                int offsetY = rawY - lastY;

                // layout(getLeft()+offsetX,
                // getTop()+offsetY,
                // getRight()+offsetX,
                // getBottom()+offsetY);

//                offsetLeftAndRight(offsetX);
//                offsetTopAndBottom(offsetY);

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

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

                lastX = rawX;
                lastY = rawY;

                break;
        }

        return true;
    }

这里需要注意的是
1.首先我们的ScrollTo() and ScrollBy()方法移动的是View的Content
2.我们移动的是画布,因此需要设置相反的值,才能让View 跟随手指移动.

Scroller


使用Scroller类来移动View,与ScrollBy()方法关系紧密,ScrollBy()移动是瞬时完成,Scroller类在ACTION_MOVE中对偏移量进行划分,达到平滑效果.我们需要三个步骤.

 mScroller = new Scroller(context);
@Override
    public void computeScroll() {
        super.computeScroll();
        if (mScroller.computeScrollOffset()) {
            ((View) getParent()).scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            invalidate();
        }
    }
 case MotionEvent.ACTION_UP:

                ViewGroup viewGroup = (ViewGroup) getParent();         mScroller.startScroll(viewGroup.getScrollX(),viewGroup.getScrollY(),-viewGroup.getScrollX(),-viewGroup.getScrollY());

                invalidate();

                break;

computeScroll判断是否滑动结束,进而进行滑动,之后通过invalidate()刷新界面调用onDraw方法

Property Animation


通过 属性动画对View位置对改变

        int w = text.getWidth();
        int screenW = UiUtil.getScreenWidth();
        int transX = screenW - w;
        ObjectAnimator transAnim = ObjectAnimator.ofFloat(text, "translationX", 0, transX);

ViewDragHelper


使用v4包中的ViewDragHelper能很好的实现View的滑动和事件分发,典型谷歌官方的 Drawerlayout

ViewDragHelper封装了滚动操作,其内部使用了Scroller,关于ViewDragHelper的介绍网上也很多,重要的就是其内部类ViewDragHelper.callback,我们只需要按需复写即可.

实例:ViewDragHelper实现QQ侧滑效果DragLayout[github]

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

Android View 移动的几种方式

layout()如果你将滑动后的目标位置的坐标传递给layout(),这样子就会把view的位置给重新布置了一下,在视觉上就是view的一个滑动的效果。public class DragView ex...
  • a15286856575
  • a15286856575
  • 2016年03月17日 16:12
  • 2328

Android移动view动画问题 关于view的位置移动了,但view里面绑定的监听器还在原位

Android移动view动画问题 Android写动画效果不是一般的麻烦,网上找了好久,终于解决了动画的问题,总结记录以共勉。 仅以水平方向移动效果做说明,垂直方向类似。   完整动...
  • hzc543806053
  • hzc543806053
  • 2013年01月20日 18:56
  • 15881

android移动View位置(动画)

项目中运用到移动View位置,向使得移动过程更加鲜活一些,使用到动画并做记录小结: 创建并绑定动画到指定View,动画播放结束后如果需要停留在移动后的位置,那么设置View的位置; /** ...
  • lifuzl1
  • lifuzl1
  • 2015年11月12日 10:48
  • 1237

android view 的移动的几种方式

在android开发中,经常会遇到一个view需要它能够支持滑动的需求。下面通过本篇文章给大家介绍android view移动的六种方法。 layout() 如果你将滑动后的目标位置的坐标传递给la...
  • Deaht_Huimie
  • Deaht_Huimie
  • 2016年10月16日 22:56
  • 134

Android View 移动的几种方式

layout()如果你将滑动后的目标位置的坐标传递给layout(),这样子就会把view的位置给重新布置了一下,在视觉上就是view的一个滑动的效果。public class DragView ex...
  • a15286856575
  • a15286856575
  • 2016年03月17日 16:12
  • 2328

Android实战之 SlidingMenu视觉差动画简单版和Activity视觉差动画+自定义View实现仿系统DrawerLayout覆盖型菜单几种方式

Android实战之 SlidingMenu视觉差动画简单版和Activity视觉差动画+自定义View实现仿系统DrawerLayout覆盖型菜单几种方式...
  • gaolei1201
  • gaolei1201
  • 2015年12月25日 19:48
  • 2059

Android移动view动画问题

Android写动画效果不是一般的麻烦,网上找了好久,终于解决了动画的问题,总结记录以共勉。 仅以水平方向移动效果做说明,垂直方向类似。 完整动画函数代码:  public void...
  • ljb_blog
  • ljb_blog
  • 2013年08月23日 14:38
  • 7860

android移动View位置(动画)

项目中运用到移动View位置,向使得移动过程更加鲜活一些,使用到动画并做记录小结: 创建并绑定动画到指定View,动画播放结束后如果需要停留在移动后的位置,那么设置View的位置; /** ...
  • lifuzl1
  • lifuzl1
  • 2015年11月12日 10:48
  • 1237

android任意view移动缩放至消失到任何位置的通用动画

要求将界面中显示的任意一个view(已经Measure好了)缩放移动到任意位置直至消失可以用图片这样描述: 实现思路:使用系统缩放动画ScaleAnimation进行缩放和移动,缩放倍数和移动距离根...
  • u010499721
  • u010499721
  • 2016年02月18日 11:48
  • 1899

Android移动view动画问题

Android写动画效果不是一般的麻烦,网上找了好久,终于解决了动画的问题,总结记录以共勉。 仅以水平方向移动效果做说明,垂直方向类似。 完整动画函数代码: public void slid...
  • hjysmi
  • hjysmi
  • 2015年05月13日 09:36
  • 309
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android动画--移动View的几种方式
举报原因:
原因补充:

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