之前写过一个小球随手指滑动的demo,很简单,复写onTouchEvent,事件传递进来,得到手指触点位置,通知重绘invalidate, 复写onDraw方法,传入触点坐标。这是不断画图的过程。总结一下不画图的几种滑动方式。
1、layout方法
@Override
public boolean onTouchEvent(MotionEvent event) {
float rawX = event.getRawX();
float x = event.getX();
float y = event.getY();
Log.e("mrpeng","raw:::"+rawX+"rawY::::"+x);
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
float offsetX=x-lastX;
float offsetY=y-lastY;
break;
case MotionEvent.ACTION_UP:
break;
}
lastX = x;
Log.e("mrpeng","lastX::::"+ lastX);
lastY = y;
return true;
}
2、offsetLeftAndRight
系统提供一个对左右上下移动的API方法
View myView = findViewById(R.id.myView);
myView.offsetLeftAndRight(offsetX);
3、LayoutParams
LinearLayout.LayoutParams layoutParams =
(LinearLayout.LayoutParams) myView.getLayoutParams();
layoutParams.leftMargin= myView.getLeft()+offsetX;
layoutParams.topMargin=myView.getTop()+offsetY;
4、scrollTo scrollBy
注意,此处移动的是View的content,即让View 的内容移动,如果ViewGroup调用此方法,那么移动的将是所有子View,如果View中使用移动的是View中的内容物,如果是TextView,则移动text,ImageView,则为drawable对象。
myView.getParent().scrollBy(-offsetX,-offsetY);
5、Scroller
Scroller mScroller=new Scroller(mContex);
public void smoothScrollTo(int destX,int destY){
int scrollX = getScrollX();
int delta=destX-scrollX;
mScroller.startScroll(scrollX,0,delta,0,1000);
invalidate();
}
/**
* 系统会在绘制View的时候在draw()方法中调用该方法,实际就是使用scrollTo()方法,
*/
@Override
public void computeScroll() {
super.computeScroll();
if (mScroller.computeScrollOffset()){
scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
postInvalidate();
}
}
6、动画
demo\codes\AnimationDrawable\app\src\main\res\anim\my_anim.xml
<?xml version="1.0" encoding="UTF-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/linear_interpolator"
android:duration="5000">
<!-- 定义位移变换 -->
<translate android:fromXDelta="10"
android:toXDelta="130"
android:fromYDelta="30"
android:toYDelta="-80"
android:duration="2000"/>
</set>
属性动画
bulabula
时间分发,用一段伪代码展示其关系
public void dispatchTouchEvent(MotionEvent ev){
boolean consume=false;
if (onInterceptTouchEvent(ev)){
consume=onTouchEvent(ev);
}else {
consume=child.diapatchTouchEvent(ev);
}
return consume;
}
坑人的滑动冲突
1、父View左右滑,子View上下滑
2、父View上下滑,子View也上下滑
3、爷爷…………………… 万变不离其宗。。。
ViewPager+ListView本来是有滑动冲突的,但是强大的VoewPager已经处理过了,如果是横向ScrollView 嵌套ListView
第一种方法,父容器拦截处理,重写onInterceptTouchEvent
第二种方法,内部拦截处理,重写子元素的dispatchTouchEvent
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
boolean intercepted = false;
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
intercepted = false;
if (!mScroller.isFinished()) {
mScroller.abortAnimation();
intercepted = true;
}
break;
}
case MotionEvent.ACTION_MOVE: {
int deltaX = x - mLastXIntercept;
int deltaY = y - mLastYIntercept;
if (Math.abs(deltaX) > Math.abs(deltaY)) {
intercepted = true;
} else {
intercepted = false;
}
break;
}
case MotionEvent.ACTION_UP: {
intercepted = false;
break;
}
default:
break;
}
Log.d(TAG, "intercepted=" + intercepted);
mLastX = x;
mLastY = y;
mLastXIntercept = x;
mLastYIntercept = y;
return intercepted;
}
第二种方法
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
getParent().requestDisallowInterceptTouchEvent(true);
break;
}
case MotionEvent.ACTION_MOVE: {
int deltaX = x - mLastX;
int deltaY = y - mLastY;
Log.d(TAG, "dx:" + deltaX + " dy:" + deltaY);
if (Math.abs(deltaX) > Math.abs(deltaY)) {
getParent().requestDisallowInterceptTouchEvent(false);
}
break;
}
case MotionEvent.ACTION_UP: {
break;
}
default:
break;
}
mLastX = x;
mLastY = y;
return super.dispatchTouchEvent(event);
}