3种滑动方式的学习
一:使用scrollTO/scrollBy
二: 通过动画给View施加平移效果
三:通过改变View的LayoutParams使View重新布局从而实现滑动
一:使用scrollTo/scrollBy
1:scrollBy实际调用scrollTo方法
2:scrollBy实现基于当前位置的相对滑动
3:scrollTo实现基于所传递参数的绝对滑动
4:scrollTo/scrollBy只改变View内容位置而不改变View在布局中的位置,View边缘是指View的位置,而View内容边缘指View中内容边缘。
5:理解mScrollX和mScrollY改变规则
mScrollX值总等于View左边缘和View 内容左边缘在水平方向的距离
mScrollY值总等于View上边缘和View 内容上边缘在竖直方向的距离
二、使用动画
主要操作:View的translationX和translationY
可以使用View传统动画,也可以使用属性动画
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true"
android:zAdjustment="normal">
<translate
android:duration="100"
android:fromXDelta="0"
android:fromYDelta="0"
android:interpolator="@android:anim/linear_interpolator"
android:toXDelta="100"
android:toYDelta="100"/>
</set>
ObjectAnimator.ofFloat(targetView,"translationX",0,100).setDuration(100).start();
注:View动画是对View的影像做操作,它并不能真下改变View的位置参数,包括宽/高,并且如果希望动画后的状态得以保留必须将fillAfter属性设置为true.否则动画完成后其动画结果会消失。比如我们把View向右移动100像素,如果fillAfter设置成false,它会在完成的一刹恢复原先状态,如果fillAfter设置成true,View会停留在View右边100像素的右边。使用属性动画不会存在这样的问题,但Android 3.0以下无法使用属性动画,这个时候可以使用动画兼容库nineooldandroids来实现属性动画。但是,android3.0以下的手机通过nineoldandroids来实现属性动画的本质仍然是View动画。
使用View动画,并不能真正改变View的位置,这会导致一个问题,一个Button在使用View动画将Button移动位置后,单击事件还在原来位置上。因为不管Button怎么变换,但它的位置信息并不会随动画而改变。因此在系统眼里,这个Button并没有发生任何改变。它的真身还在原来位置上。
从android3.0开始,使用属性动画可以解决上面问题,如果要兼容3.0以下,而3.0不能使用属性动画,就会出现问题,解决办法:创建两个Button一个隐藏,移动到指定位置,指定位置的Button显示。
三、改变布局参数
使用LayoutParams
MarginLayoutParams params=(MarginLayoutParams)mButton1.getLayoutParams();
params.width+=100;
params.leftMargin+=100;
mButton1.requestLayout();
//或者mButton1.setLayoutParams(params);
三个优缺点:
scrollTO/scrollBy只能滑动View内容,不能滑动View本身。
动画:android3.0使用属性动画,并没有明显的缺点,如果使用View动画或者android 3.0使用属性动画均不能改变View本身的属性,如果不需要用户的交互,那么使用动画做滑动是比较人合适的,否则不太适合。
改变布局:使用麻烦,主要适用对象是一些具有交互性的View,因为这些View需要和用户交互,通过动画会有问题。
int downX = 0;
int downY = 0;
@Override
public boolean onTouchEvent(MotionEvent event) {
int rawX = (int) event.getRawX();
int rawY = (int) event.getRawY();
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
//当触摸时,记录坐标
downX = rawX;
downY = rawY;
break;
case MotionEvent.ACTION_MOVE:
//移动时,记录坐标,并计算出偏移量
int offsetX = rawX-downX;
int offsetY = rawY-downY;
//在当前left top bottom right上加上偏移量,得到的就是新的坐标
layout(getLeft()+offsetX,getTop()+offsetY,getRight()+offsetX,getBottom()+offsetY);
downX = rawX;
downY = rawY;
break;
}
return true;
}