View是Android中全部控件的基類。是一種界面層控件的抽象。html
參數名 | 獲取方式 | 含義 |
---|---|---|
top | getTop() | View左上角縱座標 |
left | getLeft() | View左上角橫座標 |
bottom | getBottom() | View右下角縱座標 |
right | getRight() | View右下角橫座標 |
View:x/y | getX()/getY() | View左上角座標 |
translationX | getTranslationX() | View左上角相對於父容器的偏移量 |
translationY | getTranslationY() | View左上角相對於父容器的偏移量 |
MotionEvent:x/y | event.getX()/event.getY() | 點擊事件相對於View左上角的座標 |
MotionEvent:rawX/rawY | event.getRawX()/event.getRawY() | 點擊事件相對於手機屏幕左上角的座標 |
MotionEvent獲取點擊事件x,y座標:java
getX/getY 相對於View左上角
getRawX/getRawY 相對於手機屏幕左上角android
//在View或Activity中攔截touch events,重寫onTouchEvent方法 @Override public boolean onTouchEvent(MotionEvent event) { int action = MotionEventCompat.getActionMasked(event); switch (action) { case (MotionEvent.ACTION_DOWN): Log.d(TAG,"action down"); return true; case (MotionEvent.ACTION_MOVE): Log.d(TAG,"action move"); return true; case (MotionEvent.ACTION_UP): Log.d(TAG,"action up"); return true; case (MotionEvent.ACTION_CANCEL): Log.d(TAG,"action cancel"); return true; case (MotionEvent.ACTION_OUTSIDE): Log.d(TAG,"action outside"); return true; default: return super.onTouchEvent(event); } } //對於View,能夠使用setOnTouchListener()方法來監聽touch events而不須要繼承現有的View View myView = findViewById(R.id.my_view); myView.setOnTouchListener(new OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { // ... Respond to touch events return true; } });
滑動的最小距離,常量,和設備有關。ide
//獲取方式: ViewConfiguration.get(getContext()).getScaledTouchSlop();
學習資料:
1.https://developer.android.com/training/gestures/movement.html佈局
追蹤手指滑動的速度學習
使用過程:動畫
//在View的onTouchEvent方法中 VelocityTracker velocityTracker = VelocityTracker.obtain(); velocityTracker.addMoveMent(event); //時間間隔設爲1000ms tracker.computeCurrentVelocity(1000); int Vx = (int)velocityTracker.getXVelocity(); int Vy = (int)VelocityTracker.getYVelocity(); //再也不使用的時候,須要清除並回收 velocityTracker.clear(); velocityTracker.recycle();
手勢監測:單擊,滑動,長按,雙擊等等。this
使用方法:.net
GestureDetectorCompat
類GestureDetector.OnGestureListener
接口和GestureDetector.OnDoubleTapListener
接口。GestureDetector.SimpleOnGestureListener
類。//監測全部的手勢 public class MainActivity extends Activity implements GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener{ private static final String DEBUG_TAG = "Gestures"; private GestureDetectorCompat mDetector; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //實例化GestureDetectorCompat mDetector = new GestureDetectorCompat(this,this); //將雙擊事件交給GestureDetectorCompat監聽 mDetector.setOnDoubleTapListener(this); } @Override public boolean onTouchEvent(MotionEvent event){ this.mDetector.onTouchEvent(event); return super.onTouchEvent(event); } @Override public boolean onDown(MotionEvent event) { Log.d(DEBUG_TAG,"onDown: " + event.toString()); return true; } @Override public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) { Log.d(DEBUG_TAG, "onFling: " + event1.toString()+event2.toString()); return true; } @Override public void onLongPress(MotionEvent event) { Log.d(DEBUG_TAG, "onLongPress: " + event.toString()); } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { Log.d(DEBUG_TAG, "onScroll: " + e1.toString()+e2.toString()); return true; } @Override public void onShowPress(MotionEvent event) { Log.d(DEBUG_TAG, "onShowPress: " + event.toString()); } @Override public boolean onSingleTapUp(MotionEvent event) { Log.d(DEBUG_TAG, "onSingleTapUp: " + event.toString()); return true; } @Override public boolean onDoubleTap(MotionEvent event) { Log.d(DEBUG_TAG, "onDoubleTap: " + event.toString()); return true; } @Override public boolean onDoubleTapEvent(MotionEvent event) { Log.d(DEBUG_TAG, "onDoubleTapEvent: " + event.toString()); return true; } @Override public boolean onSingleTapConfirmed(MotionEvent event) { Log.d(DEBUG_TAG, "onSingleTapConfirmed: " + event.toString()); return true; } } //監測部分手勢 public class MainActivity extends Activity { private GestureDetectorCompat mDetector; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mDetector = new GestureDetectorCompat(this, new MyGestureListener()); } @Override public boolean onTouchEvent(MotionEvent event){ this.mDetector.onTouchEvent(event); return super.onTouchEvent(event); } class MyGestureListener extends GestureDetector.SimpleOnGestureListener { private static final String DEBUG_TAG = "Gestures"; @Override public boolean onDown(MotionEvent event) { Log.d(DEBUG_TAG,"onDown: " + event.toString()); return true; } @Override public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) { Log.d(DEBUG_TAG, "onFling: " + event1.toString()+event2.toString()); return true; } } }
彈性滑動對象,用於實現View的彈性滑動。code
學習資料:
1.Android Scroller徹底解析,關於Scroller你所需知道的一切
2.Animating a Scroll Gesture
Scroller的基本用法:
startScroll()
方法來初始化computeScroll()
方法,並在其內部完成平滑移動的邏輯。三種方式實現View的滑動:
ScrollTo
和ScrollBy
方法。Scroll
方法的滾動都是跳躍式的,沒有平滑移動的效果。使用動畫操做View的translationX
和translationY
兩個屬性來移動View。可以使用屬性動畫/View動畫。
View動畫是對View的影像進行操做的。也就是說View動畫並不能真正的改變View的位置。
屬性動畫是真正改變View的位置,但它是從Android3.0開始推出的。
//View動畫實現移動 <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:fillAfter="true" > <translate android:fromXDelta="0" android:fromYDelta="0" android:toXDelta="500" android:toYDelta="1000" android:duration="10000" android:interpolator="@android:anim/linear_interpolator" /> </set> Animation animation = AnimationUtils.loadAnimation(this, R.anim.translate); layout.setAnimation(animation); animation.start(); //使用屬性動畫實現移動 ObjectAnimator.ofFloat(layout,"translationX",0,100).setDuration(1000).start();
改變佈局參數LayoutParams
。
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) layout.getLayoutParams(); params.width+=1000; params.leftMargin+=1000; layout.requestLayout();
方式 | 優勢 | 缺點 |
---|---|---|
scrollTo/scrollBy | 原生方法,操做簡單,適用於對內容的滑動 | 不能滑動View自己 |
動畫 | 操做簡單,適用於沒有交互的View和複雜的動畫效果 | |
改變佈局參數 | 適用於有交互的View | 操做較複雜 |
將一次時間長的滑動分紅若干次短的滑動。
//1.建立Scroller Scroller scroller = new Scroller(context); ... //2.調用Scroller的startScroll方法 int scrollX = getScrollX(); int deltaX = destX - scrollX; scroller.startScroll(scrollX,0,deltaX,0,1000); invalidate(); //3.複寫computeScroll()方法 @Override public void computeScroll(){ if(scroller.computeScrollOffset()){ scrollTo(scroller.getCurrX(),scroller.getCurrY()); invalidate(); } }