1. 程式人生 > >onTouchEvent(一) 你所必須知道的座標詳解

onTouchEvent(一) 你所必須知道的座標詳解

onTouchEvent(MotionEvent event) 這個方法是定製手勢操作的重點,根據業務不同寫法也各不相同,然而最重要也是最基礎的是其座標的含義,因為不管什麼業務都是需要根據其座標來進行判斷、操作等。
參照網上的demo來寫相信大部分人都能做出來,然而我是一個有時候很鑽牛角尖的人,不搞懂座標就寫不下去的人。
————部分資料來源於醫生的《Android群英傳》————

原點

首先原點(0,0)這個大家都知道就不多說了。
這裡寫圖片描述
兩個點A、B,A的X軸座標為20,B的X軸座標為180,X軸的正方向為以水平方向向右,故左邊的X值越來越小,右邊的X值越來越大。

滑動

    Scroller mScroller;
    float
mLastX; float mLastY; @Override public boolean onTouchEvent(MotionEvent event) { // return super.onTouchEvent(event); int dx = 0; int dy = 0; float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: if
(!mScroller.isFinished()) mScroller.abortAnimation(); mLastX = x; mLastY = y; break; case MotionEvent.ACTION_MOVE: if (!mScroller.isFinished()) mScroller.abortAnimation(); dx = (int
) (mLastX - x); dy = (int) (mLastY - y); scrollBy(dx,dy); break; } return true; }

這是一個最簡單的手勢控制程式碼。
mScroller是一個輔助類。後面再介紹,在這段程式碼裡的作用是:判斷移動的動畫是否結束,未結束立即結束,座標移動至最終座標值。
MotionEvent 的getX()、getY()是獲取當前觸控點距離控制元件的座標。
mLastX、mLastY快取上一次的座標。

手勢說明:
上滑:Y座標減小
下滑:Y座標增大
左滑:X座標減小
右滑:X座標增大

根據原點(0,0),X/Y軸正方向可以得出該結果,例如左滑X軸座標慢慢靠近原點所以值會越來越小,反之越來越大。

關鍵在於下面三行程式碼。

    1.            dx = (int) (mLastX - x);
    2.            dy = (int) (mLastY - y);
    3.            scrollBy(dx,dy);

1和2大家可能照著網上寫並沒有注意,而這篇文章主要是因為它們而誕生的。為什麼是上一次操作的座標減去當前操作的座標?雖然打log看值和不停測試最終也能得出結果,但是我求知慾比較大(好奇心殺死貓)。

    public void scrollBy(int x, int y) {
        scrollTo(mScrollX + x, mScrollY + y);
    }

這是3的原始碼。
mScrollX是當前的X軸偏移量, mScrollY是當前Y軸的偏移量。

public void scrollTo(int x, int y) {
        if (mScrollX != x || mScrollY != y) {
            int oldX = mScrollX;
            int oldY = mScrollY;
            mScrollX = x;
            mScrollY = y;
            invalidateParentCaches();
            onScrollChanged(mScrollX, mScrollY, oldX, oldY);
            if (!awakenScrollBars()) {
                postInvalidateOnAnimation();
            }
        }
    }

scrollTo()是滑動到指定的座標。

滑動偏移量

左滑X軸座標會越來越小。根據剛才的scrollBy()原始碼來說X的偏移為mScrollX + x,為了要左滑x就必須為負值。
down:X=480 , move:X=400
故dx = (400 - 480); // dx = -80;
但當你以為搞定的時候,實際效果view不是左移,而是右移!!!
實際程式碼為:dx = (int) (mLastX - x);
即: dx = 480 - 400 ; //dx = 80;
值為正值!!!
Why!
為什麼和說好的不一樣?

其中關鍵是移動的並不是ViewGroup的內容。

這裡寫圖片描述
首先螢幕大小和ViewGroup一樣大,當前只能顯示藍色的ChildView。
根據實際程式碼測試出,左滑顯示出ChildView2需要傳入正的X值。
這是為什麼呢?

