1. 程式人生 > >Android觸控事件(三)-觸控事件類使用例項

Android觸控事件(三)-觸控事件類使用例項

目錄

概述

本文主要介紹之前提到的AbsTouchEventHandle(自定義觸控事件處理類)及TouchUtils(觸控事件輔助工具類)如何結合一起使用.
使用的目的或者說達到的結果是:

簡單方便地完成介面元素的拖動與縮放

在整個過程中,介面元素的拖動與縮放工作完全交給以上兩個類處理,而不需要做任何其它的操作.只需要完成的是相關的一些介面實現與回撥而已.

使用流程

以下為兩個類結合使用的簡單流程,若不是特別理解可以略過,下面會一一詳細說明.

  • 建立一個專門用於繪製整個介面的類,Draw
  • 使Draw繼承自AbsTouchEventHandle,並實現重寫其所有抽象方法(暫時不需要處理)
  • 建立TouchUtils的例項物件,TestRectangleDraw實現TouchUtils裡的移動及縮放介面IMoveEventIScaleEvent
  • TouchUtils例項物件與其介面實現類物件繫結以方便回撥

使用AbsTouchEventHandle

我們知道,介面元素最終的顯示是以View的形式繪製到螢幕上.而View的繪製工作全部都是在onDraw()方法裡處理的.
但這裡我們需要建立一個新的類去完成繪製工作而不是直接通過View去完成工作.這是因為

AbsTouchEventHandle本身是個抽象類,意味著它必須被繼承才能使用.而自定義View必定是繼承自系統類View

,所以這是不可能再繼承另外一個類的

除此之外,使用全新的類專門處理繪製工作還有一個好處是: 繪製工作是獨立的,而不會與View本身的某些方法混淆在一起.這是一種類似組合的方式而不是巢狀的方式.
由於繪製類不繼承自View,則需要與顯示此繪製介面的View關聯起來,所以此繪製需要提供一些方法以將繪製介面成功連線到View上.

最後一個重要的點,AbsTouchEventHandle本質是實現了觸控事件介面View.OnTouchListener處理的,千萬不要忘了將ViewonTouchListener事件設定為當前的繪製類~~~

