1. 程式人生 > >安卓Tv開發(一)移動智慧電視之焦點控制(觸控事件)

安卓Tv開發(一)移動智慧電視之焦點控制(觸控事件)

      前言:移動智慧裝置的發展,推動了安卓另一個領域,包括智慧電視和智慧家居,以及可穿戴裝置的大量使用,但是這些裝置上的開發並不是和傳統手機開發一樣,特別是焦點控制和使用者操作體驗風格上有很大的區別,本系列博文主要用TV播放器的實現去了解下在智慧裝置上的開發一個APP的流程,實現遙控器控制焦點移動,方向鍵模擬滑鼠,並完成線上視訊直播,手機當遙控器使用等相關功能。點選檢視原文 ,轉載請說明出處 :http://blog.csdn.net/sk719887916

     說到安卓TV上的APP應用,最主要還是看焦點控制,其他和手機APP無多大區別。比如常見的TV版本視訊播放器,TV瀏覽器,以及電視遊戲,都採用九宮格的UI視覺 demoUI如下

  

實現這個ui很容易,但是要實現遙控器上下左右控制並實現動畫放大效果,到邊緣進行翻頁效果,很多同學就不知道怎麼做了 ,看到很多人在手機上實現的手機UI很炫,但是貌似

沒有一篇講解TV或者電視盒子上應用開發的列子的,包括點選翻頁,或者移動,在這個TV開發入門的文章中,本人以微小的技術給大家先說下安卓事件焦點機制,之後的幾篇文章中,

本人將結合自己經驗,詳細說明安卓TV專案開發,安卓線上電視demo,實現一個TV上的視訊應用,前提是要學會自定義view,,也要學會android事件機制,,必須先了解觸控事件,

MotionEvent是必要,接下來本蝙給大家說下MotionEvent具體原理,,下篇將會說道鍵盤點選事件KeyEvent。

安卓主要點選事件


android下,事件的發生是在監聽器下進行,android系統可以響應按鍵事件和觸控式螢幕事件,事件說明如下:

onClick(View v) 一個普通的點選按鈕事件

onlongClick(View v) 一個普通的點選長按按鈕事件

boolean onKeyMultiple(int keyCode,int repeatCount,KeyEvent event)多個事件連續時發生,用於按鍵重複,必須過載@Override實現

boolean onKeyDown(int keyCode,KeyEvent event) 用於在按鍵進行按下時發生

