1. 程式人生 > >Android實現滑動的幾種方法

Android實現滑動的幾種方法

下面通過一個例子來總結實現滑動的幾種方式,例子的主要功能就是讓我們的自定義View能夠隨著手指的移動而移動。 佈局檔案如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <com.scu.lly.dragviewtest.view.DragView
        android:layout_width="100dp"
        android:layout_height="100dp" />
</LinearLayout>

方式一:layout方法

在View進行繪製時,會呼叫onLayout()方法來設定顯示的位置,因此,我們可以通過修改View的left、top、right、bottom四個屬性來控制View的座標。要控制View隨手指滑動,因此需要在onTouchEvent()事件中進行滑動控制。程式碼如下:
public class DragView extends View{

    private int mLastX;
    private int mLastY;

    public DragView(Context context) {
        super(context);
        init();
    }

    public DragView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public DragView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init(){
        setBackgroundColor(Color.BLUE);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        int x = (int) ev.getX();
        int y = (int) ev.getY();
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                mLastX = x;
                mLastY = y;
                break;
            case MotionEvent.ACTION_MOVE:
                int offsetX = x - mLastX;
                int offsetY = y - mLastY;
                //調整layout的四個座標
                layout(getLeft() + offsetX, getTop() + offsetY, getRight() + offsetX, getBottom() + offsetY);
                break;
        }
        return true;
    }
}

方式二:offsetLeftAndRight()和offsetTopAndBottom()

這兩個方法其實是對上面那種layout設定方式的封裝、簡化,在layout中,左left、右right兩個方向都是加上offsetX,上top、下bottom兩個方向都是加上offsetY,為了簡化設定四個方向,Android提供了offsetLeftAndRight()來代替左右方向的設定,用offsetTopAndBottom()來代替上下方向的設定。 我們只需要修改上面程式碼ACTION_MOVE的部分,如下:
<span style="white-space:pre">	</span>case MotionEvent.ACTION_MOVE:
                int offsetX = x - mLastX;
                int offsetY = y - mLastY;
                //調整layout的四個座標
                //layout(getLeft() + offsetX, getTop() + offsetY, getRight() + offsetX, getBottom() + offsetY);
                //使用簡寫形式
                offsetLeftAndRight(offsetX);
                offsetTopAndBottom(offsetY);
                break;

方式三:LayoutParams

LayoutParams儲存了一個View的佈局引數,因此我們可以通過動態改變LayoutParams中的佈局引數來達到改變View的位置效果。通過getLayoutParams()方法來獲取View的LayoutParams,這裡獲取到的LayoutParams需要根據View所在父佈局的型別來設定不同的型別,比如,我們這個自定義View是放在LinearLayout中的,那麼通過getLayoutParams()獲取到的就是LinearLayout.LayoutParams。因此,通過getLayoutParams()獲取到LayoutParams的前提就是這個View需要有一個父佈局。 同樣,我們只需要修改上面程式碼ACTION_MOVE的部分,如下:
case MotionEvent.ACTION_MOVE:
    int offsetX = x - mLastX;
    int offsetY = y - mLastY;
    LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) getLayoutParams();
    lp.leftMargin = getLeft() + offsetX;
    lp.topMargin = getTop() + offsetY;
    setLayoutParams(lp);
    break;
可以看到,通過LayoutParams改變一個View的位置時,改變的是這個View的Margin屬性,這也是為什麼這種方式一定要有父佈局的原因,只有有了父佈局,margin屬性的設定才會起作用。 對於使用LayoutParams這種方式改變View位置,如果我們不想考慮父佈局的型別,還可以使用ViewGroup.MarginLayoutParams來進行設定,這樣也更加方便。如下:
case MotionEvent.ACTION_MOVE:
    int offsetX = x - mLastX;
    int offsetY = y - mLastY;
    //LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) getLayoutParams();
    ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) getLayoutParams();
    lp.leftMargin = getLeft() + offsetX;
    lp.topMargin = getTop() + offsetY;
    setLayoutParams(lp);
    break;
效果是一樣的。

方式四:scrollTo與scrollBy

