hi,粉絲朋友們!
上一節(jié)已經(jīng)對車載的多屏互動進行了相關(guān)的技術(shù)方案介紹,以及相關(guān)的核心方法
moveRootTaskToDisplay的講解和使用。
具體可以參考鏈接:https://blog.csdn.net/learnframework/article/details/130461689
本節(jié)就來進行代碼實戰(zhàn)
1、方案設(shè)計
要實現(xiàn)雙屏互動,主要就只需要兩個步驟:
1、手指動作識別
2、識別動作后觸發(fā)尋找display,獲取頂部task,觸發(fā)moveTask操作
2、手勢動作識別部分
觸發(fā)手勢設(shè)計:因為模擬器實現(xiàn)條件有限,所以這里采用是雙指向右移動一定距離觸發(fā)。
首先要進行對手指全局移動的監(jiān)聽,針對多個手指的觸摸移動動作要進行識別。
代碼實現(xiàn):
單獨建立一個PointerEventListener的實現(xiàn)子類叫做DoubleScreenMovePointerEventListener,在這里面的onPointerEvent方法即可以實現(xiàn)對應(yīng)的觸摸動作識別,這里實現(xiàn)是雙指同時滑動觸摸方式:
diff --git a/services/core/java/com/android/server/wm/DoubleScreenMovePointerEventListener.java b/services/core/java/com/android/server/wm/DoubleScreenMovePointerEventListener.java
new file mode 100644
index 000000000000..f9c765476d19
--- /dev/null
+++ b/services/core/java/com/android/server/wm/DoubleScreenMovePointerEventListener.java
@@ -0,0 +1,62 @@
+package com.android.server.wm;
+
+import android.view.MotionEvent;
+import android.view.WindowManagerPolicyConstants;
+
+public class DoubleScreenMovePointerEventListener implements WindowManagerPolicyConstants.PointerEventListener {
+ boolean shouldBeginMove = false;
+ int mPoint0FirstX = 0;
+ int mPoint1FirstX = 0;
+
+ int mPoint0LastX = 0;
+ int mPoint1LastX = 0;
+ int START_GAP = 20;//動作觸發(fā)閾值,最少移動為20個像素才可以
+ private final WindowManagerService mService;
+
+ public DoubleScreenMovePointerEventListener(WindowManagerService mService, DisplayContent mDisplayContent) {
+ this.mService = mService;
+ this.mDisplayContent = mDisplayContent;
+ }
+
+ private final DisplayContent mDisplayContent;
+
+ @Override
+ public void onPointerEvent(MotionEvent motionEvent) {
+ android.util.Log.i("DoubleScreenTouch","DoubleScreenMovePointerEventListener onPointerEvent motionEvent = "+motionEvent);
+ switch (motionEvent.getActionMasked()) {
+ case MotionEvent.ACTION_DOWN:
+ case MotionEvent.ACTION_POINTER_DOWN:
+ if (motionEvent.getPointerCount() > 2) {
+ shouldBeginMove = false;
+ android.util.Log.i("DoubleScreen","DoubleScreenMovePointerEventListener motionEvent.getPointerCount() > 2 end DoubleScreenMove ");
+ }
+ if (motionEvent.getPointerCount() == 2) {
+ if (mPoint0FirstX == 0 && mPoint1FirstX == 0) {
+ mPoint0FirstX = (int)motionEvent.getX(0);
+ mPoint1FirstX = (int)motionEvent.getX(1);
+ }
+ }
+ break;
+ case MotionEvent.ACTION_MOVE:
+ if (motionEvent.getPointerCount() == 2) {
+ if (!shouldBeginMove && motionEvent.getX(0) - mPoint0FirstX > START_GAP &&
+ motionEvent.getX(1) - mPoint1FirstX > START_GAP) { //識別了雙指動作達到觸發(fā)task移動條件,則調(diào)用對應(yīng)mDisplayContent.doTestMoveTaskToOtherDisplay方法
+ android.util.Log.i("DoubleScreen","DoubleScreenMovePointerEventListener start DoubleScreenMove ");
+ shouldBeginMove = true;
+ mDisplayContent.doTestMoveTaskToOtherDisplay();
+ }
+
+ mPoint0LastX = (int)motionEvent.getX(0);
+ mPoint1LastX = (int)motionEvent.getX(1);
+ }
+ break;
+ case MotionEvent.ACTION_POINTER_UP:
+ case MotionEvent.ACTION_UP:
+ shouldBeginMove = false;
+ mPoint0FirstX = mPoint1FirstX =0;
+ android.util.Log.i("DoubleScreen","DoubleScreenMovePointerEventListener ACTION_UP end DoubleScreenMove ");
+ break;
+ }
+ }
+
+}
同時不要忘記需要把這個PointEventListener讓displaycontent注冊監(jiān)聽:
@@ -1063,7 +1085,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
// 1. All physical displays (multi-display).
// 2. VirtualDisplays on VR, AA (and everything else).
mTapDetector = new TaskTapPointerEventListener(mWmService, this);//需要傳遞WMS和DisplayContent方便調(diào)用
+ mDoubleScreenMoveListener = new DoubleScreenMovePointerEventListener(mWmService, this);
registerPointerEventListener(mTapDetector);
+ registerPointerEventListener(mDoubleScreenMoveListener);
registerPointerEventListener(mWmService.mMousePositionTracker);
if (mWmService.mAtmService.getRecentTasks() != null) {
registerPointerEventListener(
3、尋找當前Display的Task,移動到目標display
觸摸動作識別后會調(diào)用DisplayContent的doTestMoveTaskToOtherDisplay方法來完成剩下的業(yè)務(wù):
1、獲取要移動到的目標display對象
2、獲取當前display要移動的Task對象
3、調(diào)用RootWindowContainer的moveRootTaskToDisplay方法來實現(xiàn)
+//add by doublescreenmove
+ public void doTestMoveTaskToOtherDisplay() {
+ DisplayContent otherDisplay = null;
+ if (mRootWindowContainer.getChildCount() == 2) {//檢測是不是雙屏
+ otherDisplay = (mRootWindowContainer.getChildAt(0) == this) ? mRootWindowContainer.getChildAt(1):mRootWindowContainer.getChildAt(0);//獲取另一個屏幕的DisplayContent
+ }
+ if (otherDisplay!= this && otherDisplay!= null) {
+ int rootTaskId = 0;
+ try {
+ Task rootTask = getTopRootTask();//獲取當前display的頂部Task
+ if (rootTask.isActivityTypeHome()) {//home類型的task不支持移動
+ android.util.Log.i("DoubleScreen","doTestMoveTaskToOtherDisplay isActivityTypeHome");
+ return;
+ }
+ rootTaskId =rootTask.mTaskId;
+ mRootWindowContainer.moveRootTaskToDisplay(rootTaskId,otherDisplay.mDisplayId,true);//把task移動到另一屏
+ }catch (Exception e) {
+ android.util.Log.i("DoubleScreen","doTestMoveTaskToOtherDisplay Exception",e);
+ }
+ }
+ }
+ //end by doublescreenmove
成果展示:文章來源:http://www.zghlxwxcb.cn/news/detail-703401.html
模擬器調(diào)試要點:
這個部分請關(guān)注bibili的 視頻
https://www.bilibili.com/video/BV1Tv4y1J7eb文章來源地址http://www.zghlxwxcb.cn/news/detail-703401.html
到了這里,關(guān)于第二節(jié)-安卓多屏雙屏實戰(zhàn)車載車機智能駕駛艙開發(fā)/千里馬android framwork開發(fā)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!