boolean onKeyUp(int keyCode,KeyEvent event

 用於在按鍵進行釋放時發生

boolean onKeyLongPress(int keyCode, KeyEvent event)當你長時間按時發生

onTouchEvent(MotionEvent event) 觸控式螢幕事件,當觸控式螢幕幕時發生(暫時簡單的這麼理解,後做詳細說明)

boolean dispatchTouchEvent(MotionEvent event)  觸控時負責事件傳遞必須過載@Override實現 (View和Activity都可以進行分發)

     當然也有傳遞KeyEvent的方法 

boolean onInterceptTouchEvent(MotionEvent event)  觸控時負責事件攔截ViewGroup負責事件攔截。

Event事件機制

 在引出下文之前 我們先大致瞭解下Android事件機制,安卓事件機制主要包含事件的攔截,傳遞(分發),響應(消費)。在翻閱了很多文章後,再結合谷歌官方文章總結出,安卓每個事件都會進行以上三種過程。那麼接下來我們先開始理解下事件的整個過程

 (1)Event事件的攔截


   onInterceptTouchEvent(),安卓中此事件負責攔截一個使用者產生的點選或者觸控事件,主要起終止傳遞作用,當用戶點觸控產生一個事件時,由上層(view,Activity)傳入事件時,此方法負責攔截,攔截後將交由本控制元件去消費當前事件,如果無需攔截,則繼續交由下層的view去自己傳遞和分發。具體如下:     如果返回true,則代表攔截此事件,那麼事件就不會往子控制元件進行傳遞,由當前view進行呼叫onTouchEvent()來響該事件。反之 返回false 不攔截,事件將繼續傳遞  則由子view去呼叫自己的 dispatchTouchEvent()  去分發, 最後由具體的控制元件去消費此事件。 注意:很多書中和部落格中忽視了一點,當然 onInterceptHoverEvent() 也擁有攔截權利,但是它和OnInterCeptTouchEvent()有細微區別,此方法主要處理滑動事件,通俗講就是當產生有位移的事件時(列如當我們的觸控事件由產生速率的時候)觸發此方法。

 (2)Event事件的傳遞


dispatchEvent(MotionEvent event)  負責事件的排程,很多人稱之為分發和傳遞也一個意思,主要負責將事件交由哪個控制元件去處理,如果自己不想處理,則可以繼續往下傳遞,想處理則觸發本身view的ontuchEvent()此方法也返回bool型別,返回ture代表傳遞,返回false代表不傳遞,和我們的事件攔截恰恰相反,對於初學者來說很容易搞糊塗,本事件Activty,ViewGroup,View都擁有處理權,主要將事件負責轉發,無論交由別人處理還是自己,其實都在充當排程角色,是事件的核心。

 (3)Event事件響應

      安卓中事件具體處理由onTouchEvent()  來執行,此階段主要負責事件的消費響應,通過處理完事件後,然後逐步向上級彙報,如果消費了上次則不會再進行做響應消費處理,只會繼續返回給根佈局。
  此方法返回布林型別,如果消費了此事件,則會呼叫上級的此方法,預設返回false做處理,如果返回true,則代表不消費此時間 ,讓上級呼叫本方法去做處理,逐步網上彙報,直到Activity得到訊息為止。

 (4 (4 )Event傳遞整個過程

          通過上面三個各自的方法,我們已經瞭解了各個環節中自己充當的角色,那麼整個事件怎麼傳遞的呢,為了讓大家更加方便的理解,我也很蛋疼的畫了一蛋疼圖,雖然本人不怎麼喜歡畫圖。
       如上圖,A:代表當前Activty。B.:ViewGrup.    C :View.   對於View還不夠清楚的請移步  《AndroidUI之View的載入機制》自行閱讀為了方便理解,我們把view理解為具體一個控制元件,列如C代表Button,B代表佈局。當我們點選螢幕上的C時整個事件將會由A—B --C —B—A,事件分發我們可以理解為鑽井模式,消費回撥為冒泡模式。        當點選C (Button)時,首先有A進行分發,然後傳遞到B,如果B不攔截,則繼續分發,傳遞到C ,此時C無法繼續傳遞 ,則執行事件,消費後繼續向上反饋,上級則不會進行消費處理,如果不消費,則由上級B(Layout)進行處理,如果不處理,則繼續交由A(Activity)處理,此時此事件結束。      以上便是一個完整的事件週期,我們可在不同環節根據當前需要I進行處理,已到達響應的需求.  只要我們理解了時間的整個過程,那麼焦點事件我們可以隨心所欲的去處理。

MotionEvent事件

一般我們是在View或者activty的重寫onTouchEvent()方法中處理MotionEvent物件的.

    public boolean onTouchEvent(MotionEvent event) 

 (1)MotionEvent事件的型別

主要的事件型別有:

 ACTION_DOWN: 表示使用者開始觸控.

 ACTION_MOVE: 表示使用者在移動(手指或者其他)

 ACTION_UP:表示使用者擡起了手指 

還有一個不常見的:

ACTION_OUTSIDE: 表示使用者觸碰超出了正常的UI邊界.

但是對於多點觸控的支援,Android加入了以下一些事件型別.來處理,如另外有手指按下了,

有的手指擡起來了.等等:

ACTION_POINTER_DOWN:有一個非主要的手指按下了.

ACTION_POINTER_UP:一個非主要的手指擡起來了

可以通過getAction()可以獲取型別,在android2.2之後加入多點觸控支援之後使用getActionMasked()方法.

 (2)事件發生的位置,x,y軸

  getX() 獲得事件發生時,觸控的中間區域在螢幕的X軸.

   getY() 獲得事件發生時,觸控的中間區域在螢幕的X軸.

 在多點觸控中還可以通過:    

 getX(int pointerIndex) ,來獲得對應手指事件的發生位置. 獲得Y軸用getY(int pointerIndex)

 (3)其他屬性

  getEdgeFlags():當事件型別是ActionDown時可以通過此方法獲得,手指觸控開始的邊界. 如果是的話,有如下幾種值:EDGE_LEFT,EDGE_TOP,EDGE_RIGHT,EDGE_BOTTOM

 特別說明:

(1)首先是MotionEvent 中getAction()getActionMasked()的區別:

 首先看原始碼:

?
123456789101112publicstaticfinalintACTION_MASK =0xff;publicfinalintgetAction() {returnmAction;}publicfinalintgetActionMasked() {returnmAction & ACTION_MASK;}

上面的程式碼是基於android2.2的,註釋是android4.X中最新的.

他們有什麼區別呢?如果mAction的值是在0x00到0xff之間的話。getAction()返回的值,和

getActionMasked()的返回的值是一樣的。

(Q1)那什麼時候返回的值是一樣的呢?即當mAction值大於0xff時,那什麼時候會大於0xff呢?

  這就是是當有多點觸控時。當有多點觸控時。

 mAction的低8位即0x00到0xff用來表示動作的型別資訊。

 例如:MotionEvent#ACTION_DOWN的值是 0,即0x00。

         MotionEvent#ACTION_UP的值是 1,即0x01。

  等等。

 但是,我們知道Android是支援多點觸控的,那麼怎麼知道這個一個MotionEvent是哪一個

觸控點觸發的呢?那麼就還需要MotionEvent帶有觸控點索引資訊。

 Android的解決方案時在;mAction的第二個8位中儲存。

例如,如果mAction的值是0x0000,則表示是第一個觸控點的ACTION_DOWN操作。

       如果mAction的值是0x0100呢,則表示是第二個觸控點的ACTION_DOWN操作。

       第三個的ACTION_DOWN呢?相信你可以推出來是0x0200。

總而言之,mAction時的低8位(也就是0-7位)是動作型別資訊。

            mAction的8-15位呢,是觸控點的索引資訊。(即表示是哪一個觸控點的事件)。

(Q2),為什麼不用兩個欄位來表示。

如   int mAction,int mPointer,

mAction表示動作型別,mPointer表示第幾個觸控點。點選檢視原文

因為,動作型別只要0-255就可以了,動作型別,mPointer也是。

只要一個欄位(32位),否則需要兩個欄位(32*2=64位),即可以節約記憶體。又可以方便提高處理速度。

不過通常我們都是以不同的欄位來儲存不同的資訊。但是在計算機內部他們還是變成了0,1。

計算機始終還是以位來儲存資訊的。如果我們多我熟悉以位為基本單位來理解資訊的儲存。對於理解android中的很多變數是很有幫助的。因為他其中的很多東西使用的這樣的節約內在的技巧。

如onMeasure中的MeasureSpec。(onMeasures是view繪製過程中常用的方法 具體過程請參考其他文章

先看關於這兩個方法註釋:

我簡單的翻譯如下:

?
1234567891011121314151617181920212223/*** action碼的位掩碼部分就是action本身*/publicstaticfinalintACTION_MASK             = 0xff;/**返回action的型別,考慮使用getActionMasked()和getActionIndex()來獲得單獨的經過掩碼的action和觸控點的索引.@return action例如ACTION_DOWN或者ACTION_POINTER_DOWN與轉換的觸控點索引的合成值*/publicfinalintgetAction() {returnmAction;}/**返回經過掩碼的action,沒有觸控點索引資訊.通過getActionIndex()來得到觸控操作點的索引.@return action,例如ACTION_DOWN,ACTION_POINTER_DOWN*/publicfinalintgetActionMasked() {returnmAction & ACTION_MASK;}

在上面的兩個方法中註釋出現差異的地方是對於ACTION_POINTER_DOWN的描述:

通過getAction()返回的ACTION_POINTER_DOWN的是與轉換觸控點索引的合成值.

而getActionMasked()則就是一個ACTION_POINTER_DOWN的值:

這麼來看我們知道一個action的程式碼值還包含了action是那個觸控點的索引值:

現在我們對比來看看ACTION_MASK和ACTION_POINTER_INDEX_MASK

?
12publicstaticfinalintACTION_MASK             =0xff;publicstaticfinalintACTION_POINTER_INDEX_MASK  =0xff00;
還沒有看出來什麼嗎?

您把ACTION_MASK看成是0x00ff

就知道了吧.

也就是說,一個MotionEvent中的action程式碼,

前8位是實實在在包含表示哪一個動作常量.

後八位呢就是包含了觸控點的索引資訊.

因為ACTION_MASK = 0x00ff所以,經過ACTION_MASK掩碼過後的action碼就沒有索引資訊了.

如何得索引值呢?

原理:

先將action跟0xff00相與清除前8位用於儲存動作常量的資訊,

然後將action右移8位就可以得到索引值了.

我們就可以自己想辦法得到索引資訊了.

即先對action用ACTION_POINTER_INDEX_MASK進行掩碼處理,

即  maskedIndex = action&ACTION_POINTER_INDEX_MASK = action&0xff00

這各掩碼也就是將action這個數的前8位清零.

然後再將maskedIndex向右移8位就能夠得到索引值了.

再看看android真實是怎麼做的吧,

用於右移8位的常量.

?
1

相關推薦

Tv開發移動智慧電視焦點控制觸控事件

      前言:移動智慧裝置的發展,推動了安卓另一個領域,包括智慧電視和智慧家居,以及可穿戴裝置的大量使用,但是這些裝置上的開發並不是和傳統手機開發一樣,特別是焦點控制和使用者操作體驗風格上有很大的區

-自定義佈局】App開發思路 步一個腳印實現內嵌在app中的webview 騰訊開源X5 高效安全

實現內嵌在app中的webview 採用騰訊開源X5 高效安全 webview在app的使用中,十分頻繁,原生的webview載入速度相對來說很慢,而且很費流量。騰訊開源了x5的webview

-自定義佈局】App開發思路 步一個腳印實現自定義滾動的新聞條目上下滾動-仿蘑菇街

實現自定義滾動的新聞條目上下滾動-仿蘑菇街       這種上下滾動的自定義佈局,就像是公告那種上下的翻滾,一般為文字的滾動,很明顯,就是自定義佈局,一般是線性佈局。這裡提到的安卓原生的控制元件自然是

ROM定製筆記 使用隱藏API配合studio開發系統級APP

雖然在開發中使用隱藏API是不推薦的,但是為了一些需求,還是得做的。獲取安卓架包在sdk中這個包叫做android.jar,有兩種方式,第一種方式 從github上獲取,android-hidden-api,下載對應安卓版本的android.jar檔案第二種方式 從編譯完成的

工程化開發筆記1

測試 商業 軟件開發 界面 計算機 數學 開發流程 str sof 2018.3.8日 一、什麽是軟件工程? 1、軟件工程 是把系統的、有序的、可量化的方法應用到軟件的開發、運營和維護上的過程。 2、軟件工程包括下列領域 軟件需求分析、軟件設計、軟件構建、軟件測試和軟件

工程化開發筆記2

設計 說明 規劃 選擇 軟件企業 需求分析 結構 系統 周期 一、軟件生命周期 1、軟件定義期: 軟件定義是由軟件系統分析人員和用戶合作,確定軟件是什麽,針對有待開發的軟件系統進行分析、規劃和規格描述,為今後的軟件開發做準備。 (1)軟件任務立項 (2)項目可行性分析 (3

Intellij Idea12第一個程式開發HelloWorld及簡單講解Android

一、前言           本helloworld只有3行程式碼,皆為讓沒做過安卓的朋友看看安卓的目錄結構以及基本的開發方式。      &

使用手機開發深度學習簡易教程Python3+Keras

本教程基於安卓手機平臺,在PyDroid3軟體上,使用Python3語言配合Keras框架開發深度學習。本文章主要涉及在手機上開發環境的搭建,以及簡單的示例程式碼,如果想深入研究開發,還需要讀者自己花些功夫了。不廢話,開始教程。。 準備工作 1、手上需要有一個安卓手機,最近兩年

應用開發4UI設計

由於Google是官方,所以本系列內容全部是掛外網,請參考者注意。如若打不開,請使用vpn。 Google官方教程 https://developer.android.com/training/basics/firstapp/creating-project 本章參考: http

應用開發3執行工程

由於Google是官方,所以本系列內容全部是掛外網,請參考者注意。如若打不開,請使用vpn。 Google官方教程 https://developer.android.com/training/basics/firstapp/creating-project 1. 連線硬體

應用開發2建立工程

由於Google是官方,所以本系列內容全部是掛外網,請參考者注意。如若打不開,請使用vpn。 Google官方教程 https://developer.android.com/training/basics/firstapp/creating-project 1.新建工程

應用開發1環境安裝

由於Google是官方,所以本系列內容全部是掛外網,請參考者注意。如若打不開,請使用vpn。 Google官方教程 https://developer.android.com/training/basics/firstapp/creating-project 1.安裝Android

mac下搭建native開發環境供rn使用,及rn相關命令

A:搭建安卓native開發環境在http://www.android-studio.org/下載最新的as,按步驟操作,新建工程,會去下載安裝一些gradle相關的東西;還有一些sdk和模擬器可能也需要手動安裝和建立。as的執行依賴於jdk,如果你的mac沒有安裝jdk需要

工作中碰到的那些坑混合開發webview開啟連結出錯

https%3a%2f%2fmapi.alipay.com%2fgateway.do%3f_input_charset%3dutf-8%26it_b_pay%3d1d%26notify_url%3dhttp%253A%252F%252Fpay.jz-test.ganji.com%252Fpay%252Fnot

移動端使用rem同時適應ios手機原理解析,移動端響應式開發

size screen bsp 應用 屏幕 來看 比例 忽略 基礎 rem單位大家可能已經很熟悉,rem是隨著html的字體大小來顯示代表寬度的方法,我們怎樣進行移動端響應式開發呢 瀏覽器默認的字體大小為16px 及1rem 等於 16px 如果我們想要使1rem等於 12

權威編程指南-筆記 第29章定制視圖與觸摸事件

getx prot ret tex when fff ati 簡單 lean 1.定制視圖   Android自帶眾多優秀的標準視圖與組件,但有時為追求獨特的應用視覺效果,我們仍需創建定制視圖。   定制視圖分為兩大類別:   簡單視圖: 簡單視圖內部也可以很復雜,之所以

從入門到進階推薦學習方法與書籍整理pdf

前言:技術書閱讀方法論   一.速讀一遍(最好在1~2天內完成)   人的大腦記憶力有限,在一天內快速看完一本書會在大腦裡留下深刻印象,對於之後複習以及總結都會有特別好的作用。   對於每一章的知識,先閱讀標題,弄懂大概講的是什麼主題,再去快速看

Android 網路開發 okHttp網路請求快取控制Cache-Control

Cache-Control: Cache-Control指定請求和響應遵循的快取機制。在請求訊息或響應訊息中設定Cache-Control並不會修改另一個訊息處理過程中的快取處理過程。請求時的快取指令有下幾種: Public指示響應可被任何快取區快取。 Private指示對於單個

不容錯過,最全的架構合集【從零開始搭建android框架系列2

安卓架構文章合集(a collection of android Architecture) 部落格原地址: 簡書部落格 github地址: 這是從各大平臺上參考的android架構文章,文章資料,主要參考自Info,推薦關注: infoQ 1 Android

() 購物車二級列表,計算和全反選 以及 EventBus訊息傳遞

先看效果圖: MainActivity; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import androi