Canvas是內容實際的載體,draw(Canvas canvas)畫的內容都是在Canvas上的。而ViewGroup是實際展示的區域。
也就是說一共兩層,底層的Canvas承載著繪製出來的view,ViewGroup在上層(z軸值大於Canvas),ViewGroup以外區域是不可見區域,可見區域為ViewGroup區域。

scrollBy()實際移動的是ViewGroup。
例如:
scrollBy(80,0);ViewGroup的X + 80,即layout(l+80,t,r+80,b);Canvas並沒有移動,ChildView也就沒有移動。
ViewGroup向右移了80,Canvas沒有移動,就變相的相當於內容向左移動了80。
scrollBy(-80,0);即layout(l-80,t,r-80,b),ViewGroup向左移動了80,相當於內容向右移動了80。

到此就明白了為什麼偏移量的計算公式是mLastX - x的原因了。

mScrollX 是一個很重要的值,其累計了偏移量,在做滑動操作用於邏輯判斷,獲取的api是getScrollX()。//mScrollY類似函式簽名。

本篇到這裡就結束了,當然當前只是虛擬碼,跑起來是有偏差的,只是能實現滑動而已,跟實際使用還差了那麼一些邏輯處理。下一篇會結合Scroller和getScrollX()、getScrollY()實現一個完整的demo。

相關推薦

onTouchEvent() 必須知道座標

onTouchEvent(MotionEvent event) 這個方法是定製手勢操作的重點,根據業務不同寫法也各不相同,然而最重要也是最基礎的是其座標的含義,因為不管什麼業務都是需要根據其座標來進行判斷、操作等。 參照網上的demo來寫相信大部分人都能做

必須知道的三種基本求兩個數最大公約數的演算法

1 迭代法求最大公約數 /*迭代法求最大公約數 *原理:m n r;將r賦值給n,n賦值給m */ #include <iostream> using namespace std; int Gcd(int m, int n) { int r; r =