public class TestRectangleDraw
extends AbsTouchEventHandle{
private View mDrawView; public TestRectangleDraw(View drawView){ mDrawView=drawView; //必須將繪製View的觸控監聽事件替換成當前的類 mDrawView.setOnTouchListener(this); } //忽略抽象方法的重寫,後面使用 TouchUtils 時再處理 }

以上為AbsTouchEventHandle類的使用,當繼承此類時可以直接處理View的單擊事件,雙擊事件(拖動與縮放需要TouchUtils輔助)

使用TouchUtils

使用TouchUtils輔助工具類是為了方便處理拖動事件與縮放事件,一般的拖動事件及縮放事件都不需要再自定義,直接使用TouchUtils及實現相關的介面即可.
首先,根據之前有關TouchUtils的介紹文章,我們知道使用此工具類需要實現對應的介面,這是一個很重要的操作.
關於介面的實現並不需要一定是當前的繪製類,如果你喜歡完全可以使用一個新類去處理這些介面.但實際並沒有這個必要,這裡我們直接使用繪製類去實現這些介面

之後需要在繪製類中建立TouchUtils的例項物件,同時將介面實現物件與其繫結,以實現其拖動與縮放的有效性.

//為了方便檢視,忽略之前繼承的 AbsTouchEventHandle,只看介面的實現
public class TestRectangleDraw implements TouchUtils.IMoveEvent, TouchUtils.IScaleEvent{
    private TouchUtils mTouch;
    public TestRectangleDraw(View drawView){
        mDrawView=drawView;
        //必須將繪製View的觸控監聽事件替換成當前的類
        mDrawView.setOnTouchListener(this);
        mTouch=new TouchUtils();
        mTouch.setMoveEvent(this);
        mTouch.setScaleEvent(this);
    }
    //介面實現內容下面會詳細解釋,暫時忽略
}

以上即為TouchUtils的基本使用.下面是關於一些細節部分的處理.

細節易錯點

特別提出的是,這個使用上應該不會很難,但是在TouchUtils.IScaleEvent介面的實現上,很可能出錯率會很高.這並不是此兩個類的問題,而是在處理資料時可能會考慮不完善的問題(已經踩了幾次坑了),下面會有兩個實現類的對比.文章最後也會將兩個類完整地給出.可以做比較檢視.

關於TouchUtils.IMoveEvent

前面兩部分的操作是必須,這個地方只討論這個介面的具體實現.
這個介面是為了實現拖動操作的.介面本身不處理任何的拖動操作事件,只是為了

確認是否允許拖動操作;拖動操作的執行及拖動操作失誤時的處理.

這個介面一共有四個方法:

//是否允許X軸方向的拖動
boolean isCanMovedOnX(float moveDistanceX, float newOffsetX);
//是否允許Y軸方向的拖動
boolean isCanMovedOnY(float moveDistacneY, float newOffsetY);
//拖動事件(基本上就是重繪操作)
void onMove(int suggestEventAction);
//拖動失敗事件(不能拖動)
void onMoveFail(int suggetEventAction);

介面的功能應該是很明確的.下面給出一個簡單的實現.

//允許X軸方向的拖動
boolean isCanMovedOnX(float moveDistanceX, float newOffsetX){
    return true;
}
//允許Y軸方向的拖動
boolean isCanMovedOnY(float moveDistacneY, float newOffsetY){
    return true;
}
//通知View重繪
void onMove(int suggestEventAction){
    mDrawView.postInvalidate();
}
//拖動失敗事件(不能拖動)
void onMoveFail(int suggetEventAction){
    //一般都不需要特別處理,可以選擇提醒使用者不能拖動了
}

拖動事件介面的實現並不會有很大的麻煩,一般也不容易出錯.唯一的問題是在isCanMovedOn方法中根據實際的情況去確定什麼時候可以進行拖動什麼時候不可以(繪製元素邊界?還是達到螢幕邊界?)

關於TouchUtils.IScaleEvent

縮放回調事件會相對複雜一點.這是因為拖動的時候元素大小是不變的,也就是介面元素的本身的屬性都是不變的.僅僅改變的是座標.
但從關於TouchUtils的文章中我們已經是將座標的變化與元素本身的座標是分開的.即不管在任何時候,元素都只處理初始化時的座標,任何移動產生偏移的座標都由TouchUtils類去處理.
但是縮放是不一樣的.縮放時意味著元素本身的屬性會改變,大小,長寬等都會改變.包括自身的座標.

由於繪製的元素是什麼工具類無法確定,所以整個元素的變化操作只能交給繪製元素的類去處理.即工具類不負責縮放元素的屬性變化,只會告訴繪製類變化的比例.

基於這個原則,TouchUtils.IScaleEvent就有存在的需要了.同理,參考TouchUtils.IMoveEvent的方法,IScaleEvent也有四個方法

//是否允許縮放,縮放肯定是整個元素一起縮放的,不存在某個維度可以縮放而另外一個卻不可以的情況
boolean isCanScale(float newScaleRate);
//設定元素縮放比
void setScaleRate(float newScaleRate, boolean isNeedStoreValue);
//縮放操作(基本上是重繪)
void onScale(int suggestEventAction);
//縮放失敗操作(不能縮放的情況下)
void onScaleFail(int suggetEventAction);

以上四個方法應該也不難理解的.其中onScaleonScaleFail兩個方法是最容易的.isCanScale取決於使用者需求而是否複雜,在任何情況下都可以縮放直接返回true即可.
最重要的一個方法,也可能是最複雜和容易出錯的:setScaleRate,必須記住的是

setScaleRate是用於處理元素縮放屬性資料的.在一次縮放事件中,每一次回撥都是相對開始縮放前的原始元素大小的比例.

以下重點解釋此方法,本小節最後會給出此介面實現的完整程式碼.
一次縮放事件是指: 兩點觸控按下時到兩點觸控擡起時整個過程
開始縮放前原始元素大小是指: 兩點觸控按下時元素的大小

整個縮放過程的比例都是以 兩點按下時元素的大小為基礎的

在下面會使用兩個不同的情景來解釋此方法的使用.其中一個是TestCircleDraw,介面元素僅為一個圓形;
另外一個是TestRectangleDraw,介面元素僅為一個矩形;
通過這兩個實際的不同的介面元素的繪製來說明該方法使用時需要注意的一些問題

使用縮放前,我們需要確定的是元素縮放到底是需要縮放的是什麼?

TestCircleDraw圓形縮放

圓形縮放,本質需要縮放的是: 半徑

//全域性定義的半徑變數
//繪製時使用的半徑變數(包括縮放時半徑不斷變化也是使用此變數)
float mRadius;
//用於儲存每一次縮放後的固定半徑變數(僅在縮放後才會改變,其它時間不會改變)
float mTempRadius;

//實現方法
public void setScaleRate(float newScaleRate, boolean isNeedStoreValue) {
    //計算新的半徑
    mRadius = mTempRadius * newScaleRate;
    //當返回的標誌為true時,提醒為已經到了up事件
    //此時應該把最後一次縮放的比例當做最終的資料儲存下來
    if (isNeedStoreValue) {
        //縮放結束,儲存狀態
        mTempRadius = mRadius;
    }
}

這個地方應該不會很難理解.要記住~

mRadius是繪製時使用的變數,在整個縮放過程會不斷變化;而mTempRadius是用於暫存變數,僅會在縮放後改變,其它時候是不變的

圓形的應該是比較容易理解,這也是放在前面先講的原因,下面的是矩形,複雜度會提升一些.

TestRectangleDraw矩形縮放

同理,先考慮需要縮放的是什麼?
矩形需要縮放的必定是寬高,而不是座標,這個很重要.
由於矩形繪製時是使用RectF類來記錄矩形的屬性資料,此處我們也需要建立對應的變數來記錄縮放前後的資料.

//定義全域性變數
//繪製時使用的變數(同理,會不斷變化)
RectF mRectf;
//用於儲存每一次縮放後的資料
RectF mTempRectF;

//介面方法實現
public void setScaleRate(float newScaleRate, boolean isNeedStoreValue) {
    //計算新的寬度
    float newWidth = mTempRectf.width() * newScaleRate;
    //計算新的高度
    float newHeight = mTempRectf.height() * newScaleRate;
    //計算中心位置
    float centerX = mTempRectf.centerX();
    float centerY = mTempRectf.centerY();
    //根據中心位置調整大小
    //此處確保了縮放時是按繪製物體中心為標準
    mDrawRectf.left = centerX - newWidth / 2;
    mDrawRectf.top = centerY - newHeight / 2;
    mDrawRectf.right = mDrawRectf.left + newWidth;
    mDrawRectf.bottom = mDrawRectf.top + newHeight;
    //縮放事件結束,需要儲存資料
    if (isNeedStoreValue) {
        mTempRectf = new RectF(mDrawRectf);
    }
}

可見,矩形的儲存工作比圓形複雜得多,當然,實際的流程並不會很難理解.當需要處理的元素會比較複雜時,那麼儲存工作需要做的事情將會更多,這種時候很容易會出錯,所以這個方法即是縮放的重點,也是容易出錯的地方.
最後必須注意的是:

縮放肯定會存在一個縮放中心,需要確定元素到底是要中心縮放還是以某點為縮放中心.

如以上矩形,若更新矩形座標時使用的是

mDrawRectf.right=mDrawRectf.left+newWidth;
mDrawRectf.bottom=mDrawRectf.top+newHeight;

此時將以左上解為縮放中心,而不是元素物體的中心.

圓形/矩形縮放介面實現程式碼

圓形:

@Override
public boolean isCanScale(float newScaleRate) {
    return true;
}

@Override
public void setScaleRate(float newScaleRate, boolean isNeedStoreValue) {
    //更新當前的資料
    //newScaleRate縮放比例一直是相對於按下時的介面的相對比例,所以在移動過程中
    //每一次都是要與按下時的介面進行比例縮放,而不是針對上一次的結果
    //使用這種方式一方面在縮放時的思路處理是比較清晰的
    //另一方面是縮放的比例不會資料很小(若相對於上一次,每一次move移動幾個畫素,
    //這種情況下縮放的比例相對上一次肯定是0.0XXXX,資料量一小很容易出現一些不必要的問題)
    mRadius = mTempRadius * newScaleRate;
    //當返回的標誌為true時,提醒為已經到了up事件
    //此時應該把最後一次縮放的比例當做最終的資料儲存下來
    if (isNeedStoreValue) {
        mTempRadius = mRadius;
    }
}

@Override
public void onScale(int suggestEventAction) {
    mDrawView.postInvalidate();
}

@Override
public void onScaleFail(int suggetEventAction) {

}

矩形

@Override
public boolean isCanScale(float newScaleRate) {
    return true;
}

@Override
public void setScaleRate(float newScaleRate, boolean isNeedStoreValue) {
    float newWidth = mTempRectf.width() * newScaleRate;
    float newHeight = mTempRectf.height() * newScaleRate;
    //計算中心位置
    float centerX = mTempRectf.centerX();
    float centerY = mTempRectf.centerY();
    //根據中心位置調整大小
    //此處確保了縮放時是按繪製物體中心為標準
    mDrawRectf.left = centerX - newWidth / 2;
    mDrawRectf.top = centerY - newHeight / 2;
    mDrawRectf.right = mDrawRectf.left + newWidth;
    mDrawRectf.bottom = mDrawRectf.top + newHeight;
    //此方式縮放中心為左上角
    //mDrawRectf.right=mDrawRectf.left+newWidt
    //mDrawRectf.bottom=mDrawRectf.top+newHeig
    if (isNeedStoreValue) {
        mTempRectf = new RectF(mDrawRectf);
    }
}

@Override
public void onScale(int suggestEventAction) {
    mDrawView.postInvalidate();
}

@Override
public void onScaleFail(int suggetEventAction) {

}

繪製View的其它細節

onDraw(Canvas)

由以上得知,繪製介面時本質是View.onDraw()方法,而繪製類只是我們建立的一個類,所以我們也提供了對應的方法提供給自定義View在onDraw()方法中呼叫

//忽略繼承類及介面等無關因素
public class TestRectangleDraw{
    public void onDraw(Canvas canvas){
        //繪製操作
    }
}

TouchUtilsAbsTouchEventHandle抽象方法中的使用

TouchUtils類中有對應的方法處理拖動及縮放事件,直接在抽象方法中呼叫即可;至於單擊和雙擊事件不由TouchUtils處理.

@Override
public void onSingleTouchEventHandle(MotionEvent event, int extraMotionEvent) {
    //工具類預設處理的單點觸控事件
    mTouch.singleTouchEvent(event, extraMotionEvent);
}

@Override
public void onMultiTouchEventHandle(MotionEvent event, int extraMotionEvent) {
    //工具類預設處理的多點(實際只處理了兩點事件)觸控事件
    mTouch.multiTouchEvent(event, extraMotionEvent);
}

@Override
public void onSingleClickByTime(MotionEvent event) {
    //基於時間的單擊事件
    //按下與擡起時間不超過500ms
}

@Override
public void onSingleClickByDistance(MotionEvent event) {
    //基於距離的單擊事件
    //按下與擡起的距離不超過20畫素(與時間無關,若按下不動幾小時後再放開只要距離在範圍內都可以觸發)
}

繪製操作注意

在繪製元素時,需要注意的是,TouchUtils處理了所有的與移動相關的偏移量,並儲存到TouchUtils中.所以繪製元素時需要將該偏移量使用上才可以真正顯示出移動後的介面.
以矩形繪製為例

//正常繪製矩形
//canvas.drawRect(mDrawRectf.left,             mDrawRectf.top,mDrawRectf.right,mDrawRectf.bottom,mPaint);
//正確繪製矩形
float offsetX=mTouchUtils.getOffsetX();
float offsetY=mTouchUtils.getOffsetY();
//必須將offset偏移量部分新增到繪製的實際座標中才可以正確繪製移動後的元素
canvas.drawRect(mDrawRectf.left + offsetX,
                mDrawRectf.top + offsetY,
                mDrawRectf.right + offsetX,
                mDrawRectf.bottom + offsetY,
                mPaint);

矩形原始碼

//矩形繪製類
public class TestRectangleDraw extends AbsTouchEventHandle implements TouchUtils.IMoveEvent, TouchUtils.IScaleEvent {
    //建立工具
    private TouchUtils mTouch = null;
    //儲存顯示的View
    private View mDrawView = null;
    //畫筆
    private Paint mPaint = null;
    //繪製時使用的資料
    private RectF mDrawRectf = null;
    //縮放時儲存的縮放資料
    //此資料儲存的是每一次縮放後的資料(螢幕不存在觸控時,才算縮放後,縮放時為滑動螢幕期間)
    private RectF mTempRectf = null;

    public TestRectangleDraw(View drawView) {
        mTouch = new TouchUtils();
        mTouch.setMoveEvent(this);
        mTouch.setScaleEvent(this);
        mDrawView = drawView;
        mDrawView.setOnTouchListener(this);

        mPaint = new Paint();
        mPaint.setAntiAlias(true);

        //起始位置為 300,300
        //寬為200,長為300
        mDrawRectf = new RectF();
        mDrawRectf.left = 300;
        mDrawRectf.right = 500;
        mDrawRectf.top = 300;
        mDrawRectf.bottom = 600;

        //必須暫存初始化時使用的資料
        mTempRectf = new RectF(mDrawRectf);

        mTouch.setIsShowLog(false);
        this.setIsShowLog(false, null);
    }

    //回滾移動位置
    public void rollback() {
        mTouch.rollbackToLastOffset();
    }

    public void onDraw(Canvas canvas) {
        mPaint.setColor(Color.BLACK);
        mPaint.setStyle(Paint.Style.FILL);
        //此處是實際的繪製介面+偏移量,偏移量切記不能儲存到實際繪製的資料中!!!!
        //不可以使用 mDrawRectf.offset(x,y)
        canvas.drawRect(mDrawRectf.left + mTouch.getDrawOffsetX(), mDrawRectf.top + mTouch.getDrawOffsetY(),
                mDrawRectf.right + mTouch.getDrawOffsetX(), mDrawRectf.bottom + mTouch.getDrawOffsetY(),
                mPaint);
    }

    @Override
    public void onSingleTouchEventHandle(MotionEvent event, int extraMotionEvent) {
        //工具類預設處理的單點觸控事件
        mTouch.singleTouchEvent(event, extraMotionEvent);
    }

    @Override
    public void onMultiTouchEventHandle(MotionEvent event, int extraMotionEvent) {
        //工具類預設處理的多點(實際只處理了兩點事件)觸控事件
        mTouch.multiTouchEvent(event, extraMotionEvent);
    }

    @Override
    public void onSingleClickByTime(MotionEvent event) {
        //基於時間的單擊事件
        //按下與擡起時間不超過500ms
    }

    @Override
    public void onSingleClickByDistance(MotionEvent event) {
        //基於距離的單擊事件
        //按下與擡起的距離不超過20畫素(與時間無關,若按下不動幾小時後再放開只要距離在範圍內都可以觸發)
    }

    @Override
    public void onDoubleClickByTime() {
        //基於時間的雙擊事件
        //單擊事件基於clickByTime的兩次單擊
        //兩次單擊之間的時間不超過250ms
    }

    @Override
    public boolean isCanMovedOnX(float moveDistanceX, float newOffsetX) {
        return true;
    }

    @Override
    public boolean isCanMovedOnY(float moveDistacneY, float newOffsetY) {
        return true;
    }

    @Override
    public void onMove(int suggestEventAction) {
        mDrawView.postInvalidate();
    }

    @Override
    public void onMoveFail(int suggetEventAction) {

    }

    @Override
    public boolean isCanScale(float newScaleRate) {
        return true;
    }

    @Override
    public void setScaleRate(float newScaleRate, boolean isNeedStoreValue) {
        float newWidth = mTempRectf.width() * newScaleRate;
        float newHeight = mTempRectf.height() * newScaleRate;
        //計算中心位置
        float centerX = mTempRectf.centerX();
        float centerY = mTempRectf.centerY();
        //根據中心位置調整大小
        //此處確保了縮放時是按繪製物體中心為標準
        mDrawRectf.left = centerX - newWidth / 2;
        mDrawRectf.top = centerY - newHeight / 2;
        mDrawRectf.right = mDrawRectf.left + newWidth;
        mDrawRectf.bottom = mDrawRectf.top + newHeight;
        //此方式縮放中心為左上角
//        mDrawRectf.right=mDrawRectf.left+newWidth;
//        mDrawRectf.bottom=mDrawRectf.top+newHeight;
        if (isNeedStoreValue) {
            mTempRectf = new RectF(mDrawRectf);
        }
    }

    @Override
    public void onScale(int suggestEventAction) {
        mDrawView.postInvalidate();
    }

    @Override
    public void onScaleFail(int suggetEventAction) {

    }
}

自定義VIEW繪製顯示

/**
 * Created by CT on 15/9/25.
 * 此View演示了AbsTouchEventHandle與TouchUtils怎麼用
 */
public class TestView extends View {
    //建立繪製圓形示例介面專用的繪製類
    TestCircleDraw mTestCircleDraw = new TestCircleDraw(this, getContext());
    //建立繪製方形示例介面專用的繪製類
    TestRectangleDraw mTestRectfDraw = new TestRectangleDraw(this);

    public TestView(Context context) {
        super(context);
    }

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

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

    //回滾移動位置
    public void rollback() {
        mTestRectfDraw.rollback();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //實際上的繪製工作全部都交給了繪製專用類
        //在繪製很複雜的介面時,這樣可以很清楚地分開
        //繪製與檢視,因為檢視本身可能還要處理其它的事件(比如來自繪製事件中回撥的事件等)
        //而且View本身的方法就夠多了,還加一很多繪製方法,看起來也不容易理解
//        mTestCircleDraw.onDraw(canvas);
        mTestRectfDraw.onDraw(canvas);
    }
}

GitHub示例地址

示例GIF

觸控事件GIF

回到目錄

相關推薦

Android觸控事件()-觸控事件使用例項

目錄 概述 本文主要介紹之前提到的AbsTouchEventHandle(自定義觸控事件處理類)及TouchUtils(觸控事件輔助工具類)如何結合一起使用. 使用的目的或者說達到的結果是: 簡單方便地完成介面元素的拖動與縮放 在整個過程

android面試題之觸控事件分發與處理簡述

android觸控事件分發與處理     android的分發機制:由父控制元件判斷是否攔截,如果不攔截事件,則繼續分發到子控制元件,然後一直分發下去。     處理:與分發相反,由子控制元件先處理事件,如果子控制元件不處理,則交給父控制元件處理,一直向上傳遞,直到那個控制

quick-cocos2dx lua語言講解 (動作,定時器,觸控事件,工程的的講解)

--MainScene部分 -- display.newScene 建立一個場景 --  在quick裡面我們的控制元件、精靈  一般是載入到場景上的  local MainScene = class("MainScene", function()     return d

Android應用層View觸控事件分發機制

概述 前兩篇部落格從原始碼的角度對View繪製流程進行了分析,那麼當用戶需要跟View進行互動的時候,比如點選按鈕的時候,按鈕是如何得到點選事件的呢?當用戶在螢幕上進行點選或觸控的時候,事件是如何傳遞到各個View的呢?這個就是本篇部落格研究的點:View事件

Android View】Android中View對觸控事件的處理和傳遞dispatchTouchEvent、onInterceptTouchEvent

View中存在dispatchTouchEvent、onTouchEvent兩個方法。 而ViewGroup中則存在dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent三個方法。 呼叫順序依次為dispatchTouch

cocos creator Touch事件應用(觸控選擇多個子節點)

event false 等待 結果 ble cte mask convert 計算 最近參與了cocos creator的研究,開發小遊戲,結果被一個事件坑得不行不行的。現在終於解決了,分享給大家。 原理 1.觸控事件是針對節點的 2.觸控事件的冒泡,是直接關系冒泡,父

Android的按鈕單擊事件及監聽器的實現方式(附例項)

第一種:匿名內部類作為事件監聽器類 大部分時候,事件處理器都沒有什麼利用價值(可利用程式碼通常都被抽象成了業務邏輯方法),因此大部分事件監聽器只是臨時使用一次,所以使用匿名內部類形式的事件監聽器更合適,實際上,這種形式是目前是最廣泛的事件監聽器形式。上面的程式

手機端觸控touchmove 關閉預設事件和開啟預設事件

<head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1.0,maximum-scale=1.0,minimum-sca

cocos2dX 事件觸控事件觸控事件集合

今天, 我們來學習cocos2dX裡面的觸控事件與觸控事件合集, 現在的手機遊戲互動基本上都是通過觸控互動的, 所以大家明白這節的重要性了吧, 本節篇幅比較大, 所以我就不扯閒話了 先來看看常用函式: 觸控事件: addTargeteDelegate( 誰使用, 優先順序

Android事件分發機制事件分發工作流程

## 前言 很高興遇見你~ 本文是事件分發系列的第三篇。 在前兩篇文章中,[Android事件分發機制一:事件是如何到達activity的?](https://juejin.cn/post/6918272111152726024) 分析了事件分發的真正起點:viewRootImpl,Activity只是

android入門 — ListView點擊事件

.com 方法 itemclick text his class 處理 分享 str listView中提供了兩種點擊事件的處理方法,分別是OnItemClick和OnItemLongClick。 OnItemClick提供的是點擊操作的處理,OnItemLongClic

Android 輸入管理服務-輸入事件到達之後的處理流程

content 例如 enter 技術 fontsize tail 流程 ref ora 接上一篇博客“Android 輸入管理服務啟動過程的流程”。這兩天分析了Android 輸入管理服務接收到輸入事件之後的處理流程,詳細流程例如以下面兩圖所看到的:

js 事件的綁定

() tag eve nod mouseup als listen src cell 第一種:前段常規綁定: <button type="button" class="recolor" onclick="reCol(‘rowIndex‘,‘colIndex‘

背水一戰 Windows 10 (68) - 控件(控件基): UIElement - Pointer 相關事件, Tap 相關事件, Key 相關事件, Focus 相關事件

tar release 關於 場景 npr 相對 capture soft etc [源碼下載] 背水一戰 Windows 10 (68) - 控件(控件基類): UIElement - Pointer 相關事件, Tap 相關事件, Key 相關事件, Focus 相關

Android 自定義組件 事件處理

items int ems set rect 獲取 控件 pan highlight 以點擊事件為例: 覆寫方法: public boolean dispatchTouchEvent(MotionEvent event); 可以從MotionEvent 獲取事件坐標,

Android onClick 按鈕單擊事件 四種常用寫法

匿名內部類 inpu find private highlight 事件監聽 instance super eat XML文件 <EditText android:layout_width="match_parent" android

從PRISM開始學WPF(六)MVVM(事件聚合器EventAggregator?

rec 行動 manage using panel mark 控件 lock object 從PRISM開始學WPF(一)WPF? 從PRISM開始學WPF(二)Prism? 從PRISM開始學WPF(三)Prism-Region? 從PRISM開始學WPF(四)Prism

gtest 事件機制

sting include 一個 兩個 end 程序 mod scrip rtu 前言:   1.首先說明gtest中事件的結構層次:      測試程序:一個測試程序只有一個main函數,也可以說是一個可執行程序是一個測試程序。該級別的事件機制會在程序的開始和結束

Vue.js-03:第章 - 事件修飾符的使用

 一、前言   熟悉了 Vue 的指令系統後,在實際開發中,不可避免的會使用到對於事件的操作,如何處理 DOM 事件流,成為我們必須要掌握的技能。不同於傳統的前端開發,在 Vue 中給我們提供了事件修飾符這一利器,使我們可以便捷的處理 DOM 事件,本章,一起來學習如何使用事件修飾符來實現對於 D

【Vue.js 牛刀小試】03:第章 - 事件修飾符的使用

前言         熟悉了 Vue 的指令系統後,在實際開發中,不可避免的會使用到對於事件的操作,如何處理 DOM 事件流,成為我們必須要掌握的技能。不同於傳統的前端開發,在 Vue 中給我們提供了事件修飾符這一利器,使我們可