Android View 的滑动
一、View 的簡介
View是所有可視化控件的基類,我們平時接觸的所有的控件,比如說TextView,Button 等等都繼承于View。View是Android 在視覺上的呈現,是界面層控件的一種抽象,可以是單個控件也可以是一組控件。
二、坐標系
1、Android 坐標系
在Android中,屏幕的左上角定點被視為Android坐標系的原點,原點向右是X軸正方向,原點向下是Y軸正方向。在觸控事件中使用 getRawX()、getRawY() 來獲取Android 坐標系的坐標,也可以稱之為絕對坐標。
2、視圖(View)坐標系
視圖坐標系是用來描述當前View 和父視圖的位置關系的。這里是以父視圖的左上角定點為視圖坐標系的原點,原點向右是X軸正方向,原點向下是Y軸正方向。在觸控事件中使用getX()、getY() 來獲取視圖坐標系的坐標,也可以稱之為相對坐標.
三、View滑動的實現
View 的滑動實現邏輯:當觸摸事件傳到View 時,記錄下觸摸點的坐標,手指在移動的時候記下移動后的觸摸坐標并算出偏移量,然后通過偏移量來修改View 的坐標。
MotionEvent
我們要實現View的滑動要在 onTouchEvent(MotionEvent event)中進行觸摸事件的監聽,MotionEvent 是觸控事件的封裝,簡短的介紹下MotionEvent中封裝的事件常量:
public static final int ACTION_DOWN = 0; //單點觸摸按下動作
public static final int ACTION_UP = 1; //單點觸摸離開動作
public static final int ACTION_MOVE = 2; //單點觸摸移動動作
public static final int ACTION_CANCEL = 3; //觸摸動作取消
public staiic final int ACTION_OUTSIDE = 4; //觸摸動作超出邊界
public static final int ACTION_POINTER_DOWN = 5; //多點觸摸按下動作
public static final int ACTION_POINTER_UP = 6; 多點離開動作
1、layout()方法
view進行繪制的時候會調用onLayout()方法來設置顯示的位置,因此我們同樣也可以通過修改View的left、top、right、bottom這四種屬性來控制View的坐標:
@Overridepublic boolean onTouchEvent(MotionEvent event) {// 獲取觸摸點的x,yint x = (int) event.getX();int y = (int) event.getY();switch (event.getAction()) {case MotionEvent.ACTION_DOWN:// 記錄觸摸點坐標lastX = x;lastY = y;break;case MotionEvent.ACTION_MOVE:// 計算偏移量int moveX = x - lastX;int moveY = y - lastY;// 更改位置layout(getLeft() + moveX, getTop() + moveY,getRight() + moveX, getBottom() + moveY);break;}return true;}2、offsetLeftAndRight()和offsetTopAndBottom
傳入偏移量后,這兩個方法就是對View左右、上下移動的操作。
@Overridepublic boolean onTouchEvent(MotionEvent event) {// 獲取觸摸點的x,yint x = (int) event.getX();int y = (int) event.getY();switch (event.getAction()) {case MotionEvent.ACTION_DOWN:// 記錄觸摸點坐標lastX = x;lastY = y;break;case MotionEvent.ACTION_MOVE:// 計算偏移量int moveX = x - lastX;int moveY = y - lastY;// 更改位置offsetLeftAndRight(moveX);offsetTopAndBottom(moveY);break;}return true;}3、LayoutParams
LayoutParams保存了View的布局參數,所以我們可以改變LayoutParams來動態的改變布局的位置來達到滑動的效果。
@Overridepublic boolean onTouchEvent(MotionEvent event) {// 獲取觸摸點的x,yint x = (int) event.getX();int y = (int) event.getY();switch (event.getAction()) {case MotionEvent.ACTION_DOWN:// 記錄觸摸點坐標lastX = x;lastY = y;break;case MotionEvent.ACTION_MOVE:// 計算偏移量int moveX = x - lastX;int moveY = y - lastY;// 更改位置LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) getLayoutParams();params.leftMargin = getLeft() + moveX;params.topMargin = getTop() + moveY;setLayoutParams(params);break;}return true;}其實LayoutParams 完全可以配合 xml 中的layout_width、layout_marginLeft 等等這些前面帶layout_ 的屬性去理解,設置LayoutParams 各個參數的過程就是動態設置xml中帶layout_ 各個屬性的過程。關于LayoutParams 的詳細分析,可以參照這位大神寫的博客 自定義控件知識儲備-LayoutParams的那些事,寫的很透徹,完全被圈粉。
4、ScrollTo 和 scrollBy
scollTo(x,y)表示移動到一個具體的坐標點,而scollBy(dx,dy)則表示移動的增量為dx、dy。查看scollBy()源碼最終也是要調用scollTo的,舉個例子說明下scollBy()是怎樣移動的:
我們都知道畫布的大小是無限大的,而坐標系是基于屏幕的左上角為原點的,所以屏幕中的控件的Android 坐標是(40,50),當我們執行scrollBy(30,30) 的時候,按照字面意思,這個控件的位置應該會出現在當前紅色屏幕的右下方,可是事實上卻出現在了屏幕的左上方。這是因為當執行scrollBy()方法的時候,我們的屏幕會沿著X軸正方向平移30,向Y軸正方向平移30,也就是屏幕向右下方平移了,此時紅色的位置就是當前屏幕的位置。當執行完ScrollBy 以后,坐標系就會繼續基于屏幕的左上角為原點,所以此時的屏幕中的控件的Android坐標為(10,20)。所以當我們調用scrollBy 方法的時候,要設置值為負數才能得到自己想要的移動效果。
scollTo、scollBy移動的是View的內容,如果在ViewGroup中使用則是移動他所有的子View,這點要特別注意。
5、Scroller
我們用scollTo/scollBy方法來進行滑動時,這個過程是瞬間完成的,所以用戶體驗不大好。這里我們可以使用Scroller來實現有過度效果的滑動,這個過程不是瞬間完成的,而是在一定的時間間隔完成的。Scroller本身是不能實現View的滑動的,它需要配合View的computeScroll()方法才能彈性滑動的效果。Scroller的基本用法其實還是比較簡單的,主要可以分為以下幾個步驟:
1. 創建Scroller的實例
2. 調用startScroll()方法來初始化滾動數據并刷新界面
3. 重寫computeScroll()方法,并在其內部完成平滑滾動的邏輯
結尾:以上就是關于View 滑動的相關內容了,當然還有屬性動畫也能控制View 的滑動,我準備放到動畫篇講解。下面附上源碼:https://github.com/smile-sxl/CustomView
轉載于:https://www.cnblogs.com/javasxl/p/9397774.html
總結
以上是生活随笔為你收集整理的Android View 的滑动的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: win主机ping不通linux的IP
- 下一篇: Android 获取ROOT权限原理解析