關於scrollTo()和scrollBy()方法,我這篇文章《Android Scroller大揭祕》中有詳細介紹。 使用scrollTo()和scrollBy()方法需要注意的一點是,scrollTo()和scrollBy()方法移動的是View的content,即讓View的內容移動,如果在ViewGroup中使用scrollTo()和scrollBy()方法,那麼移動的將是所有的子View,如果在View中使用,那麼移動的將是View的內容。例如,TextView,content就是它的文字,ImageView,content就是它的drawable物件。 因此,上面例子中我們如果直接這樣使用: scrollBy(offsetX,offsetY); 發現View並沒有移動,但其實是發生了移動的,只不過此時移動的是View中的內容,而我們例子中的content什麼也沒有。 所以,我們要想使這個View發生移動,我們就應該在View所在的ViewGroup中使用scrollBy或scrollTo方法來進行移動。同時,使用者兩個方法進行移動的時候,注意此時的座標方向與平常是相反的,具體在《Android Scroller大揭祕》有講解。程式碼如下:
case MotionEvent.ACTION_MOVE:
    //int offsetX = x - mLastX;
    //int offsetY = y - mLastY;
    //此時,計算座標是相反的
    int offsetX = mLastX - x;
    int offsetY = mLastY - y;
    //讓View所在的ViewGroup進行移動
    ((View)getParent()).scrollBy(offsetX,offsetY);
     break;

方式五:Scroller

通過Scroller這個輔助類,配合scrollTo和scrollBy可以實現一些更加高階的滑動效果,關於Scroller類的具體介紹,同樣在這篇文章中有詳解《Android Scroller大揭祕》 這裡,我們只是結合上面這個例子實現一個簡單的功能,當我們滑動完畢擡起手指後,View自動回彈到原來的位置。程式碼如下:
public class DragView extends View{

private int mLastX;
    private int mLastY;
    private Scroller mScroller;

    public DragView(Context context) {
        super(context);
        init(context);
    }

    public DragView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public DragView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context){
        setBackgroundColor(Color.BLUE);
        mScroller = new Scroller(context);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        int x = (int) ev.getX();
        int y = (int) ev.getY();
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                mLastX = x;
                mLastY = y;
                break;
            case MotionEvent.ACTION_MOVE:
                //int offsetX = x - mLastX;
                //int offsetY = y - mLastY;
                //此時,計算座標是相反的
                int offsetX = mLastX - x;
                int offsetY = mLastY - y;
                //讓View所在的ViewGroup進行移動
                ((View)getParent()).scrollBy(offsetX,offsetY);
                break;
            case MotionEvent.ACTION_UP:
                View viewGroup = (View) getParent();
                mScroller.startScroll(viewGroup.getScrollX(),viewGroup.getScrollY(),-viewGroup.getScrollX(),-viewGroup.getScrollY());
                //記住需要invalidate
                invalidate();
                break;
        }
    return true;
}

    @Override
    public void computeScroll() {
        super.computeScroll();
        if(mScroller.computeScrollOffset()){
            ((View)getParent()).scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
        //記住,需要不斷呼叫invalidate進行重繪
        invalidate();
        }
    }
}
以上五種方法就是常用的滑動View的方法。還有兩種方式能夠控制一個View的移動效果:屬性動畫和使用ViewDragHelper,對於這兩種方法,大家可以查閱網上資料,就不詳細介紹了。 (以上內容來源於看《Android群英傳》的總結)

相關推薦

Java單例模式實現方法

