安卓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系統可以響應按鍵事件和觸控式螢幕事件,事件說明如下:
l onClick(View v) 一個普通的點選按鈕事件
l onlongClick(View v) 一個普通的點選長按按鈕事件
l boolean onKeyMultiple(int keyCode,int repeatCount,KeyEvent event)多個事件連續時發生,用於按鍵重複,必須過載@Override實現
l boolean onKeyDown(int keyCode,KeyEvent event) 用於在按鍵進行按下時發生
l boolean onKeyUp(int keyCode,KeyEvent event
l boolean onKeyLongPress(int keyCode, KeyEvent event)當你長時間按時發生
l onTouchEvent(MotionEvent event) 觸控式螢幕事件,當觸控式螢幕幕時發生(暫時簡單的這麼理解,後做詳細說明)
l boolean dispatchTouchEvent(MotionEvent event) 觸控時負責事件傳遞,必須過載@Override實現 (View和Activity都可以進行分發)
當然也有傳遞KeyEvent的方法
l 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()的區別:
首先看原始碼:
?123456789101112 | public static final int ACTION_MASK = 0xff ; public final int getAction() { return mAction; } public final int getActionMasked() { return mAction & 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本身 */ public static final int ACTION_MASK = 0xff ; /** 返回action的型別,考慮使用getActionMasked()和getActionIndex()來獲得單獨的經過掩碼的action和觸控點的索引. @return action例如ACTION_DOWN或者ACTION_POINTER_DOWN與轉換的觸控點索引的合成值 */ public final int getAction() { return mAction; } /** 返回經過掩碼的action,沒有觸控點索引資訊. 通過getActionIndex()來得到觸控操作點的索引. @return action,例如ACTION_DOWN,ACTION_POINTER_DOWN */ public final int getActionMasked() { return mAction & ACTION_MASK; } |
在上面的兩個方法中註釋出現差異的地方是對於ACTION_POINTER_DOWN的描述:
通過getAction()返回的ACTION_POINTER_DOWN的是與轉換觸控點索引的合成值.
而getActionMasked()則就是一個ACTION_POINTER_DOWN的值:
這麼來看我們知道一個action的程式碼值還包含了action是那個觸控點的索引值:
現在我們對比來看看ACTION_MASK和ACTION_POINTER_INDEX_MASK
?12 | public static final int ACTION_MASK = 0xff ; public static final int ACTION_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、手上需要有一個安卓手機,最近兩年 安卓應用開發(4)UI設計由於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-ControlCache-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 |