From 88838a30afcfff443bc4335b65a1dd20c07f9ff3 Mon Sep 17 00:00:00 2001 From: Yohei Yukawa Date: Tue, 27 May 2014 17:19:34 +0900 Subject: [PATCH] Make sample IME aware of language switching This CL demonstrates how the new language switching functionality should work by using the SoftKeyboard sample. BUG: 15267645 Change-Id: I18ab25a0784979fe6028b97a22ff02bfd502d506 --- .../sym_keyboard_language_switch.png | Bin 0 -> 1773 bytes .../sym_keyboard_language_switch.png | Bin 0 -> 1121 bytes samples/SoftKeyboard/res/xml/method.xml | 1 + samples/SoftKeyboard/res/xml/qwerty.xml | 10 ++- samples/SoftKeyboard/res/xml/symbols.xml | 10 ++- .../SoftKeyboard/res/xml/symbols_shift.xml | 10 ++- .../android/softkeyboard/LatinKeyboard.java | 60 +++++++++++++++++- .../softkeyboard/LatinKeyboardView.java | 2 + .../android/softkeyboard/SoftKeyboard.java | 46 +++++++++++--- 9 files changed, 120 insertions(+), 19 deletions(-) create mode 100644 samples/SoftKeyboard/res/drawable-hdpi/sym_keyboard_language_switch.png create mode 100644 samples/SoftKeyboard/res/drawable-mdpi/sym_keyboard_language_switch.png diff --git a/samples/SoftKeyboard/res/drawable-hdpi/sym_keyboard_language_switch.png b/samples/SoftKeyboard/res/drawable-hdpi/sym_keyboard_language_switch.png new file mode 100644 index 0000000000000000000000000000000000000000..78d3a1fc5251868ff6731a7f082ac19b39668392 GIT binary patch literal 1773 zcmZ`(dpOe#8~)8y;uIIX+`?~Mvy07Q?>nZTZd+t_4r~v@5 z+uO^7AZHUf%v7NAPALWLqaRR`JfQNM*T(q!2vafYu4UPjX=x?M3hffXw{> zkd+Gn61kPN3;=W_0DutyfGz_77_F*103#njqkKF)0NIbKWj9`vJE}CVkQ6z4{TH~= zlfMFhGTYn3HHb7gUKZLMj{WDzxrKCfw*QdP1)#$)YT&7sRxPF^@1W6Sy#_AI5V{Z# zSP1(y6(Me&7*39Afo83e>E2szoM9u}Kub$jFgI7zaOlyVBbb1=u03%tK8fE)zO16& zbXe$O+l)@EuqopevMtKoM&65%&(E=>#HF+y%bLsB<4TSXj>qCgp&s_FIrRQCmdOGn zPa%x@Xt6<0AE?)MiFbs4L(?#V3ndu_Gmsv&%OBPFa`UX#@$tX!I!e zK=lB;%Ew?ptgs%nIjrsR*Rc z)T!yFLY^Zx99?mC+=j;r<=*B!<~3pT z;q~pdj%o>RhC9dV@BTjJwlUumT%^x~it)#iR)7w(wv|Zr?~7gI zyoE^Ymrz7d%CYzIiw|5eStn~2&D zgRSTDmpVXJ$MJjnbj8Ntm(S2-->rq^Y5(~0eFC_ExVUR^C1yGL)7>V@?h98$MS(${ zaJ;&$)|b9L4ebvQA{s%0BlQ09ZreWpYD+0$u-;Y?RIa`8=|(GiCPCE8!ZDP-;V^x{ zJMyN~!&P#s{g{c?1t)jXECiYG4TZ(u7jKoc>{P7Mv+l9Vng#B+=&nx`Esei-sl3=@ z`f8BWUbu8EtfT9ghNue8bZ$3!3FD1}&xSecqV{epr*tpq#mtcCT2yQE}DU%Q_X zIQns%4_#uEE>o&()4MvY3VDShLOE|@h z^H4|j_s5xsrMGu=#%Cm7lAKT|J;R5I*Kd;c$=X6H_Xf?aQKJX4>rc}i9jyFwKHk+1 zJ==>K57GI;m~JjV|5uEQXD+KeZ98lbZ$G+iteZ`;e{C&92d4Eec#(XX7`p}%RoKV!N+J@it zFuTKL<}UPs*q6*RZfnx(uQw-C>v?k)S(Bajckx-d7bRpzM`Ykk5b7Nn{Q2GT*Q8zX z^p(Uhiull``eeEK^905S*B}rTVy$Fd%f*gmlS@I3BX>G2lBZ%9%@+qD=!UIPB;T(h z7M8R957*KB{2}RqYlV*;q`DQn0xLf@k+-fxNOQ!yTk!fq0CVoOo0fxs5Oud zVfLYNVD!hoH%-NoQez@h$>`{0vYdcJNSnh}NCzt$WRMLCeb^Rld&mlDk47R1*M+D5 zCy+>uIT4%j{{zNjzYWO)IzKi9Qe#uoBa_L1YYa7tZ0MaBNg)%+kue!bqvRiF0Nz-< KN2^=J`TqdwQ%1}H literal 0 HcmV?d00001 diff --git a/samples/SoftKeyboard/res/drawable-mdpi/sym_keyboard_language_switch.png b/samples/SoftKeyboard/res/drawable-mdpi/sym_keyboard_language_switch.png new file mode 100644 index 0000000000000000000000000000000000000000..828929bc8a42b49c9d87f68631ca4f91edb4174f GIT binary patch literal 1121 zcmeAS@N?(olHy`uVBq!ia0vp^5GZqKA zJ29*~C-V}>QAqX(@?~JCQe$9fXklRZ1r%y{!N5>zz`*b-fq}tl1_Oh5!JJ)zHb4os zByV>YhW{YAVDIwDKoQOYkH}&m?E%JaC$sGs7?=$`T^vI^j`vQB?+6W*I9mVw-o})! zSzMc^8*;fV3^MH4G<`}_R||)yBBz=X$ENA`xVU9DY}W|tShQV%OG!sw>Vsl6C#z=H zp??muoIE4FOta3N`TMot`o7J3i`Q>?xZ%9r@7vk6_wCZxZkA><*(zt|F#BMx+zVE7 z-_05ecCr*`fByWJp|BNYm43*fHeaoM<@VL@SHHfp z`?~qa+R*(W=}ra9ttM{0opol{9qB9guj)$b2hI=P9~|$u?YEQJV!5+hWA}#1p1l=( z&?$FeU&@B)x$Cy&1fROM?B3$I6Fc_I-hcUh(EU*P6T33Me!bH#vSH~f!_wqqzVmDs z>7C!aow>s9ui)3vubHK#Q*X3|lvV!aGh1aJa&g!MI`hSHsSc_hC5w%}+Z*|xVpjlfcAmE2WK+&F|O{G71;VOY~^l^ zKfVt%6FeJcXPte1VEX~T1ZS5@qvGWaPgSBDj1Qv#x?0hXB zGDPk%uJg=MKlMKKvv7gv2Q~w)J(F{HS~aX)#k5IP^`M}b%-5J-q8t0-Slt`A52S4R zCvby#4(l{V{#5C7XS1-%>oHr`K5x`+{5a#GYgpli_ty0*XGJfcSGI6&@cxt6H`y6Z zUwU6?>i0E^ZX8M3dV{0)ldU`d`7q8i%j(zmKUna~XJfb0s!Q@KHr^tyO_t!P2u zx9ftcuee`5T=i+*Vln%u)a!;@U$5ByC3K^9aq-j#A>pg|SEn~!{JK!FthT*MiFT*HJ^lfX3(+#j5G{K)Jt%IvY=y@%0*8%AF;jHe`U z1O_(-PK^6>f%Sv@>hk?h&p&Ij0_Gys64!{5l*E!$tK_0oAjM#0U}&ssV5w_p5MpR* zWo%+)Vx((eZe?H)H0?_TiiX_$l+3hB+!~Zm`y2skkObKfoS#-wo>-L1;Fyx1l&avF co0y&&l$w}QS$HxPl+_tLUHx3vIVCg!00dp`p8x;= literal 0 HcmV?d00001 diff --git a/samples/SoftKeyboard/res/xml/method.xml b/samples/SoftKeyboard/res/xml/method.xml index 2f2d6f0a3..37a59c861 100644 --- a/samples/SoftKeyboard/res/xml/method.xml +++ b/samples/SoftKeyboard/res/xml/method.xml @@ -22,6 +22,7 @@ - + android:keyWidth="15%p" android:keyEdgeFlags="left"/> + + + - + android:keyWidth="15%p" android:keyEdgeFlags="left" /> + + + diff --git a/samples/SoftKeyboard/res/xml/symbols_shift.xml b/samples/SoftKeyboard/res/xml/symbols_shift.xml index d7139f340..fa551f29a 100755 --- a/samples/SoftKeyboard/res/xml/symbols_shift.xml +++ b/samples/SoftKeyboard/res/xml/symbols_shift.xml @@ -69,8 +69,14 @@ - + android:keyWidth="15%p" android:keyEdgeFlags="left" /> + + + diff --git a/samples/SoftKeyboard/src/com/example/android/softkeyboard/LatinKeyboard.java b/samples/SoftKeyboard/src/com/example/android/softkeyboard/LatinKeyboard.java index 67787dca4..aae67cd1b 100644 --- a/samples/SoftKeyboard/src/com/example/android/softkeyboard/LatinKeyboard.java +++ b/samples/SoftKeyboard/src/com/example/android/softkeyboard/LatinKeyboard.java @@ -22,11 +22,35 @@ import android.content.res.XmlResourceParser; import android.graphics.drawable.Drawable; import android.inputmethodservice.Keyboard; import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodManager; public class LatinKeyboard extends Keyboard { private Key mEnterKey; private Key mSpaceKey; + /** + * Stores the current state of the mode change key. Its width will be dynamically updated to + * match the region of {@link #mModeChangeKey} when {@link #mModeChangeKey} becomes invisible. + */ + private Key mModeChangeKey; + /** + * Stores the current state of the language switch key (a.k.a. globe key). This should be + * visible while {@link InputMethodManager#shouldOfferSwitchingToNextInputMethod(IBinder)} + * returns true. When this key becomes invisible, its width will be shrunk to zero. + */ + private Key mLanguageSwitchKey; + /** + * Stores the size and other information of {@link #mModeChangeKey} when + * {@link #mLanguageSwitchKey} is visible. This should be immutable and will be used only as a + * reference size when the visibility of {@link #mLanguageSwitchKey} is changed. + */ + private Key mSavedModeChangeKey; + /** + * Stores the size and other information of {@link #mLanguageSwitchKey} when it is visible. + * This should be immutable and will be used only as a reference size when the visibility of + * {@link #mLanguageSwitchKey} is changed. + */ + private Key mSavedLanguageSwitchKey; public LatinKeyboard(Context context, int xmlLayoutResId) { super(context, xmlLayoutResId); @@ -45,10 +69,39 @@ public class LatinKeyboard extends Keyboard { mEnterKey = key; } else if (key.codes[0] == ' ') { mSpaceKey = key; + } else if (key.codes[0] == Keyboard.KEYCODE_MODE_CHANGE) { + mModeChangeKey = key; + mSavedModeChangeKey = new LatinKey(res, parent, x, y, parser); + } else if (key.codes[0] == LatinKeyboardView.KEYCODE_LANGUAGE_SWITCH) { + mLanguageSwitchKey = key; + mSavedLanguageSwitchKey = new LatinKey(res, parent, x, y, parser); } return key; } - + + /** + * Dynamically change the visibility of the language switch key (a.k.a. globe key). + * @param visible True if the language switch key should be visible. + */ + void setLanguageSwitchKeyVisibility(boolean visible) { + if (visible) { + // The language switch key should be visible. Restore the size of the mode change key + // and language switch key using the saved layout. + mModeChangeKey.width = mSavedModeChangeKey.width; + mModeChangeKey.x = mSavedModeChangeKey.x; + mLanguageSwitchKey.width = mSavedLanguageSwitchKey.width; + mLanguageSwitchKey.icon = mSavedLanguageSwitchKey.icon; + mLanguageSwitchKey.iconPreview = mSavedLanguageSwitchKey.iconPreview; + } else { + // The language switch key should be hidden. Change the width of the mode change key + // to fill the space of the language key so that the user will not see any strange gap. + mModeChangeKey.width = mSavedModeChangeKey.width + mSavedLanguageSwitchKey.width; + mLanguageSwitchKey.width = 0; + mLanguageSwitchKey.icon = null; + mLanguageSwitchKey.iconPreview = null; + } + } + /** * This looks at the ime options given by the current editor, to set the * appropriate label on the keyboard's enter key (if it has one). @@ -57,7 +110,7 @@ public class LatinKeyboard extends Keyboard { if (mEnterKey == null) { return; } - + switch (options&(EditorInfo.IME_MASK_ACTION|EditorInfo.IME_FLAG_NO_ENTER_ACTION)) { case EditorInfo.IME_ACTION_GO: mEnterKey.iconPreview = null; @@ -93,7 +146,8 @@ public class LatinKeyboard extends Keyboard { static class LatinKey extends Keyboard.Key { - public LatinKey(Resources res, Keyboard.Row parent, int x, int y, XmlResourceParser parser) { + public LatinKey(Resources res, Keyboard.Row parent, int x, int y, + XmlResourceParser parser) { super(res, parent, x, y, parser); } diff --git a/samples/SoftKeyboard/src/com/example/android/softkeyboard/LatinKeyboardView.java b/samples/SoftKeyboard/src/com/example/android/softkeyboard/LatinKeyboardView.java index 489c283fd..abfa2f21f 100644 --- a/samples/SoftKeyboard/src/com/example/android/softkeyboard/LatinKeyboardView.java +++ b/samples/SoftKeyboard/src/com/example/android/softkeyboard/LatinKeyboardView.java @@ -26,6 +26,8 @@ import android.view.inputmethod.InputMethodSubtype; public class LatinKeyboardView extends KeyboardView { static final int KEYCODE_OPTIONS = -100; + // TODO: Move this into android.inputmethodservice.Keyboard + static final int KEYCODE_LANGUAGE_SWITCH = -101; public LatinKeyboardView(Context context, AttributeSet attrs) { super(context, attrs); diff --git a/samples/SoftKeyboard/src/com/example/android/softkeyboard/SoftKeyboard.java b/samples/SoftKeyboard/src/com/example/android/softkeyboard/SoftKeyboard.java index 7c4a17e1f..cdebde5a7 100644 --- a/samples/SoftKeyboard/src/com/example/android/softkeyboard/SoftKeyboard.java +++ b/samples/SoftKeyboard/src/com/example/android/softkeyboard/SoftKeyboard.java @@ -16,14 +16,17 @@ package com.example.android.softkeyboard; +import android.app.Dialog; import android.inputmethodservice.InputMethodService; import android.inputmethodservice.Keyboard; import android.inputmethodservice.KeyboardView; +import android.os.IBinder; import android.text.InputType; import android.text.method.MetaKeyKeyListener; import android.view.KeyCharacterMap; import android.view.KeyEvent; import android.view.View; +import android.view.Window; import android.view.inputmethod.CompletionInfo; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; @@ -114,10 +117,17 @@ public class SoftKeyboard extends InputMethodService mInputView = (LatinKeyboardView) getLayoutInflater().inflate( R.layout.input, null); mInputView.setOnKeyboardActionListener(this); - mInputView.setKeyboard(mQwertyKeyboard); + setLatinKeyboard(mQwertyKeyboard); return mInputView; } + private void setLatinKeyboard(LatinKeyboard nextKeyboard) { + final boolean shouldSupportLanguageSwitchKey = + mInputMethodManager.shouldOfferSwitchingToNextInputMethod(getToken()); + nextKeyboard.setLanguageSwitchKeyVisibility(shouldSupportLanguageSwitchKey); + mInputView.setKeyboard(nextKeyboard); + } + /** * Called by the framework when your view for showing candidates needs to * be generated, like {@link #onCreateInputView}. @@ -247,7 +257,7 @@ public class SoftKeyboard extends InputMethodService @Override public void onStartInputView(EditorInfo attribute, boolean restarting) { super.onStartInputView(attribute, restarting); // Apply the selected keyboard to the input view. - mInputView.setKeyboard(mCurKeyboard); + setLatinKeyboard(mCurKeyboard); mInputView.closing(); final InputMethodSubtype subtype = mInputMethodManager.getCurrentInputMethodSubtype(); mInputView.setSubtypeOnSpaceKey(subtype); @@ -509,19 +519,19 @@ public class SoftKeyboard extends InputMethodService } else if (primaryCode == Keyboard.KEYCODE_CANCEL) { handleClose(); return; + } else if (primaryCode == LatinKeyboardView.KEYCODE_LANGUAGE_SWITCH) { + handleLanguageSwitch(); + return; } else if (primaryCode == LatinKeyboardView.KEYCODE_OPTIONS) { // Show a menu or somethin' } else if (primaryCode == Keyboard.KEYCODE_MODE_CHANGE && mInputView != null) { Keyboard current = mInputView.getKeyboard(); if (current == mSymbolsKeyboard || current == mSymbolsShiftedKeyboard) { - current = mQwertyKeyboard; + setLatinKeyboard(mQwertyKeyboard); } else { - current = mSymbolsKeyboard; - } - mInputView.setKeyboard(current); - if (current == mSymbolsKeyboard) { - current.setShifted(false); + setLatinKeyboard(mSymbolsKeyboard); + mSymbolsKeyboard.setShifted(false); } } else { handleCharacter(primaryCode, keyCodes); @@ -597,11 +607,11 @@ public class SoftKeyboard extends InputMethodService mInputView.setShifted(mCapsLock || !mInputView.isShifted()); } else if (currentKeyboard == mSymbolsKeyboard) { mSymbolsKeyboard.setShifted(true); - mInputView.setKeyboard(mSymbolsShiftedKeyboard); + setLatinKeyboard(mSymbolsShiftedKeyboard); mSymbolsShiftedKeyboard.setShifted(true); } else if (currentKeyboard == mSymbolsShiftedKeyboard) { mSymbolsShiftedKeyboard.setShifted(false); - mInputView.setKeyboard(mSymbolsKeyboard); + setLatinKeyboard(mSymbolsKeyboard); mSymbolsKeyboard.setShifted(false); } } @@ -629,6 +639,22 @@ public class SoftKeyboard extends InputMethodService mInputView.closing(); } + private IBinder getToken() { + final Dialog dialog = getWindow(); + if (dialog == null) { + return null; + } + final Window window = dialog.getWindow(); + if (window == null) { + return null; + } + return window.getAttributes().token; + } + + private void handleLanguageSwitch() { + mInputMethodManager.switchToNextInputMethod(getToken(), false /* onlyCurrentIme */); + } + private void checkToggleCapsLock() { long now = System.currentTimeMillis(); if (mLastShiftTime + 800 > now) {