根据Android R版别分析
新增 DoubleScreenMovePointerEventListener 类:
package com.android.server.wm;
import android.util.Log;
import android.view.MotionEvent;
import android.view.WindowManagerPolicyConstants;
public class DoubleScreenMovePointerEventListener implements WindowManagerPolicyConstants.PointerEventListener {
private static final String TAG = DoubleScreenMovePointerEventListener.class.getName();
private boolean shouldBeginMove = false;
private int mPoint0FirstX = 0;
private int mPoint1FirstX = 0;
private int mPoint0LastX = 0;
private int mPoint1LastX = 0;
int START_GAP = 20; //动作触发阈值,最少移动为20个像素才能够
private final WindowManagerService mService;
private final DisplayContent mDisplayContent;
public DoubleScreenMovePointerEventListener(WindowManagerService service, DisplayContent displayContent) {
mService = service;
mDisplayContent = displayContent;
}
@Override
public void onPointerEvent(MotionEvent motionEvent) {
Log.d(TAG, "onPointerEvent: motionEvent = " + motionEvent);
switch (motionEvent.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
if (motionEvent.getPointerCount() > 1) {
shouldBeginMove = false;
Log.d(TAG, "onPointerEvent: motionEvent.getPointerCount() > 2 end DoubleScreenMove");
}
if (motionEvent.getPointerCount() == 1) {
if (mPoint0FirstX == 0) {
//if (mPoint0FirstX == 0 && mPoint1FirstX == 0) {
mPoint0FirstX = (int) motionEvent.getX(0);
// mPoint1FirstX = (int) motionEvent.getX(1);
}
}
break;
case MotionEvent.ACTION_MOVE:
if (motionEvent.getPointerCount() == 1) {
if (!shouldBeginMove && (motionEvent.getX(0) - mPoint0FirstX) > START_GAP) {
// && (motionEvent.getX(1) - mPoint1FirstX) > START_GAP
//识别了双指动作到达触发task移动条件,则调用对应mDisplayContent.doTestMoveTaskToOtherDisplay办法
Log.d(TAG, "onPointerEvent: start DoubleScreenMove");
shouldBeginMove = true;
mDisplayContent.doMoveStackToDisplay();
}
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;
Log.d(TAG, "onPointerEvent: ACTION_UP end DoubleScreenMove");
break;
}
}
}
新增DoubleScreenMovePointerEventListener初始化(在DisplayContent中):
final DoubleScreenMovePointerEventListener mPointerEventListener;
DisplayContent(Display display, RootWindowContainer root) {
……………………
mTapDetector = new TaskTapPointerEventListener(mWmService, this);
mPointerEventListener = new DoubleScreenMovePointerEventListener(mWmService,this);
registerPointerEventListener(mTapDetector);
registerPointerEventListener(mPointerEventListener);
registerPointerEventListener(mWmService.mMousePositionTracker);
……………………
}
修正DisplayContent,新增doMoveStackToDisplay()办法:
public void doMoveStackToDisplay() {
DisplayContent otherDisplay = null;
if (mRootWindowContainer.getChildCount() >= 2) {
otherDisplay = (mRootWindowContainer.getChildAt(0) == this)
? mRootWindowContainer.getChildAt(1) : mRootWindowContainer.getChildAt(0);
}
if (otherDisplay != this && otherDisplay != null) {
int topStackId = 0;
try {
Task topStack = getTopStack();
if (topStack.isActivityTypeHome()) {
Log.d(TAG, "doMoveStackToDisplay: isActivityTypeHome");
return;
}
topStackId = topStack.mTaskId;
mRootWindowContainer.moveStackToDisplay(topStackId, otherDisplay.mDisplayId, true);
} catch (Exception ex) {
Log.d(TAG, "doMoveStackToDisplay: exception = " + ex);
}
}
}