8080import android .util .Slog ;
8181import android .util .Xml ;
8282import android .view .IWindowManager ;
83+ import android .view .LayoutInflater ;
84+ import android .view .View ;
85+ import android .view .ViewGroup ;
8386import android .view .WindowManager ;
8487import android .view .inputmethod .EditorInfo ;
8588import android .view .inputmethod .InputBinding ;
8689import android .view .inputmethod .InputMethod ;
8790import android .view .inputmethod .InputMethodInfo ;
8891import android .view .inputmethod .InputMethodManager ;
8992import android .view .inputmethod .InputMethodSubtype ;
93+ import android .widget .ArrayAdapter ;
94+ import android .widget .RadioButton ;
95+ import android .widget .TextView ;
9096
9197import java .io .File ;
9298import java .io .FileDescriptor ;
@@ -337,11 +343,10 @@ public String toString() {
337343 int mBackDisposition = InputMethodService .BACK_DISPOSITION_DEFAULT ;
338344 int mImeWindowVis ;
339345
340- AlertDialog .Builder mDialogBuilder ;
341- AlertDialog mSwitchingDialog ;
342- InputMethodInfo [] mIms ;
343- CharSequence [] mItems ;
344- int [] mSubtypeIds ;
346+ private AlertDialog .Builder mDialogBuilder ;
347+ private AlertDialog mSwitchingDialog ;
348+ private InputMethodInfo [] mIms ;
349+ private int [] mSubtypeIds ;
345350
346351 class SettingsObserver extends ContentObserver {
347352 SettingsObserver (Handler handler ) {
@@ -1148,7 +1153,7 @@ public void setImeWindowStatus(IBinder token, int vis, int backDisposition) {
11481153 ? TextUtils .concat (mCurrentSubtype .getDisplayName (mContext ,
11491154 imi .getPackageName (), imi .getServiceInfo ().applicationInfo ),
11501155 (TextUtils .isEmpty (imiLabel ) ?
1151- "" : " ( " + imiLabel + ")" ))
1156+ "" : " - " + imiLabel ))
11521157 : imiLabel ;
11531158
11541159 mImeSwitcherNotification .setLatestEventInfo (
@@ -2073,8 +2078,7 @@ public int compare(InputMethodInfo imi1, InputMethodInfo imi2) {
20732078
20742079 sortedImmis .putAll (immis );
20752080
2076- final ArrayList <Pair <CharSequence , Pair <InputMethodInfo , Integer >>> imList =
2077- new ArrayList <Pair <CharSequence , Pair <InputMethodInfo , Integer >>>();
2081+ final ArrayList <ImeSubtypeListItem > imList = new ArrayList <ImeSubtypeListItem >();
20782082
20792083 for (InputMethodInfo imi : sortedImmis .keySet ()) {
20802084 if (imi == null ) continue ;
@@ -2084,7 +2088,7 @@ public int compare(InputMethodInfo imi1, InputMethodInfo imi2) {
20842088 enabledSubtypeSet .add (String .valueOf (subtype .hashCode ()));
20852089 }
20862090 ArrayList <InputMethodSubtype > subtypes = getSubtypes (imi );
2087- final CharSequence label = imi .loadLabel (pm );
2091+ final CharSequence imeLabel = imi .loadLabel (pm );
20882092 if (showSubtypes && enabledSubtypeSet .size () > 0 ) {
20892093 final int subtypeCount = imi .getSubtypeCount ();
20902094 if (DEBUG ) {
@@ -2096,37 +2100,29 @@ public int compare(InputMethodInfo imi1, InputMethodInfo imi2) {
20962100 // We show all enabled IMEs and subtypes when an IME is shown.
20972101 if (enabledSubtypeSet .contains (subtypeHashCode )
20982102 && ((mInputShown && !isScreenLocked ) || !subtype .isAuxiliary ())) {
2099- final CharSequence title ;
2100- final String mode = subtype .getMode ();
2101- title = TextUtils .concat (subtype .getDisplayName (context ,
2102- imi .getPackageName (), imi .getServiceInfo ().applicationInfo ),
2103- (TextUtils .isEmpty (label ) ? "" : " (" + label + ")" ));
2104- imList .add (new Pair <CharSequence , Pair <InputMethodInfo , Integer >>(
2105- title , new Pair <InputMethodInfo , Integer >(imi , j )));
2103+ final CharSequence subtypeLabel = subtype .getDisplayName (context ,
2104+ imi .getPackageName (), imi .getServiceInfo ().applicationInfo );
2105+ imList .add (new ImeSubtypeListItem (imeLabel , subtypeLabel , imi , j ));
2106+
21062107 // Removing this subtype from enabledSubtypeSet because we no longer
21072108 // need to add an entry of this subtype to imList to avoid duplicated
21082109 // entries.
21092110 enabledSubtypeSet .remove (subtypeHashCode );
21102111 }
21112112 }
21122113 } else {
2113- imList .add (new Pair <CharSequence , Pair <InputMethodInfo , Integer >>(
2114- label , new Pair <InputMethodInfo , Integer >(imi , NOT_A_SUBTYPE_ID )));
2114+ imList .add (new ImeSubtypeListItem (imeLabel , null , imi , NOT_A_SUBTYPE_ID ));
21152115 }
21162116 }
21172117
21182118 final int N = imList .size ();
2119- mItems = new CharSequence [N ];
2120- for (int i = 0 ; i < N ; ++i ) {
2121- mItems [i ] = imList .get (i ).first ;
2122- }
21232119 mIms = new InputMethodInfo [N ];
21242120 mSubtypeIds = new int [N ];
21252121 int checkedItem = 0 ;
21262122 for (int i = 0 ; i < N ; ++i ) {
2127- Pair < InputMethodInfo , Integer > value = imList .get (i ). second ;
2128- mIms [i ] = value . first ;
2129- mSubtypeIds [i ] = value . second ;
2123+ final ImeSubtypeListItem item = imList .get (i );
2124+ mIms [i ] = item . mImi ;
2125+ mSubtypeIds [i ] = item . mSubtypeId ;
21302126 if (mIms [i ].getId ().equals (lastInputMethodId )) {
21312127 int subtypeId = mSubtypeIds [i ];
21322128 if ((subtypeId == NOT_A_SUBTYPE_ID )
@@ -2137,14 +2133,7 @@ public int compare(InputMethodInfo imi1, InputMethodInfo imi2) {
21372133 }
21382134 }
21392135
2140- AlertDialog .OnClickListener adocl = new AlertDialog .OnClickListener () {
2141- @ Override
2142- public void onClick (DialogInterface dialog , int which ) {
2143- hideInputMethodMenu ();
2144- }
2145- };
2146-
2147- TypedArray a = context .obtainStyledAttributes (null ,
2136+ final TypedArray a = context .obtainStyledAttributes (null ,
21482137 com .android .internal .R .styleable .DialogPreference ,
21492138 com .android .internal .R .attr .alertDialogStyle , 0 );
21502139 mDialogBuilder = new AlertDialog .Builder (context )
@@ -2159,7 +2148,11 @@ public void onCancel(DialogInterface dialog) {
21592148 com .android .internal .R .styleable .DialogPreference_dialogTitle ));
21602149 a .recycle ();
21612150
2162- mDialogBuilder .setSingleChoiceItems (mItems , checkedItem ,
2151+ final ImeSubtypeListAdapter adapter = new ImeSubtypeListAdapter (context ,
2152+ com .android .internal .R .layout .simple_list_item_2_single_choice , imList ,
2153+ checkedItem );
2154+
2155+ mDialogBuilder .setSingleChoiceItems (adapter , checkedItem ,
21632156 new AlertDialog .OnClickListener () {
21642157 @ Override
21652158 public void onClick (DialogInterface dialog , int which ) {
@@ -2201,6 +2194,59 @@ public void onClick(DialogInterface dialog, int whichButton) {
22012194 }
22022195 }
22032196
2197+ private static class ImeSubtypeListItem {
2198+ public final CharSequence mImeName ;
2199+ public final CharSequence mSubtypeName ;
2200+ public final InputMethodInfo mImi ;
2201+ public final int mSubtypeId ;
2202+ public ImeSubtypeListItem (CharSequence imeName , CharSequence subtypeName ,
2203+ InputMethodInfo imi , int subtypeId ) {
2204+ mImeName = imeName ;
2205+ mSubtypeName = subtypeName ;
2206+ mImi = imi ;
2207+ mSubtypeId = subtypeId ;
2208+ }
2209+ }
2210+
2211+ private static class ImeSubtypeListAdapter extends ArrayAdapter <ImeSubtypeListItem > {
2212+ private final LayoutInflater mInflater ;
2213+ private final int mTextViewResourceId ;
2214+ private final List <ImeSubtypeListItem > mItemsList ;
2215+ private final int mCheckedItem ;
2216+ public ImeSubtypeListAdapter (Context context , int textViewResourceId ,
2217+ List <ImeSubtypeListItem > itemsList , int checkedItem ) {
2218+ super (context , textViewResourceId , itemsList );
2219+ mTextViewResourceId = textViewResourceId ;
2220+ mItemsList = itemsList ;
2221+ mCheckedItem = checkedItem ;
2222+ mInflater = (LayoutInflater )context .getSystemService (Context .LAYOUT_INFLATER_SERVICE );
2223+ }
2224+
2225+ @ Override
2226+ public View getView (int position , View convertView , ViewGroup parent ) {
2227+ final View view = convertView != null ? convertView
2228+ : mInflater .inflate (mTextViewResourceId , null );
2229+ if (position < 0 || position >= mItemsList .size ()) return view ;
2230+ final ImeSubtypeListItem item = mItemsList .get (position );
2231+ final CharSequence imeName = item .mImeName ;
2232+ final CharSequence subtypeName = item .mSubtypeName ;
2233+ final TextView firstTextView = (TextView )view .findViewById (android .R .id .text1 );
2234+ final TextView secondTextView = (TextView )view .findViewById (android .R .id .text2 );
2235+ if (TextUtils .isEmpty (subtypeName )) {
2236+ firstTextView .setText (imeName );
2237+ secondTextView .setVisibility (View .GONE );
2238+ } else {
2239+ firstTextView .setText (subtypeName );
2240+ secondTextView .setText (imeName );
2241+ secondTextView .setVisibility (View .VISIBLE );
2242+ }
2243+ final RadioButton radioButton =
2244+ (RadioButton )view .findViewById (com .android .internal .R .id .radio );
2245+ radioButton .setChecked (position == mCheckedItem );
2246+ return view ;
2247+ }
2248+ }
2249+
22042250 void hideInputMethodMenu () {
22052251 synchronized (mMethodMap ) {
22062252 hideInputMethodMenuLocked ();
@@ -2216,7 +2262,6 @@ void hideInputMethodMenuLocked() {
22162262 }
22172263
22182264 mDialogBuilder = null ;
2219- mItems = null ;
22202265 mIms = null ;
22212266 }
22222267
0 commit comments