package offer; public class Test02 { /** * 01 餓漢模式 執行緒安全 */ public static class Singleton{ private final static Singleton

SpringBoot---系統啟動載入實現方法

1.CommandLineRunner  通過實現介面 CommandLineRunner 來實現,來完成專案啟動就載入所需要的資源。 import org.springframework.boot.CommandLineRunner; import org.springfra

選項卡的實現方法

今天總結一下頁面中選項卡實現的幾種方法。在實戰中會經常的使用到。下面的方法都是純HTML+CSS,並沒有用到JS,JS日後補上。 一、使用:target屬性實現選項卡        頁面的結構:(h

Fibonacci演算法實現方法

公式:F(n) = F(n-1) + F(n-2) 假設第一個數是0,第二個數是1 1.迭代加法: long long fabonacci_first(int n) { long long a = 0, b = 1; if (n == 1) return a;

SpringBoot實踐之---系統啟動載入實現方法init、servelt、CommandLineRunner

實際應用中,我們會有在專案服務啟動的時候就去載入一些資料或做一些事情這樣的需求。 方法一:CommandLineRunner 為了解決這樣的問題,Spring Boot 為我們提供了一個方法,通過實現介面 CommandLineRunner 來實現。很簡單,只需要一個類就可以

Android實現滑動方法

下面通過一個例子來總結實現滑動的幾種方式,例子的主要功能就是讓我們的自定義View能夠隨著手指的移動而移動。 佈局檔案如下: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:andro

記錄Android實現滑動方法

一、layou方法 程式碼示例如下,自定義一個view,在onTouchEvent()方法中計算手指滑動時的偏移量,呼叫view的layout()方法,在當前left、top、right、bottom上加上偏移量,實現view的滑動。 public clas

Android View事件(四)】View滑動實現滑動方法

1 前言 在前面的幾篇文章,我向大家介紹的都是單一View事件,而在這篇文章中,我將向大家介紹連續的事件 —— 滑動。 在安卓裝置上滑動幾乎是應用的標配,由於安卓手機螢幕較小,為了給使用者呈現更多的內容,就需要使用滑動來隱藏和顯示一些內容。

Android 實現滑動方法(三)scrollTo 與 scrollBy

scrollTo(x,y): 表示移動到一個座標點(x,y) scrollBy(dx,dy) : 表示移動的增量為dx,dy 如果在ViewGroup中使用scrollTo和scrollBy,那麼移

Android實現延時執行操作的方法

在Android開發中我們可能會有延時執行某個操作的需求,例如我們啟動應用的時候,一開始呈現的是一個引導頁面,過了兩三秒後,會自動跳轉到主介面。這就是一個延時操作。  下面是實現延時執行操作的幾種方法: 1.使用執行緒的休眠實現延時操作    new Thread() {

Android實現計時與倒計時的方法

                方法一Timer與TimerTask(Java實現)public class timerTask extends Activity{ private int recLen = 11; private TextView txtView; Timer timer = new Tim

Android實現延遲的方法小結

本文例項總結了Android實現延遲的幾種方法。分享給大家供大家參考,具體如下: 一、通過Thread new Thread(){ public void run(){ sleep(***); } }.start(); 通過ProgressDialog的使用來

Android實現滑動的七方法實踐

  在講解滑動之前,要先熟悉一下安卓的座標系。安卓檢視有兩個座標系,一個是Android座標系,一個是檢視座標系。前者以螢幕的最左上角為原點,向右為X軸正方向,向下為Y軸正方向。後者以父檢視的左上角為原點,其它與前者一致。   而獲取座標的方法也可以分為兩類,View提供的

Android實現截圖和截長圖功能的方法

一般情況下各種型號的手機都會有自帶的截圖功能,也會有諸如“開關機鍵+音量鍵”的截圖快捷鍵,只要手機是亮屏狀態,都會將手機螢幕的可視區域(包含狀態列)全部擷取下來。如果開發中想要調取系統的截圖功能,理論上講是可以的,需要在APK中呼叫“adb shell screencap -

Android實現非同步的方法

在Android專案中,有經驗的開發人員都知道,一些耗時的IO操作等都必須在子執行緒中去操作,那麼可以有哪些方法來開啟子執行緒呢,一般可以使用Java中自帶的幾種方法,也可以使用Andorid特有的一些類。 用Java來實現非同步 主要有兩種方法來實現非同步

Android實現滑動的7方法

    在Android4.x之後,滑動操作大量的出現在Android系統中,滑動的操作方式具有更好的使用者體驗。所以本章會對Android中 實現滑動效果的方式做一個小歸納。     在介紹滑動方法前,先講一下Android的座標系,Android的座標系分為兩種。  

Android 實現View滑動方式

關於View的滑動,Android中提供了許多方法,具體可以分為一下幾類: layout 在ACTION_MOVE中通過獲取x、y的偏移量動態佈局view,並禁止向父控制元件傳遞事件: @Override public boolean onTo

Android實現滑動的七方法

1.layout方法 每次移動後,呼叫layout()方法對自己重新佈局從而達到移動的效果 @Override public boolean onTouchEvent(MotionEvent event) { int x = (int) e

實現View 滑動方法

時間過得真快,一轉眼就要到10月了,這幾天風颳的厲害,氣溫驟降,看來秋天真的要來了! 今天我主要是給大家講一些實現View平滑的移動的方法,View 平滑移動的方法一般有一下三種: 1.通過View 本身提供的scrollTo / scrollBy 方法實現滑動 2.通過動

android 自定義view時,實現動起來的方法

前言 在自定義view時如何讓她動起來呢?本人在14年面世的時候就被問到了listview下拉重新整理時,如何下拉如何上移,還記得本人當初的答案是使用屬性動畫,被人好好的鄙視了一番,說多了,好了拔劍吧 offsetLeftAndRight(offsetX)