实现View 滑动的几种方法

时间过得真快,一转眼就要到10月了,这几天风刮的厉害,气温骤降,看来秋天真的要来了!

今天我主要是给大家讲一些实现View平滑的移动的方法,View 平滑移动的方法一般有一下三种:

1.通过View 本身提供的scrollTo / scrollBy 方法实现滑动

2.通过动画给View施加平移效果来实现滑动

3.通过改变View 的LayoutParams 使得重新布局从而实现滑动


1.ScrollTo() / ScrollBy() 方法实现滑动

scrollTo(int destX,int destY) / scrollBy(int deltaX,int deltaY) 这两个方法是在View 下的,所以android中只要是集成View的皆可使用这种方法实现平滑移动。ScrollTo是基于参数的绝对的滑动,ScrollBy则是相对滑动。在View中源代码如下:

 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();
            }
        }
    }
 public void scrollBy(int x, int y) {
        scrollTo(mScrollX + x, mScrollY + y);
    }
可以看到ScrollBy 内部调用的是ScrollTo方法,由于scrollBy是相对对标,所以需要加上mScrollX 和 mScrollY. 要获取mScrollX 和 mScrollY 可通过  getScrollX() 和 getScrollY() 实现。那么什么是scrollX,scrollY呢? 首先需要明白的一点:ScrollTo / scrollBy 这个两个方法只是移动View 内部的内容而不是View 本身。举个例子ScrollView, 当我们在滑动ScrollView的时候ScrollView 本身这个View 并没有发送位置或者大小上的任何改变,改变的只是ScrollView 内部的内容区域。

mScrollX 始终等于View的左边缘 - View的内容区域左边缘,如果水平从左向右滑动的话mScrollX 为负值,反之为正值
mScrollY 始终等于View的上边缘 - View的内容区域上边缘,如果纵向从上向下滑动的话mScrollY为负值,反之为为正值
为了便于理解我花了如下图,虚线框代表着View 本身,而实体框代表着View 的内容区域,通过该图应该很快就能理解mScrollX和mScrollY这两个参数了。

ScrollTo和ScrollBy的使用场景的话,例如我们在使用ScrollView 和 listView 的时候已经滑动到了最底层,那么想要滑动到最顶层的话直接使用scrollTo(0,0)即可。
需要注意的是:默认ScrollTo这个方式是瞬间滑动到目标位置这样并不友好,我们可以借助Scroller 来实现平滑移动。
示例代码: 对TextView 进行自定义复写:
public class MyTextView extends TextView {

    private Scroller mScroller;

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

    public MyTextView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mScroller = new Scroller(context);
    }

    /**
     * 平滑移动到设定的坐标
     *
     * @param destX 绝对坐标X
     * @param destY 绝对坐标Y
     */
    public void smoothScrollTo(int destX, int destY) {
        int mScrollX = getScrollX();
        int mScrollY = getScrollY();

        int deltaX = mScrollX - destX;
        int deltaY = mScrollY - destY;

        if (deltaX == 0 && deltaY == 0)
            return;
        mScroller.startScroll(mScrollX, mScrollY, deltaX, deltaY, 1000);
        invalidate();
    }

    @Override
    public void computeScroll() {
        if (mScroller != null) {
            if (mScroller.computeScrollOffset()) {
                scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
                postInvalidate();
            }
        }
    }
}
这样就可轻松的实现平滑移动了,当然加入你使用的是ScrollView 或者是listView这样的控件直接调用系统方法: smoothScrollToPosition()即可。当然系统提供的这些平滑移动的方法也是有Scoller实现的,看一下源码就知道了。

2 使用动画实现控件的平滑移动

   android的动画包括三大类:帧动画 补间动画  属性动画

 (1) 帧动画
在anim 文件夹下建立xml文件,在xml中按照一定的顺序将图片资源 进行排列起来,在布局中使用 android :background= "" 引用即可 。示例代码如下:
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false" >

    <item
        android:drawable="@drawable/loading1"
        android:duration="200"/>
    <item
        android:drawable="@drawable/loading3"
        android:duration="200"/>
    <item
        android:drawable="@drawable/loading5"
        android:duration="200"/>
    <item
        android:drawable="@drawable/loading7"
        android:duration="200"/>
    <item
        android:drawable="@drawable/loading9"
        android:duration="200"/>
 
</animation-list>

代码中的引用:
AnimationDrawable drawable = (AnimationDrawable) mTextView.getBackground();
drawable.start();
drawable.stop();
使用这种动画方式,应该注意使用图片较小的资源,不然容易出现oom的异常。

(2)补间动画  
补间动画包括:TranslateAnimation ScaleAnimation AlphaAnimation RotateAnimation 这种动画只是一种动画形式并不能改变控件本有的属性。实现这些效果可以通过代码设置也可以通过xml文件设置。

通过代码设置:
TranslateAnimation animation = new TranslateAnimation(0,100,0,100);
animation.setDuration(300);
mTextView.startAnimation(animation);  
通过xml设置:
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/decelerate_interpolator" >

    <alpha
        android:duration="300"
        android:fromAlpha="0.0"
        android:toAlpha="1.0" />

</set>

Animation utils = AnimationUtils.loadAnimation(this,R.anim.umeng_socialize_fade_in);
mTextView.startAnimation(utils);

(3)属性动画
属性动画一般常用到的两个类:ObjectAnimator 和 ValueAnimator(属性动画动画改变的同时,属性也在进行改变)
代码示例:
ObjectAnimator.ofFloat(mTextView,"translationX",0,100).setDuration(300).start();
具体可参照博客:http://blog.csdn.net/lmj623565791/article/details/38067475

3 通过改变布局参数的形式

使用布局参数一般大概步骤如下:比如我想使Button向右平移100px那么我可以这样做

ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mTextView.getLayoutParams();
params.leftMargin += 100;
mTextView.requestLayout();// 或者 mTextView.setLayoutParams(params);

这个是用场景的话,比如我们要去做,仿QQ那种listView item 优化弹出删除按钮的效果,我们就可以使用这种方法,通过不断的让删除Button的布局宽度变大,你就可以看到那种效果。


以上三种就是目前View 平滑移动的常见方法。








  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值