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