一个用例理解MotionEvent.getX()/getRawX/getScrollY()/childView.scrollBy((int) DX, (int) 0)

Sylvia ·
更新时间:2024-09-21
· 910 次阅读

 1.Android移动方式

1. 使用scrollTo/scrollBy
  只能影响View的内容移动,并不能改变View本身的位置 
2. setX , setY: 设置控件相对于父控件位置
3. 动画  

2. Api 综合理解:

getRawX: 获取当前控件相对于屏幕原点坐标
getX: 获取当前控件相对于父控件坐标 

 ##MotionEvent.getX(): 获取按下点相对于屏幕原点坐标
 MotionEvent.getY();

 ## getScrollY(): 里面内容相对于父控件移动距离

  // 设置内容移动 
     // 从左到右 负值,  开始减去结束
    // 从右往左 正值,
    float distanceX = endX - startX;
    childView.scrollBy((int) DX, (int) 0);//移动的是一下断的距离

看图理解:

3. Android实现左右滑动内容弹性效果:

布局:

 代码实现:

package com.qqyumidi.event; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.widget.LinearLayout; import android.widget.Scroller; public class TouchEventChilds extends LinearLayout { private View childView; private Scroller scroller; @Override protected void onFinishInflate() { super.onFinishInflate(); childView = getChildAt(0); } public TouchEventChilds(Context context) { super(context); } public TouchEventChilds(Context context, AttributeSet attrs) { super(context, attrs); scroller = new Scroller(context) ; } public boolean dispatchTouchEvent(MotionEvent ev) { Log.e("eventTest", "Childs | dispatchTouchEvent --> " + TouchEventUtil.getTouchAction(ev.getAction())); return super.dispatchTouchEvent(ev); //return true; } public boolean onInterceptTouchEvent(MotionEvent ev) { Log.i("eventTest", "Childs | onInterceptTouchEvent --> " + TouchEventUtil.getTouchAction(ev.getAction())); return super.onInterceptTouchEvent(ev); // return true; } private float startX; private float startY; public boolean onTouchEvent(MotionEvent ev) { super.onTouchEvent(ev); Log.d("eventTest", "Childs | onTouchEvent --> " + TouchEventUtil.getTouchAction(ev.getAction())); switch (ev.getAction()){ case MotionEvent.ACTION_DOWN: startX = ev.getX(); startY = ev.getY(); Log.d("yangguangfu", "========ACTION_DOWN=========" + startX+","+startY); break; case MotionEvent.ACTION_MOVE: float endX = ev.getX(); float endY = ev.getY(); float distanceX = endX - startX; float distanceY = endY - startY; Log.d("yangguangfu", " getScrollX ===================" + getScrollX()); // getScrollX() 的值为0 //float DX = getScrollX() - distanceX; float DX = 0 - distanceX; Log.d("yangguangfu", "( " + startX+",,,"+startY+")"+"--("+endX+"---"+endY+")--("+distanceX+",,,"+distanceY+")"+",DX==="+DX); // Log.d("yangguangfu", "getScrollX ======================" + getScrollX()); // childView.scrollTo((int) DX, (int) 0);//移动的是相当坐标 // 从左到右 负值, 开始减去结束 // 从右往左 正值, childView.scrollBy((int) DX, (int) 0);//移动的是一下断的距离 startX = ev.getX(); startY = ev.getY(); break; case MotionEvent.ACTION_UP: int totalScrollX = childView.getScrollX(); // 为什么要0 减去 // 从左到右 负值, // 从右往左 正值, // 恢复原来的位置 int X = 0 - childView.getScrollX(); // Log.d("yangguangfu", "( " + childView.getScrollX()+",,,"+childView.getScrollY()+")"+"--("+X+",,,"+0+")"+",childViewWidth="+childView.getMeasuredWidth()); scroller.startScroll(childView.getScrollX(), childView.getScrollY(), X, 0); // 刷新UI这里会调用 computeScroll()方法 // 不调用 onDraw()方法 invalidate(); break; } // return super.onTouchEvent(ev); return true; } @Override public void computeScroll() { super.computeScroll(); if(scroller .computeScrollOffset()){ childView.scrollTo(scroller.getCurrX(),scroller.getCurrY()); invalidate(); } } }

输出内容:

E/yangguangfu: ========ACTION_DOWN=========209.99219,323.98438
E/yangguangfu:  getScrollX ===================0
E/yangguangfu: ( 209.99219,,,323.98438)--(219.42232---323.98438)--(9.43013,,,0.0),DX===-9.43013  //DX向右移动9.43013

// 在MotionEvent.ACTION_MOVE的时候对应代码:
float DX = 0 - distanceX;
childView.scrollBy((int) DX, (int) 0);//移动的是一下断的距离

效果图:


作者:小置同学



int dx

需要 登录 后方可回复, 如果你还没有账号请 注册新账号