时间过得真快,一转眼就要到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);
以上三种就是目前View 平滑移动的常见方法。