Two line item for the IME switcher dialog.

bug: 5098770
Change-Id: I2b955973e7f223d8c98d8dac6aaa657a7a31b555
This commit is contained in:
Ken Wakasa
2011-08-22 15:22:43 +09:00
parent dbfba8560d
commit 05dbb65dfa
2 changed files with 139 additions and 35 deletions

View File

@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2011 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:paddingLeft="16dip"
android:paddingRight="12dip"
android:minHeight="?android:attr/listPreferredItemHeightSmall">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
android:gravity="center_vertical">
<TextView android:id="@android:id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="?android:attr/textColorAlertDialogListItem"
android:gravity="center_vertical|left"
android:singleLine="true"
android:ellipsize="marquee"
/>
<TextView android:id="@android:id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorAlertDialogListItem"
android:gravity="center_vertical|left"
android:singleLine="true"
android:ellipsize="marquee"
/>
</LinearLayout>
<RadioButton
android:id="@+id/radio"
android:layout_width="35dip"
android:layout_height="wrap_content"
android:paddingRight="12dip"
android:gravity="center_vertical"
android:focusable="false"
android:clickable="false"
/>
</LinearLayout>

View File

@@ -80,6 +80,9 @@ import android.util.Printer;
import android.util.Slog; import android.util.Slog;
import android.util.Xml; import android.util.Xml;
import android.view.IWindowManager; import android.view.IWindowManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager; import android.view.WindowManager;
import android.view.inputmethod.EditorInfo; import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputBinding; import android.view.inputmethod.InputBinding;
@@ -87,6 +90,9 @@ import android.view.inputmethod.InputMethod;
import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodSubtype; import android.view.inputmethod.InputMethodSubtype;
import android.widget.ArrayAdapter;
import android.widget.RadioButton;
import android.widget.TextView;
import java.io.File; import java.io.File;
import java.io.FileDescriptor; import java.io.FileDescriptor;
@@ -337,11 +343,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
int mBackDisposition = InputMethodService.BACK_DISPOSITION_DEFAULT; int mBackDisposition = InputMethodService.BACK_DISPOSITION_DEFAULT;
int mImeWindowVis; int mImeWindowVis;
AlertDialog.Builder mDialogBuilder; private AlertDialog.Builder mDialogBuilder;
AlertDialog mSwitchingDialog; private AlertDialog mSwitchingDialog;
InputMethodInfo[] mIms; private InputMethodInfo[] mIms;
CharSequence[] mItems; private int[] mSubtypeIds;
int[] mSubtypeIds;
class SettingsObserver extends ContentObserver { class SettingsObserver extends ContentObserver {
SettingsObserver(Handler handler) { SettingsObserver(Handler handler) {
@@ -1148,7 +1153,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
? TextUtils.concat(mCurrentSubtype.getDisplayName(mContext, ? TextUtils.concat(mCurrentSubtype.getDisplayName(mContext,
imi.getPackageName(), imi.getServiceInfo().applicationInfo), imi.getPackageName(), imi.getServiceInfo().applicationInfo),
(TextUtils.isEmpty(imiLabel) ? (TextUtils.isEmpty(imiLabel) ?
"" : " (" + imiLabel + ")")) "" : " - " + imiLabel))
: imiLabel; : imiLabel;
mImeSwitcherNotification.setLatestEventInfo( mImeSwitcherNotification.setLatestEventInfo(
@@ -2073,8 +2078,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
sortedImmis.putAll(immis); sortedImmis.putAll(immis);
final ArrayList<Pair<CharSequence, Pair<InputMethodInfo, Integer>>> imList = final ArrayList<ImeSubtypeListItem> imList = new ArrayList<ImeSubtypeListItem>();
new ArrayList<Pair<CharSequence, Pair<InputMethodInfo, Integer>>>();
for (InputMethodInfo imi : sortedImmis.keySet()) { for (InputMethodInfo imi : sortedImmis.keySet()) {
if (imi == null) continue; if (imi == null) continue;
@@ -2084,7 +2088,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
enabledSubtypeSet.add(String.valueOf(subtype.hashCode())); enabledSubtypeSet.add(String.valueOf(subtype.hashCode()));
} }
ArrayList<InputMethodSubtype> subtypes = getSubtypes(imi); ArrayList<InputMethodSubtype> subtypes = getSubtypes(imi);
final CharSequence label = imi.loadLabel(pm); final CharSequence imeLabel = imi.loadLabel(pm);
if (showSubtypes && enabledSubtypeSet.size() > 0) { if (showSubtypes && enabledSubtypeSet.size() > 0) {
final int subtypeCount = imi.getSubtypeCount(); final int subtypeCount = imi.getSubtypeCount();
if (DEBUG) { if (DEBUG) {
@@ -2096,13 +2100,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
// We show all enabled IMEs and subtypes when an IME is shown. // We show all enabled IMEs and subtypes when an IME is shown.
if (enabledSubtypeSet.contains(subtypeHashCode) if (enabledSubtypeSet.contains(subtypeHashCode)
&& ((mInputShown && !isScreenLocked) || !subtype.isAuxiliary())) { && ((mInputShown && !isScreenLocked) || !subtype.isAuxiliary())) {
final CharSequence title; final CharSequence subtypeLabel = subtype.getDisplayName(context,
final String mode = subtype.getMode(); imi.getPackageName(), imi.getServiceInfo().applicationInfo);
title = TextUtils.concat(subtype.getDisplayName(context, imList.add(new ImeSubtypeListItem(imeLabel, subtypeLabel, imi, j));
imi.getPackageName(), imi.getServiceInfo().applicationInfo),
(TextUtils.isEmpty(label) ? "" : " (" + label + ")"));
imList.add(new Pair<CharSequence, Pair<InputMethodInfo, Integer>>(
title, new Pair<InputMethodInfo, Integer>(imi, j)));
// Removing this subtype from enabledSubtypeSet because we no longer // Removing this subtype from enabledSubtypeSet because we no longer
// need to add an entry of this subtype to imList to avoid duplicated // need to add an entry of this subtype to imList to avoid duplicated
// entries. // entries.
@@ -2110,23 +2111,18 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
} }
} }
} else { } else {
imList.add(new Pair<CharSequence, Pair<InputMethodInfo, Integer>>( imList.add(new ImeSubtypeListItem(imeLabel, null, imi, NOT_A_SUBTYPE_ID));
label, new Pair<InputMethodInfo, Integer>(imi, NOT_A_SUBTYPE_ID)));
} }
} }
final int N = imList.size(); final int N = imList.size();
mItems = new CharSequence[N];
for (int i = 0; i < N; ++i) {
mItems[i] = imList.get(i).first;
}
mIms = new InputMethodInfo[N]; mIms = new InputMethodInfo[N];
mSubtypeIds = new int[N]; mSubtypeIds = new int[N];
int checkedItem = 0; int checkedItem = 0;
for (int i = 0; i < N; ++i) { for (int i = 0; i < N; ++i) {
Pair<InputMethodInfo, Integer> value = imList.get(i).second; final ImeSubtypeListItem item = imList.get(i);
mIms[i] = value.first; mIms[i] = item.mImi;
mSubtypeIds[i] = value.second; mSubtypeIds[i] = item.mSubtypeId;
if (mIms[i].getId().equals(lastInputMethodId)) { if (mIms[i].getId().equals(lastInputMethodId)) {
int subtypeId = mSubtypeIds[i]; int subtypeId = mSubtypeIds[i];
if ((subtypeId == NOT_A_SUBTYPE_ID) if ((subtypeId == NOT_A_SUBTYPE_ID)
@@ -2137,14 +2133,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
} }
} }
AlertDialog.OnClickListener adocl = new AlertDialog.OnClickListener() { final TypedArray a = context.obtainStyledAttributes(null,
@Override
public void onClick(DialogInterface dialog, int which) {
hideInputMethodMenu();
}
};
TypedArray a = context.obtainStyledAttributes(null,
com.android.internal.R.styleable.DialogPreference, com.android.internal.R.styleable.DialogPreference,
com.android.internal.R.attr.alertDialogStyle, 0); com.android.internal.R.attr.alertDialogStyle, 0);
mDialogBuilder = new AlertDialog.Builder(context) mDialogBuilder = new AlertDialog.Builder(context)
@@ -2159,7 +2148,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
com.android.internal.R.styleable.DialogPreference_dialogTitle)); com.android.internal.R.styleable.DialogPreference_dialogTitle));
a.recycle(); a.recycle();
mDialogBuilder.setSingleChoiceItems(mItems, checkedItem, final ImeSubtypeListAdapter adapter = new ImeSubtypeListAdapter(context,
com.android.internal.R.layout.simple_list_item_2_single_choice, imList,
checkedItem);
mDialogBuilder.setSingleChoiceItems(adapter, checkedItem,
new AlertDialog.OnClickListener() { new AlertDialog.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
@@ -2201,6 +2194,59 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
} }
} }
private static class ImeSubtypeListItem {
public final CharSequence mImeName;
public final CharSequence mSubtypeName;
public final InputMethodInfo mImi;
public final int mSubtypeId;
public ImeSubtypeListItem(CharSequence imeName, CharSequence subtypeName,
InputMethodInfo imi, int subtypeId) {
mImeName = imeName;
mSubtypeName = subtypeName;
mImi = imi;
mSubtypeId = subtypeId;
}
}
private static class ImeSubtypeListAdapter extends ArrayAdapter<ImeSubtypeListItem> {
private final LayoutInflater mInflater;
private final int mTextViewResourceId;
private final List<ImeSubtypeListItem> mItemsList;
private final int mCheckedItem;
public ImeSubtypeListAdapter(Context context, int textViewResourceId,
List<ImeSubtypeListItem> itemsList, int checkedItem) {
super(context, textViewResourceId, itemsList);
mTextViewResourceId = textViewResourceId;
mItemsList = itemsList;
mCheckedItem = checkedItem;
mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final View view = convertView != null ? convertView
: mInflater.inflate(mTextViewResourceId, null);
if (position < 0 || position >= mItemsList.size()) return view;
final ImeSubtypeListItem item = mItemsList.get(position);
final CharSequence imeName = item.mImeName;
final CharSequence subtypeName = item.mSubtypeName;
final TextView firstTextView = (TextView)view.findViewById(android.R.id.text1);
final TextView secondTextView = (TextView)view.findViewById(android.R.id.text2);
if (TextUtils.isEmpty(subtypeName)) {
firstTextView.setText(imeName);
secondTextView.setVisibility(View.GONE);
} else {
firstTextView.setText(subtypeName);
secondTextView.setText(imeName);
secondTextView.setVisibility(View.VISIBLE);
}
final RadioButton radioButton =
(RadioButton)view.findViewById(com.android.internal.R.id.radio);
radioButton.setChecked(position == mCheckedItem);
return view;
}
}
void hideInputMethodMenu() { void hideInputMethodMenu() {
synchronized (mMethodMap) { synchronized (mMethodMap) {
hideInputMethodMenuLocked(); hideInputMethodMenuLocked();
@@ -2216,7 +2262,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
} }
mDialogBuilder = null; mDialogBuilder = null;
mItems = null;
mIms = null; mIms = null;
} }