织梦绿色企业网站模板,工程造价招聘网最新招聘,个人站长和企业网站,外国优秀设计网站因为公司产品是一款vr,是没有触摸屏的,所有要想用蓝牙手柄操控LatinIME就得进行修改
LatinIME最主要的就是一个继承InputMethodService的服务,类名就是LatinIME.java
而MainKeyboardView.java就是画出来的那块键盘了,主要的响应触摸,传递键值都绕不过它调用的PointerTracker.…因为公司产品是一款vr,是没有触摸屏的,所有要想用蓝牙手柄操控LatinIME就得进行修改
LatinIME最主要的就是一个继承InputMethodService的服务,类名就是LatinIME.java
而MainKeyboardView.java就是画出来的那块键盘了,主要的响应触摸,传递键值都绕不过它调用的PointerTracker.java
直接看响应触摸的吧
通过onTouchEvent找到processMotionEvent(me);然后在processMotionEvent(me);看到tracker.processMotionEvent(me, mKeyDetector);
Overridepublic boolean onTouchEvent(final MotionEvent me) {if (getKeyboard() null) {return false;}if (mNonDistinctMultitouchHelper ! null) {if (me.getPointerCount() 1 mKeyTimerHandler.isInKeyRepeat()) {// Key repeating timer will be canceled if 2 or more keys are in action.mKeyTimerHandler.cancelKeyRepeatTimers();}// Non distinct multitouch screen supportmNonDistinctMultitouchHelper.processMotionEvent(me, mKeyDetector);return true;}return processMotionEvent(me);}public boolean processMotionEvent(final MotionEvent me) {final int index me.getActionIndex();final int id me.getPointerId(index);final PointerTracker tracker PointerTracker.getPointerTracker(id);// When a more keys panel is showing, we should ignore other fingers single touch events// other than the finger that is showing the more keys panel.if (isShowingMoreKeysPanel() !tracker.isShowingMoreKeysPanel() PointerTracker.getActivePointerTrackerCount() 1) {return true;}tracker.processMotionEvent(me, mKeyDetector);return true;}
触摸是在PointerTracker.java的processMotionEvent(me, mKeyDetector);里进行处理的
而PointerTracker.java里还有两个接口DrawingProxy和TimerProxy public interface DrawingProxy {public void invalidateKey(Key key);public void showKeyPreview(Key key);public void dismissKeyPreview(Key key);public void showSlidingKeyInputPreview(PointerTracker tracker);public void dismissSlidingKeyInputPreview();public void showGestureTrail(PointerTracker tracker, boolean showsFloatingPreviewText);}public interface TimerProxy {public void startTypingStateTimer(Key typedKey);public boolean isTypingState();public void startKeyRepeatTimerOf(PointerTracker tracker, int repeatCount, int delay);public void startLongPressTimerOf(PointerTracker tracker, int delay);public void cancelLongPressTimerOf(PointerTracker tracker);public void cancelLongPressShiftKeyTimers();public void cancelKeyTimersOf(PointerTracker tracker);public void startDoubleTapShiftKeyTimer();public void cancelDoubleTapShiftKeyTimer();public boolean isInDoubleTapShiftKeyTimeout();public void startUpdateBatchInputTimer(PointerTracker tracker);public void cancelUpdateBatchInputTimer(PointerTracker tracker);public void cancelAllUpdateBatchInputTimers();public static class Adapter implements TimerProxy {Overridepublic void startTypingStateTimer(Key typedKey) {}Overridepublic boolean isTypingState() { return false; }Overridepublic void startKeyRepeatTimerOf(PointerTracker tracker, int repeatCount, int delay) {}Overridepublic void startLongPressTimerOf(PointerTracker tracker, int delay) {}Overridepublic void cancelLongPressTimerOf(PointerTracker tracker) {}Overridepublic void cancelLongPressShiftKeyTimers() {}Overridepublic void cancelKeyTimersOf(PointerTracker tracker) {}Overridepublic void startDoubleTapShiftKeyTimer() {}Overridepublic void cancelDoubleTapShiftKeyTimer() {}Overridepublic boolean isInDoubleTapShiftKeyTimeout() { return false; }Overridepublic void startUpdateBatchInputTimer(PointerTracker tracker) {}Overridepublic void cancelUpdateBatchInputTimer(PointerTracker tracker) {}Overridepublic void cancelAllUpdateBatchInputTimers() {}}} TimerProxy是按下去时计时的,不用管,而DrawingProxy就是画的接口了
包括按下去时字母背景变黑和弹出pop,抬起时恢复等等
接着看processMotionEvent
public void processMotionEvent(final MotionEvent me, final KeyDetector keyDetector) {final int action me.getActionMasked();final long eventTime me.getEventTime();if (action MotionEvent.ACTION_MOVE) {// When this pointer is the only active pointer and is showing a more keys panel,// we should ignore other pointers motion event.final boolean shouldIgnoreOtherPointers isShowingMoreKeysPanel() getActivePointerTrackerCount() 1;final int pointerCount me.getPointerCount();for (int index 0; index pointerCount; index) {final int id me.getPointerId(index);if (shouldIgnoreOtherPointers id ! mPointerId) {continue;}final int x (int)me.getX(index);final int y (int)me.getY(index);final PointerTracker tracker getPointerTracker(id);tracker.onMoveEvent(x, y, eventTime, me);}return;}final int index me.getActionIndex();final int x (int)me.getX(index);final int y (int)me.getY(index);switch (action) {case MotionEvent.ACTION_DOWN:case MotionEvent.ACTION_POINTER_DOWN:onDownEvent(x, y, eventTime, keyDetector);break;case MotionEvent.ACTION_UP:case MotionEvent.ACTION_POINTER_UP:onUpEvent(x, y, eventTime);break;case MotionEvent.ACTION_CANCEL:onCancelEvent(x, y, eventTime);break;}}
响应触摸主要是onDownEvent(x, y, eventTime, keyDetector);和onUpEvent(x, y, eventTime);两个方法 private void onDownEvent(final int x, final int y, final long eventTime,final KeyDetector keyDetector) {setKeyDetectorInner(keyDetector);if (DEBUG_EVENT) {printTouchEvent(onDownEvent:, x, y, eventTime);}// Naive up-to-down noise filter.final long deltaT eventTime - mUpTime;if (deltaT sParams.mTouchNoiseThresholdTime) {final int distance getDistance(x, y, mLastX, mLastY);if (distance sParams.mTouchNoiseThresholdDistance) {if (DEBUG_MODE)Log.w(TAG, String.format([%d] onDownEvent: ignore potential noise: time%d distance%d,mPointerId, deltaT, distance));cancelTrackingForAction();return;}}final Key key getKeyOn(x, y);mBogusMoveEventDetector.onActualDownEvent(x, y);if (key ! null key.isModifier()) {// Before processing a down event of modifier key, all pointers already being// tracked should be released.sPointerTrackerQueue.releaseAllPointers(eventTime);}sPointerTrackerQueue.add(this);onDownEventInternal(x, y, eventTime);if (!sGestureEnabler.shouldHandleGesture()) {return;}// A gesture should start only from a non-modifier key. Note that the gesture detection is// disabled when the key is repeating.mIsDetectingGesture (mKeyboard ! null) mKeyboard.mId.isAlphabetKeyboard() key ! null !key.isModifier();if (mIsDetectingGesture) {mBatchInputArbiter.addDownEventPoint(x, y, eventTime,sTypingTimeRecorder.getLastLetterTypingTime(), getActivePointerTrackerCount());mGestureStrokeDrawingPoints.onDownEvent(x, y, mBatchInputArbiter.getElapsedTimeSinceFirstDown(eventTime));}}/* package */ boolean isShowingMoreKeysPanel() {return (mMoreKeysPanel ! null);} private void onUpEvent(final int x, final int y, final long eventTime) {if (DEBUG_EVENT) {printTouchEvent(onUpEvent :, x, y, eventTime);}sTimerProxy.cancelUpdateBatchInputTimer(this);if (!sInGesture) {if (mCurrentKey ! null mCurrentKey.isModifier()) {// Before processing an up event of modifier key, all pointers already being// tracked should be released.sPointerTrackerQueue.releaseAllPointersExcept(this, eventTime);} else {sPointerTrackerQueue.releaseAllPointersOlderThan(this, eventTime);}}onUpEventInternal(x, y, eventTime);sPointerTrackerQueue.remove(this);} onDownEvent中的onDownEventInternal(final int x, final int y, final long eventTime)和onUpEvent中的onUpEventInternal(final int x, final int y, final long eventTime)方法对触摸进行了处理 private void onDownEventInternal(final int x, final int y, final long eventTime) {Key key onDownKey(x, y, eventTime);// Key selection by dragging finger is allowed when 1) key selection by dragging finger is// enabled by configuration, 2) this pointer starts dragging from modifier key, or 3) this// pointers KeyDetector always allows key selection by dragging finger, such as// {link MoreKeysKeyboard}.mIsAllowedDraggingFinger sParams.mKeySelectionByDraggingFinger|| (key ! null key.isModifier())|| mKeyDetector.alwaysAllowsKeySelectionByDraggingFinger();mKeyboardLayoutHasBeenChanged false;mIsTrackingForActionDisabled false;resetKeySelectionByDraggingFinger();if (key ! null) {// This onPress call may have changed keyboard layout. Those cases are detected at// {link #setKeyboard}. In those cases, we should update key according to the new// keyboard layout.if (callListenerOnPressAndCheckKeyboardLayoutChange(key, 0 /* repeatCount */)) {key onDownKey(x, y, eventTime);}startRepeatKey(key);startLongPressTimer(key);setPressedKeyGraphics(key, eventTime);}} private void onUpEventInternal(final int x, final int y, final long eventTime) {sTimerProxy.cancelKeyTimersOf(this);final boolean isInDraggingFinger mIsInDraggingFinger;final boolean isInSlidingKeyInput mIsInSlidingKeyInput;resetKeySelectionByDraggingFinger();mIsDetectingGesture false;final Key currentKey mCurrentKey;mCurrentKey null;final int currentRepeatingKeyCode mCurrentRepeatingKeyCode;mCurrentRepeatingKeyCode Constants.NOT_A_CODE;// Release the last pressed key.setReleasedKeyGraphics(currentKey);if (isShowingMoreKeysPanel()) {if (!mIsTrackingForActionDisabled) {final int translatedX mMoreKeysPanel.translateX(x);final int translatedY mMoreKeysPanel.translateY(y);mMoreKeysPanel.onUpEvent(translatedX, translatedY, mPointerId, eventTime);}dismissMoreKeysPanel();return;}if (sInGesture) {if (currentKey ! null) {callListenerOnRelease(currentKey, currentKey.getCode(), true /* withSliding */);}if (mBatchInputArbiter.mayEndBatchInput(eventTime, getActivePointerTrackerCount(), this)) {sInGesture false;}showGestureTrail();return;}if (mIsTrackingForActionDisabled) {return;}if (currentKey ! null currentKey.isRepeatable() (currentKey.getCode() currentRepeatingKeyCode) !isInDraggingFinger) {return;}detectAndSendKey(currentKey, mKeyX, mKeyY, eventTime);if (isInSlidingKeyInput) {callListenerOnFinishSlidingInput();}} 而这两个方法中分别有setPressedKeyGraphics(key, eventTime);和setReleasedKeyGraphics(currentKey);两个方法通过DrawingProxy接口传到MainKeyboardView.java,
然后由MainKeyboardView.java画出触摸按下去和释放在键盘上的显示效果
onDownEventInternal中的
if (callListenerOnPressAndCheckKeyboardLayoutChange(key, 0 /* repeatCount */)) { key onDownKey(x, y, eventTime); }
是按下大写键后,整个键盘改变大小写状态的
而onUpEventInternal中的detectAndSendKey(currentKey, mKeyX, mKeyY, eventTime);方法调用callListenerOnCodeInput(key, code, x, y, eventTime, false /* isKeyRepeat */);
通过KeyboardActionListener接口将key传到LatinIME.java中的onCodeInput方法中进行处理