知道的String(String系列

String1、String定義 >通過源碼,String是由final修飾的,不能被繼承,實現序列化,其中序列化的標識是由定義的變量處理,serialVersionUID和serialPersistentFields。其中另外兩個變量是char數組和hash。 ![](http://i2.51c

筆記轉載 HTTP [轉]HTTP協議,知道

[轉]HTTP協議詳解,你所不知道的   什麼是HTTP協議 協議是指計算機通訊網路中兩臺計算機之間進行通訊所必須共同遵守的規定或規則,超文字傳輸協議(HTTP)是一種通訊協議,它允許將超文字標記語言(HTML)文件從Web伺服器傳送到客戶端的瀏覽器

知道的console.log()(console.log

console.log,作為一個前端開發者,想必每天都會用它來做分析除錯,但這個簡單函式背後你所不知道的一面,很多人未必使用過,有一些也是很方便使用的 基礎 首先,簡單科普這個函式的作用。前端開發者可以在js程式碼的任何部分呼叫console.log,然後你就可

Android 那些知道的Bitmap物件

我們知道Android系統分配給每個應用程式的記憶體是有限的,Bitmap作為消耗記憶體大戶,我們對Bitmap的管理稍有不當就可能引發OutOfMemoryError,而Bitmap物件在不同的Android版本中存在一些差異,今天就給大家介紹下這些差異,並提供一些在使用B

Android中Context ---- 知道的Context

             前言:本文是我讀《Android核心剖析》第7章 後形成的讀書筆記 ,在此向欲瞭解Android框架的書籍推薦此書。         大家好,  今天給大家介紹下我們在應用開發中最熟悉而陌生的朋友-----Context類 ,說它熟

關於MFi認證必須知道的事情

MFiLogo 前面我寫了一篇文章《iOS App連線外設的幾種方式》,其中EAP和NCM是都需要做MFi認證。對於蘋果的MFI認證,對iOS開發的同學來說其實是一個比較陌生並且繁瑣的topic,因為網上資料確實很少,百度Google幾乎都查不到啥資料,而且MFi認證門檻比較高,流程比較複雜,週期很

Java泛型()——知道的那些泛型背後

一、泛型 1、編譯期確定型別安全——泛型(Generics) 泛型是提供給Javac編譯器使用的。可以限定集合中輸入的型別,讓編譯器在編譯期間避免原始程式的非法輸入,編譯器編譯帶型別說明的集合時會去掉“型別”資訊,使程式執行效率不受影響,對

知道的ASP.NET Core MVC/WebApi基礎系列 ()

tin -c 覆蓋 文件版本號 重寫 true ets 外部 看到了 轉自博客:https://www.cnblogs.com/CreateMyself/p/9235968.html 前言 最近發表的EF Core貌似有點多,可別誤以為我只專攻EF Core哦,私下有時

知道的AWS 雲服務清單(71種)

亞馬遜 系統管理員 雲計算 應用程序 可擴展性 導讀AWS,即亞馬遜 Web 服務,是一個提供了一系列按使用計費的 web 服務的雲平臺。 它是迄今為止最為著名的雲平臺之一。由於其靈活性、有效性、彈性、可測量性和無須維護,所以有一些企業正逐步把他們的業務遷移到雲端。 由於許多公司目前在使用

知道的單例模式和多線程並發在單例模式中的影響

影響 編程問題 rop key 是我 提升 註意 特性 是不是 單例對象(Singleton)是一種常用的設計模式。在Java應用中,單例對象能保證在一個JVM中,該對象只有一個實例存在。這樣的模式有幾個好處: 1、某些類創建比較頻繁,對於一些大型的對象,這是一筆很大的系

重拾JavaScript(2)之console的知道的功能

斷言 adding devel bcf dev ces com 字符 bom JavaScript最常用的調試工具就是console.info()了。console是瀏覽器中window對象的屬性之一,由瀏覽器對象模型(BOM)提供,作用是訪問瀏覽器控制臺,你可以通過

須要知道的項目管理知識

控制 包含 pos 能夠 con 結束時間 經理 人員 困難 原創文章。轉載請註明。 當你在一個新環境、面對一個復雜的項目須要由你來負責的時候,請不要驚慌著急,經過我多年實踐經驗,通過下面幾點能夠幫到你。 一、分解項目。對於復雜龐

java中知道的CAS操作

sta mar 一個 swap 不知道 通過 樂觀 變換 沒有 1.CAS是什麽   Compare and Swap(比較並操作),由處理器架構支持,語義是如果當前值V和舊值A相同,則將當前值修改為B,如果不相同則不修改。CAS操作采用的是樂觀鎖技術,當多線程同時修改某個

知道的 【ModuleNotFoundError: No module named ''; '' is not a package】

is not a package一、背景介紹 1. 工具目錄結構 為了便於統一管理一些小工具,在本地創建了一個mytools的目錄,子目錄的結構如下: 2.python搜索路徑在環境變量中,增加了PYTHONPATH的設置,value為‘e:\mytools\lib\python‘。二、問題

Go基礎之--位操作中知道的用法

turn 自己 use 應用 const 代碼 只需要 寫法 直接 之前一直忽略的就是所有語言中關於位操作,覺得用處並不多,可能用到也非常簡單的用法,但是其實一直忽略的是它們的用處還是非常大的,下面先回顧一下位操作符的基礎 位操作符 與操作:&1 & 1 =

知道的,Java 中操作符的秘密?

tint 正常的 示例 itl 相等 params obi equal 拷貝 在 Java 編程的過程中,我們對數據的處理,都是通過操作符來實現的。例如,用於賦值的賦值操作符、用於運算的運算操作符等、用於比較的比較操作符,還包括邏輯操作符、按位操作符、移位操作符、三元操作符

關於字符編碼,需要知道的(ASCII,Unicode,Utf-8,GB2312…)

tle cati http char 表示 編寫 編號 小端 調用 字符編碼的問題看似很小,經常被技術人員忽視,但是很容易導致一些莫名其妙的問題。這裏總結了一下字符編碼的一些普及性的知識,希望對大家有所幫助。 還是得從ASCII碼說起 說到字符編碼,不得不說ASCII碼的簡

Android Service完全解析,關於服務知道的一切(下)

並且 無法 數據類型 界面 其它 wid logcat listen 程序崩潰 文章轉載至:http://blog.csdn.net/guolin_blog/article/details/9797169 這是郭霖寫的.......就是寫 "第一行代碼"的那個厲害人物,大