android群英传 自定义滑动view,Android群英传学习之路-View的滑动
滑動效果是如何產生的?
滑動一個View從本質上來說就是移動一個View,改變其當前的坐標。所以,想要滑動一個View,就必須監聽該View的觸摸事件,并且根據事件的坐標,不斷的改變View的坐標從而實現View的滑動。
Android中的坐標體系
Android中的坐標體系分為兩種:
Android坐標系
視圖坐標系
Android坐標系
Android坐標系
從圖中我們可以看的出來**在Android坐標系中以屏幕的左上方作為坐標系的原點,從原點向右為X軸的正方向,向下為Y軸的正方向**。在觸控事件中使用**getRawX()、getRawY()**來獲得Android坐標系的坐標
視圖坐標系
視圖坐標系
視圖坐標系主要描述的是該View和該View在父視圖中的位置關系,和Android坐標系一樣,也是以原點右方為X正方向,以原點下方為Y軸正方向,不過這里不是以屏幕的左上角為原點,而是**以父視圖的左上角為原點**。在觸控事件中使用**getX()、getY()**來獲得視圖坐標系的坐標
觸控事件
在上一篇文章中我們使用到了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; 多點離開動作
通常情況下我們會在onTouchEvent(MotionEvent event)方法中通過event.getAction()來獲取觸控事件的類型。知道Android中的坐標系和觸控事件之后我們就可以來實現View的滑動了
滑動實現
實現滑動有好多種方法,但是其思想都是一樣的。當觸摸到View時,記錄當前觸摸點的坐標,然后當手指移動時,獲取到相對于前一個點的偏移量,這樣我們就可以通過這個偏移量來進行修改View的坐標,這樣不斷的重復,就能實現View的滑動
舉個例子
我們自定義一個View,讓他來跟隨我們手指的移動來移動,如圖:
layout方法
我們知道在View進行繪制的時候會通過onLayout()方法來設置View的顯示位置,這里我們通過修改View的left, top, right, bottom四個值來控制View的坐標
public boolean onTouchEvent(MotionEvent event) {
int 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 offsetX = x - lastX;
int offsetY = y - lastY;
//在當前位置基礎加上偏移量
layout(
getLeft() + offsetX,
getTop() + offsetY,
getRight() + offsetX,
getBottom() + offsetY
);
break;
}
return true;
}
offsetLeftAndRight()和offsetTopAndBottom
這個方法就是相當于系統提供的一個對左右、上下移動的API的封裝,計算好偏移量后,調用方法即可:
offsetLeftAndRight(offsetX);
offsetTopAndBottom(offsetY);
LayoutParams
LayoutParams保存了View的布局參數,所以我們可以改變LayoutParams來動態的改變布局的位置來達到滑動的效果。在程序中使用getLayoutParams()來獲取當前View的LayoutParams,這里就和上面一樣,獲取到偏移量后通過setLayoutParams來設置該View的LayoutParams:
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) getLayoutParams();
params.leftMargin = getLeft() + offsetX;
params.topMargin = getTop() + offsetY;
setLayoutParams(params);
需要注意一點,通過getLayoutParams()獲取LayoutParams的時候,要根據View的父布局的類型來設置,當然前提還要有一個父布局。還有就是我們可以使用ViewGroup.MarginLayoutParams,這樣就不用考慮父布局是什么了
scrollTo、scrollBy
在View中,系統還提供了scrollTo、scrollBy兩種方式來改變一個View的位置。
其中scrollTo表示移動到一個具體的坐標點,scrollBy表示移動的偏移量,其實在scrollBy內部也是調用的scrollTo。
和前面的方式一樣,獲取到偏移量后調用scrollBy來移動view,可是當我們運行程序,拖動View,發現View并沒有移動!這是因為scrollTo、scrollBy方法移動的是View的內容,如果在ViewGroup中使用scrollTo、scrollBy的滑,那么移動的就是View了,但是如果在View中使用,那么移動的將是View里面的內容,比如TextView,那么移動的就是文本了。
所以通過上面的分析,我們把代碼改為如下:
((View)getParent()).scrollBy(offsetX, offsetY);
再次運行程序,我們會發現動是動了,但是在亂動。因為這里我們其實是在相反的方向移動(這里由于篇幅限制,感興趣的同學自行查找一下資料),我們把偏移量改為負的之后就會發現滑動正常了。
Scroller
首先來想一個場景:我們需要讓一個Button向右面移動100個像素,如果我們用scrollTo/scrollBy的話,那么該View就會很突兀的移動到該點,沒有過程,而Scroller則是可以實現平滑的過渡效果的
下面我們把上面跟隨手指滑動的例子改一下,我們在松開手指后,View自動回到原點(屏幕左上角)。使用Scroller需要三個步驟
初始化
通過構造方法即可 Scroller mScroller = new Scroller(context);
重寫computeScroll()方法,實現滑動
startScroll()開啟滑動
代碼如下:
case MotionEvent.ACTION_UP:
View viewGroup = (View) getParent();
mScroller.startScroll(
viewGroup.getScrollX(),
viewGroup.getScrollY(),
-viewGroup.getScrollX(),
-viewGroup.getScrollY()
);
invalidate();
break;
----------------------------------------------------------------
@Overrid
public void computeScroll() {
super.computeScroll();
if (mScroller.computeScrollOffset()) {
((View) getParent()).scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
invalidate();
}
}
當我們手指抬起來的時候開啟Scroller滑動,獲取到當前view的移動距離,然后我們把需要移動的偏移量設置為相反數就ok,最后調用invalidate來通知重繪,從而調用computeScroll()方法。運行程序如下:
現在就把這幾種View的滑動都說完了,自己動手寫一下,感觸良多。
最后
愛生活,愛小麗,愛Android
總結
以上是生活随笔為你收集整理的android群英传 自定义滑动view,Android群英传学习之路-View的滑动的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux文件压缩与打包-1
- 下一篇: 预测模型算法