Implement multiple locales and sublocales in Settings
Does drag-and-drop reordering, supports adding / removing locales,
suggestions, search, removes locales already selected in the
user preferences.
Bug: 25800339
Change-Id: Iffe7b9810c77ec93a84d848ab20b2ba405249676
diff --git a/src/com/android/settings/InstrumentedFragment.java b/src/com/android/settings/InstrumentedFragment.java
index 58b8eb0..bb2f948 100644
--- a/src/com/android/settings/InstrumentedFragment.java
+++ b/src/com/android/settings/InstrumentedFragment.java
@@ -37,6 +37,7 @@
public static final int DATA_USAGE_LIST = UNDECLARED + 7;
public static final int BILLING_CYCLE = UNDECLARED + 8;
public static final int APP_DATA_USAGE = UNDECLARED + 9;
+ public static final int USER_LOCALE_LIST = UNDECLARED + 10;
/**
* Declare the view of this category.
diff --git a/src/com/android/settings/LocalePicker.java b/src/com/android/settings/LocalePicker.java
deleted file mode 100644
index 950b79c..0000000
--- a/src/com/android/settings/LocalePicker.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-package com.android.settings;
-
-import android.app.Dialog;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ListView;
-
-import com.android.settings.SettingsPreferenceFragment.SettingsDialogFragment;
-
-import java.util.Locale;
-
-public class LocalePicker extends com.android.internal.app.LocalePickerWithRegion
- implements com.android.internal.app.LocalePickerWithRegion.LocaleSelectionListener,
- DialogCreatable {
-
- private static final String TAG = "LocalePicker";
-
- private SettingsDialogFragment mDialogFragment;
- private static final int DLG_SHOW_GLOBAL_WARNING = 1;
- private static final String SAVE_TARGET_LOCALE = "locale";
-
- private Locale mTargetLocale;
-
- public LocalePicker() {
- super();
- setLocaleSelectionListener(this);
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- if (savedInstanceState != null && savedInstanceState.containsKey(SAVE_TARGET_LOCALE)) {
- mTargetLocale = new Locale(savedInstanceState.getString(SAVE_TARGET_LOCALE));
- }
- }
-
- @Override
- public View onCreateView(
- LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- final View view = super.onCreateView(inflater, container, savedInstanceState);
- final ListView list = (ListView) view.findViewById(android.R.id.list);
- Utils.forcePrepareCustomPreferencesList(container, view, list, false);
- return view;
- }
-
- @Override
- public void onLocaleSelected(final Locale locale) {
- if (Utils.hasMultipleUsers(getActivity())) {
- mTargetLocale = locale;
- showDialog(DLG_SHOW_GLOBAL_WARNING);
- } else {
- getActivity().onBackPressed();
- com.android.internal.app.LocalePicker.updateLocale(locale);
- }
- }
-
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
-
- if (mTargetLocale != null) {
- outState.putString(SAVE_TARGET_LOCALE, mTargetLocale.toString());
- }
- }
-
- protected void showDialog(int dialogId) {
- if (mDialogFragment != null) {
- Log.e(TAG, "Old dialog fragment not null!");
- }
- mDialogFragment = new SettingsDialogFragment(this, dialogId);
- mDialogFragment.show(getActivity().getFragmentManager(), Integer.toString(dialogId));
- }
-
- public Dialog onCreateDialog(final int dialogId) {
- return Utils.buildGlobalChangeWarningDialog(getActivity(),
- R.string.global_locale_change_title,
- new Runnable() {
- public void run() {
- removeDialog(dialogId);
- getActivity().onBackPressed();
- com.android.internal.app.LocalePicker.updateLocale(mTargetLocale);
- }
- }
- );
- }
-
- protected void removeDialog(int dialogId) {
- // mDialogFragment may not be visible yet in parent fragment's onResume().
- // To be able to dismiss dialog at that time, don't check
- // mDialogFragment.isVisible().
- if (mDialogFragment != null && mDialogFragment.getDialogId() == dialogId) {
- mDialogFragment.dismiss();
- }
- mDialogFragment = null;
- }
-}
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index dab2cb7..88cfc74 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -80,6 +80,7 @@
import com.android.settings.inputmethod.KeyboardLayoutPickerFragment;
import com.android.settings.inputmethod.SpellCheckersSettings;
import com.android.settings.inputmethod.UserDictionaryList;
+import com.android.settings.localepicker.LocaleListEditor;
import com.android.settings.location.LocationSettings;
import com.android.settings.nfc.AndroidBeam;
import com.android.settings.nfc.PaymentSettings;
@@ -246,7 +247,7 @@
WifiP2pSettings.class.getName(),
VpnSettings.class.getName(),
DateTimeSettings.class.getName(),
- LocalePicker.class.getName(),
+ LocaleListEditor.class.getName(),
InputMethodAndLanguageSettings.class.getName(),
SpellCheckersSettings.class.getName(),
UserDictionaryList.class.getName(),
diff --git a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
index aa2d68a..9022538 100644
--- a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
+++ b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
@@ -43,6 +43,7 @@
import android.support.v7.preference.PreferenceManager;
import android.support.v7.preference.PreferenceScreen;
import android.text.TextUtils;
+import android.util.LocaleList;
import android.view.InputDevice;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
@@ -50,6 +51,7 @@
import android.view.textservice.SpellCheckerInfo;
import android.view.textservice.TextServicesManager;
+import com.android.internal.app.LocaleHelper;
import com.android.internal.app.LocalePicker;
import com.android.internal.logging.MetricsLogger;
import com.android.settings.R;
@@ -266,8 +268,8 @@
if (!mShowsOnlyFullImeAndKeyboardList) {
if (mLanguagePref != null) {
- String localeName = getLocaleName(getActivity());
- mLanguagePref.setSummary(localeName);
+ String localeNames = getLocaleNames(getActivity());
+ mLanguagePref.setSummary(localeNames);
}
updateUserDictionaryPreference(findPreference(KEY_USER_DICTIONARY_SETTINGS));
@@ -340,19 +342,9 @@
return super.onPreferenceTreeClick(preference);
}
- private static String getLocaleName(Context context) {
- // We want to show the same string that the LocalePicker used.
- // TODO: should this method be in LocalePicker instead?
- Locale currentLocale = context.getResources().getConfiguration().locale;
- List<LocalePicker.LocaleInfo> locales = LocalePicker.getAllAssetLocales(context, true);
- for (LocalePicker.LocaleInfo locale : locales) {
- if (locale.getLocale().equals(currentLocale)) {
- return locale.getLabel();
- }
- }
- // This can't happen as long as the locale was one set by Settings.
- // Fall back in case a developer is testing an unsupported locale.
- return currentLocale.getDisplayName(currentLocale);
+ private static String getLocaleNames(Context context) {
+ final LocaleList locales = LocalePicker.getLocales();
+ return LocaleHelper.getDisplayLocaleList(locales, Locale.getDefault());
}
private void saveInputMethodSelectorVisibility(String value) {
@@ -665,8 +657,8 @@
@Override
public void setListening(boolean listening) {
if (listening) {
- String localeName = getLocaleName(mContext);
- mSummaryLoader.setSummary(this, localeName);
+ String localeNames = getLocaleNames(mContext);
+ mSummaryLoader.setSummary(this, localeNames);
}
}
}
@@ -690,12 +682,12 @@
// Locale picker.
if (context.getAssets().getLocales().length > 1) {
- String localeName = getLocaleName(context);
+ String localeNames = getLocaleNames(context);
SearchIndexableRaw indexable = new SearchIndexableRaw(context);
indexable.key = KEY_PHONE_LANGUAGE;
indexable.title = context.getString(R.string.phone_language);
- indexable.summaryOn = localeName;
- indexable.summaryOff = localeName;
+ indexable.summaryOn = localeNames;
+ indexable.summaryOff = localeNames;
indexable.screenTitle = screenTitle;
indexables.add(indexable);
}
diff --git a/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java b/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java
new file mode 100644
index 0000000..b1f68b9
--- /dev/null
+++ b/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+package com.android.settings.localepicker;
+
+import android.content.Context;
+import android.support.v4.view.MotionEventCompat;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.helper.ItemTouchHelper;
+import android.util.LocaleList;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.CompoundButton;
+
+import com.android.settings.R;
+
+import com.android.internal.app.LocalePicker;
+import com.android.internal.app.LocaleStore;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+
+
+class LocaleDragAndDropAdapter
+ extends RecyclerView.Adapter<LocaleDragAndDropAdapter.CustomViewHolder> {
+
+ private final Context mContext;
+ private final List<LocaleStore.LocaleInfo> mFeedItemList;
+ private final ItemTouchHelper mItemTouchHelper;
+ private boolean mRemoveMode = false;
+ private boolean mDragEnabled = true;
+
+ class CustomViewHolder extends RecyclerView.ViewHolder implements View.OnTouchListener {
+ private final LocaleDragCell mLocaleDragCell;
+
+ public CustomViewHolder(LocaleDragCell view) {
+ super(view);
+ mLocaleDragCell = view;
+ mLocaleDragCell.getDragHandle().setOnTouchListener(this);
+ mLocaleDragCell.getTextLabel().setOnTouchListener(this);
+ mLocaleDragCell.getTranslateableLabel().setOnTouchListener(this);
+ }
+
+ public LocaleDragCell getLocaleDragCell() {
+ return mLocaleDragCell;
+ }
+
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ if (mDragEnabled) {
+ switch (MotionEventCompat.getActionMasked(event)) {
+ case MotionEvent.ACTION_DOWN:
+ mItemTouchHelper.startDrag(this);
+ }
+ }
+ return false;
+ }
+ }
+
+ public LocaleDragAndDropAdapter(Context context, List<LocaleStore.LocaleInfo> feedItemList) {
+ this.mFeedItemList = feedItemList;
+
+ this.mContext = context;
+ this.mItemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(
+ ItemTouchHelper.UP | ItemTouchHelper.DOWN, 0 /* no swipe */) {
+
+ @Override
+ public boolean onMove(RecyclerView view, RecyclerView.ViewHolder source,
+ RecyclerView.ViewHolder target) {
+ onItemMove(source.getAdapterPosition(), target.getAdapterPosition());
+ return true;
+ }
+
+ @Override
+ public void onSwiped(RecyclerView.ViewHolder viewHolder, int i) {
+ // Swipe is disabled, this is intentionally empty.
+ }
+ });
+ }
+
+ public void setRecyclerView(RecyclerView rv) {
+ mItemTouchHelper.attachToRecyclerView(rv);
+ }
+
+ @Override
+ public CustomViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
+ final LocaleDragCell item = (LocaleDragCell) LayoutInflater.from(mContext)
+ .inflate(R.layout.locale_drag_cell, viewGroup, false);
+ return new CustomViewHolder(item);
+ }
+
+ @Override
+ public void onBindViewHolder(final CustomViewHolder holder, int i) {
+ final LocaleStore.LocaleInfo feedItem = mFeedItemList.get(i);
+ final LocaleDragCell dragCell = holder.getLocaleDragCell();
+
+ String label = feedItem.getFullNameNative();
+ dragCell.setLabel(label);
+ dragCell.setLocalized(feedItem.isTranslated());
+ dragCell.setMiniLabel(Integer.toString(i + 1));
+ dragCell.setShowCheckbox(mRemoveMode);
+ dragCell.setShowMiniLabel(!mRemoveMode);
+ dragCell.setShowHandle(!mRemoveMode);
+ dragCell.setChecked(false);
+ dragCell.setTag(feedItem);
+ dragCell.getCheckbox()
+ .setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ LocaleStore.LocaleInfo feedItem =
+ (LocaleStore.LocaleInfo) holder.getLocaleDragCell().getTag();
+ feedItem.setChecked(isChecked);
+ }
+ });
+ }
+
+ @Override
+ public int getItemCount() {
+ int itemCount = (null != mFeedItemList ? mFeedItemList.size() : 0);
+ if (itemCount < 2 || mRemoveMode) {
+ setDragEnabled(false);
+ } else {
+ setDragEnabled(true);
+ }
+ return itemCount;
+ }
+
+ private void onItemMove(int fromPosition, int toPosition) {
+ Collections.swap(mFeedItemList, fromPosition, toPosition);
+ notifyItemChanged(fromPosition); // to update the numbers
+ notifyItemChanged(toPosition);
+ notifyItemMoved(fromPosition, toPosition);
+ }
+
+ void setRemoveMode(boolean removeMode) {
+ mRemoveMode = removeMode;
+ int itemCount = mFeedItemList.size();
+ for (int i = 0; i < itemCount; i++) {
+ mFeedItemList.get(i).setChecked(false);
+ notifyItemChanged(i);
+ }
+ }
+
+ void removeChecked() {
+ int itemCount = mFeedItemList.size();
+ for (int i = itemCount - 1; i >= 0; i--) {
+ if (mFeedItemList.get(i).getChecked()) {
+ mFeedItemList.remove(i);
+ }
+ }
+ notifyDataSetChanged();
+ doTheUpdate();
+ }
+
+ int getCheckedCount() {
+ int result = 0;
+ for (LocaleStore.LocaleInfo li : mFeedItemList) {
+ if (li.getChecked()) {
+ result++;
+ }
+ }
+ return result;
+ }
+
+ void addLocale(LocaleStore.LocaleInfo li) {
+ mFeedItemList.add(li);
+ notifyItemInserted(mFeedItemList.size() - 1);
+ doTheUpdate();
+ }
+
+ public void doTheUpdate() {
+ int count = mFeedItemList.size();
+ Locale[] newList = new Locale[count];
+
+ for (int i = 0; i < count; i++) {
+ LocaleStore.LocaleInfo li = mFeedItemList.get(i);
+ newList[i] = li.getLocale();
+ }
+
+ LocaleList ll = new LocaleList(newList);
+ LocalePicker.updateLocales(ll);
+ }
+
+ private void setDragEnabled(boolean enabled) {
+ mDragEnabled = enabled;
+ }
+}
diff --git a/src/com/android/settings/localepicker/LocaleDragCell.java b/src/com/android/settings/localepicker/LocaleDragCell.java
new file mode 100644
index 0000000..8b1fa3c
--- /dev/null
+++ b/src/com/android/settings/localepicker/LocaleDragCell.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+package com.android.settings.localepicker;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.CheckBox;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.settings.R;
+
+class LocaleDragCell extends LinearLayout {
+ private TextView mLabel;
+ private TextView mMiniLabel;
+ private ImageView mLocalized;
+ private CheckBox mCheckbox;
+ private ImageView mDragHandle;
+
+ public LocaleDragCell(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mLabel = (TextView) findViewById(R.id.label);
+ mLocalized = (ImageView) findViewById(R.id.l10nWarn);
+ mMiniLabel = (TextView) findViewById(R.id.miniLabel);
+ mCheckbox = (CheckBox) findViewById(R.id.checkbox);
+ mDragHandle = (ImageView) findViewById(R.id.dragHandle);
+ }
+
+ public void setShowHandle(boolean showHandle) {
+ mDragHandle.setVisibility(showHandle ? VISIBLE : GONE);
+ invalidate();
+ requestLayout();
+ }
+
+ public void setShowCheckbox(boolean showCheckbox) {
+ mCheckbox.setVisibility(showCheckbox ? VISIBLE : GONE);
+ invalidate();
+ requestLayout();
+ }
+
+ public void setChecked(boolean checked) {
+ mCheckbox.setChecked(checked);
+ }
+
+ public void setShowMiniLabel(boolean showMiniLabel) {
+ mMiniLabel.setVisibility(showMiniLabel ? VISIBLE : GONE);
+ invalidate();
+ requestLayout();
+ }
+
+ public void setMiniLabel(String miniLabelText) {
+ mMiniLabel.setText(miniLabelText);
+ invalidate();
+ }
+
+ public void setLabel(String labelText) {
+ mLabel.setText(labelText);
+ invalidate();
+ }
+
+ public void setLocalized(boolean localized) {
+ mLocalized.setVisibility(localized ? INVISIBLE : VISIBLE);
+ invalidate();
+ }
+
+ public ImageView getDragHandle() {
+ return mDragHandle;
+ }
+
+ public ImageView getTranslateableLabel() {
+ return mLocalized;
+ }
+
+ public TextView getTextLabel() {
+ return mLabel;
+ }
+
+ public CheckBox getCheckbox() {
+ return mCheckbox;
+ }
+}
diff --git a/src/com/android/settings/localepicker/LocaleListEditor.java b/src/com/android/settings/localepicker/LocaleListEditor.java
new file mode 100644
index 0000000..24e5e53
--- /dev/null
+++ b/src/com/android/settings/localepicker/LocaleListEditor.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+package com.android.settings.localepicker;
+
+import android.app.AlertDialog;
+import android.app.FragmentTransaction;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.preference.PreferenceFragment;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.util.LocaleList;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+
+import com.android.settings.R;
+
+import com.android.internal.app.LocalePicker;
+import com.android.internal.app.LocalePickerWithRegion;
+import com.android.internal.app.LocaleStore;
+import com.android.settings.InstrumentedFragment;
+import com.android.settings.SettingsPreferenceFragment;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Drag-and-drop editor for the user-ordered locale lists.
+ */
+public class LocaleListEditor extends SettingsPreferenceFragment
+ implements LocalePickerWithRegion.LocaleSelectedListener {
+
+ private static final int MENU_ID_REMOVE = Menu.FIRST + 1;
+
+ private LocaleDragAndDropAdapter mAdapter;
+ private Menu mMenu;
+ private boolean mRemoveMode;
+ private View mAddLanguage;
+
+ @Override
+ protected int getMetricsCategory() {
+ return InstrumentedFragment.USER_LOCALE_LIST;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setHasOptionsMenu(true);
+
+ LocaleStore.fillCache(this.getContext());
+ List<LocaleStore.LocaleInfo> feedsList = getUserLocaleList(this.getContext());
+ mAdapter = new LocaleDragAndDropAdapter(this.getContext(), feedsList);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstState) {
+ View result = super.onCreateView(inflater, container, savedInstState);
+ LinearLayout ll = (LinearLayout) result;
+ View myLayout = inflater.inflate(R.layout.locale_order_list, ll);
+
+ getActivity().setTitle(R.string.pref_title_lang_selection);
+
+ configureDragAndDrop(myLayout);
+ return result;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem menuItem) {
+ if (menuItem.getItemId() == MENU_ID_REMOVE) {
+ if (mRemoveMode) {
+ removeLocaleWarningDialog();
+ } else {
+ setRemoveMode(true);
+ }
+ return true;
+ }
+ return super.onOptionsItemSelected(menuItem);
+ }
+
+ private void setRemoveMode(boolean mRemoveMode) {
+ this.mRemoveMode = mRemoveMode;
+ mAdapter.setRemoveMode(mRemoveMode);
+ mMenu.findItem(MENU_ID_REMOVE).setShowAsAction(
+ mRemoveMode ? MenuItem.SHOW_AS_ACTION_ALWAYS : MenuItem.SHOW_AS_ACTION_NEVER);
+ mAddLanguage.setVisibility(mRemoveMode ? View.INVISIBLE : View.VISIBLE);
+ }
+
+ private void removeLocaleWarningDialog() {
+ int checked = mAdapter.getCheckedCount();
+
+ // Nothing checked, just exit remove mode without a warning dialog
+ if (checked == 0) {
+ setRemoveMode(!mRemoveMode);
+ return;
+ }
+
+ // All locales selected, warning dialog, can't remove them all
+ if (checked == mAdapter.getItemCount()) {
+ new AlertDialog.Builder(getActivity())
+ .setTitle(R.string.dlg_remove_locales_error_title)
+ .setMessage(R.string.dlg_remove_locales_error_message)
+ .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ }
+ })
+ .create()
+ .show();
+ return;
+ }
+
+ new AlertDialog.Builder(getActivity())
+ .setTitle(R.string.dlg_remove_locales_title)
+ .setMessage(R.string.dlg_remove_locales_message)
+ .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ setRemoveMode(!mRemoveMode);
+ }
+ })
+ .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ mAdapter.removeChecked();
+ setRemoveMode(!mRemoveMode);
+ }
+ })
+ .create()
+ .show();
+ }
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ final MenuItem menuItem =
+ menu.add(Menu.NONE, MENU_ID_REMOVE, 0, R.string.locale_remove_menu);
+ menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_WITH_TEXT);
+ menuItem.setIcon(android.R.drawable.ic_menu_delete);
+ super.onCreateOptionsMenu(menu, inflater);
+ mMenu = menu;
+ }
+
+ private static List<LocaleStore.LocaleInfo> getUserLocaleList(Context context) {
+ List<LocaleStore.LocaleInfo> result = new ArrayList<>();
+
+ LocaleList localeList = LocalePicker.getLocales();
+ for (int i = 0; i < localeList.size(); i++) {
+ Locale locale = localeList.get(i);
+ result.add(LocaleStore.getLocaleInfo(locale));
+ }
+
+ return result;
+ }
+
+ private void configureDragAndDrop(View view) {
+ RecyclerView list = (RecyclerView) view.findViewById(R.id.dragList);
+ list.setLayoutManager(new LinearLayoutManager(this.getContext()));
+
+ list.setHasFixedSize(true);
+ mAdapter.setRecyclerView(list);
+ list.setAdapter(mAdapter);
+
+ mAddLanguage = view.findViewById(R.id.add_language);
+ mAddLanguage.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ final LocalePickerWithRegion selector = LocalePickerWithRegion.createLanguagePicker(
+ getContext(), LocaleListEditor.this, false /* translate only */);
+ getFragmentManager()
+ .beginTransaction()
+ .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
+ .replace(getId(), selector)
+ .addToBackStack("localeListEditor")
+ .commit();
+ }
+ });
+ }
+
+ @Override
+ public void onLocaleSelected(LocaleStore.LocaleInfo locale) {
+ mAdapter.addLocale(locale);
+ }
+
+}
diff --git a/src/com/android/settings/localepicker/LocaleRecyclerView.java b/src/com/android/settings/localepicker/LocaleRecyclerView.java
new file mode 100644
index 0000000..b9c2b96
--- /dev/null
+++ b/src/com/android/settings/localepicker/LocaleRecyclerView.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+package com.android.settings.localepicker;
+
+import android.content.Context;
+import android.support.v7.widget.RecyclerView;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+
+class LocaleRecyclerView extends RecyclerView {
+ public LocaleRecyclerView(Context context) {
+ super(context);
+ }
+
+ public LocaleRecyclerView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LocaleRecyclerView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent e) {
+ if (e.getAction() == MotionEvent.ACTION_UP) {
+ LocaleDragAndDropAdapter adapter = (LocaleDragAndDropAdapter) this.getAdapter();
+ if (adapter != null) {
+ adapter.doTheUpdate();
+ }
+ }
+ return super.onTouchEvent(e);
+ }
+}