1.View的位置主要由四个顶点来决定,top,left,right,bottom,其中top是左上角总坐标,left是左上角横坐标,right是右下角横坐标,bottom是右下角纵坐标。这四个是相对父布局来说的。(可以说左上角的坐标是(left,top) 右下角的坐标是(right bottom))
2.View的宽 width=right-left,height = bottom-top,left = getLeft() 其他属性类似。
3.android3.0以后额外增加了几个属性,x,y ,translationX,translationY其中x,y是Vie的左上角的坐标,而translationX,translationY是View左上角相对与父容器的偏移量,默认值是0,同时也有get/set方法。
x=left+translationX(初始left+偏移量0)
y=right+translationY(初始right+偏移量0)
left等属性是初始是原View的位置信息不会改变,发生改变时可通过修改偏移量translationX,translationY而对x,y进行修改。
4.MotionEvent手指在接触屏幕后产生的时间,
ACTION_DOWN手指刚接触屏幕
ACTION_MOVE手指移动
ACTION_UP手指从屏幕离开的一瞬间
一边的触摸的情况有,点击屏幕DOWN-UP 移动DOWN-MOVE-MOVE-..-MOVE-UP
点击屏幕的时候会获取到x,y rawX,rawY 四个属性,x,y是相对于View左上角 rawX,rawY是相对于屏幕来说的。(这四个属性都可以通过get来获取 getX())
5.TouchSlop使系统能识别的最小的滑动值可通过
ViewConfiguration.get(get(Context)).getScaledTouchSlop();
来获取,进行一些自定义属性的判断
6.VelocityTracker
速度追踪,用与追踪手指在滑动过程中的数度包括水平和竖直方向的速度。
@Override
public boolean onTouchEvent(MotionEvent event) {
VelocityTracker velocityTracker = VelocityTracker.obtain();
velocityTracker.addMovement(event);
//获取当前的数度
velocityTracker.computeCurrentVelocity(1000);//获取速度之前必须先计算数度在getXVelocity();getYVelocity();方法前
int xVelocity = (int) velocityTracker.getXVelocity();
int yVelocity = (int) velocityTracker.getYVelocity();
//这里的数度是指在当时间间隔设置为1000ms时 在1s内,手指在水平方向从左向右划过100像素,那速度就是100 (此速度可以为负)
//可以用公式 速度 = (终点位置-起始位置)/时间段
//最后当不需要使用时要调用clear方法来重置并回收
velocityTracker.clear();
velocityTracker.recycle();
return super.onTouchEvent(event);
}
7.GestureDetector
手势检测 用于辅助检测用户的单击,滑动,长按,双击等行为
首先要建立一个GestureDetector对象并实现OnGrestureListener接口,根据需求可实现OnDoubleTapListener实现双击行为
@Override
public boolean onTouchEvent(MotionEvent event) {
GestureDetector mGestureDetector = new GestureDetector(this);
//解决长按屏幕后无法拖动的现象
mGestureDetector.setIsLongpressEnabled(false);
// 接管View 的 onTouchEvent方法
boolean consume = mGestureDetector.onTouchEvent(event);
return consume;
}
@Override
public boolean onDown(MotionEvent e) {
//手指轻松触摸屏幕的一瞬间
return false;
}
@Override
public void onShowPress(MotionEvent e) {
//手指轻松触摸屏幕尚未松开或尚未移动
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
//手指轻松触摸屏幕的一瞬间放开 单机行为
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
//拖动行为
return false;
}
@Override
public void onLongPress(MotionEvent e) {
//长按行为
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
//手指按下后快速滑动后松开这是滑动行为
return false;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
//严格的单击行为
return false;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
//双击
return false;
}
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
//表示发生了双击行为,再双击的期间,ACTION_DOWN,ACTION_MOVE,ACTION_UP都会执行
return false;
}
在日常开发中 onSingleTapUp(单击)onFling(快速滑动)onScroll(拖动)onLongPress(长按)onDoubleTap(双击)比较常用
8.Scroller
private Scroller scroller = new Scroller(context);
@Override
public void computeScroll() {
super.computeScroll();
if (scroller.computeScrollOffset()){
ScrollTo(scroller.getCurrX(),scroller.getCurrY());
postInvalidate();
}
}
private void smoothScrollTo(int destX, int destY){
int scrollX = getScrollX();
int delta = destX-scrollX;
//1000ms内滑动destX,效果就是慢慢滑动
scroller.startScroll(scrollX,0,delta,0,1000);
invalidate();
}
9.View的滑动
(1)使用scrollTo/scrollBy
@Override
public void scrollBy(int x, int y) {
super.scrollBy(x, y);
}
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();
}
}
}
scrollTo是根据传递值的绝对滑动,scrollBy是相对滑动 但是不管怎么移动都不能改变View的位置只能改变View中内容的位置