Update the time zone picker to work with location containing diacritics

Currently, looking for a location containing diacritics (e.g. accents) requires the user to type in exactly those characters. With this change, diacritics are ignored and the strings are returned if they match (using startsWith).
For example, looking for "reun" will show you "Réunion".

Bug: b/364245352
Test: atest tests/robotests/src/com/android/settings/datetime/timezone/BaseTimeZoneAdapterTest.java
Change-Id: I507a9ebc1c830ad3162fb2382814935fc337328d
Flag: EXEMPT bugfix
This commit is contained in:
Geoffrey Boullanger
2024-09-03 15:43:51 +00:00
parent ed519640fa
commit 766c7951fb
3 changed files with 43 additions and 17 deletions

View File

@@ -33,9 +33,11 @@ import androidx.recyclerview.widget.RecyclerView;
import com.android.settings.R;
import com.android.settings.datetime.timezone.BaseTimeZonePicker.OnListItemClickListener;
import java.text.Normalizer;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.regex.Pattern;
/**
* Used with {@class BaseTimeZonePicker}. It renders text in each item into list view. A list of
@@ -48,6 +50,9 @@ public class BaseTimeZoneAdapter<T extends BaseTimeZoneAdapter.AdapterItem>
@VisibleForTesting
static final int TYPE_ITEM = 1;
private static final Pattern PATTERN_REMOVE_DIACRITICS = Pattern.compile(
"\\p{InCombiningDiacriticalMarks}+");
private final List<T> mOriginalItems;
private final OnListItemClickListener<T> mOnListItemClickListener;
private final Locale mLocale;
@@ -183,6 +188,19 @@ public class BaseTimeZoneAdapter<T extends BaseTimeZoneAdapter.AdapterItem>
}
}
/**
* Removes diacritics (e.g. accents) from a string
*/
private static String removeDiacritics(final String str) {
if (str == null || str.isEmpty()) {
return str;
}
// decomposes the original characters into a base character and a diacritic sign
final String decomposed = Normalizer.normalize(str, Normalizer.Form.NFKD);
// replaces the diacritic signs with empty strings
return PATTERN_REMOVE_DIACRITICS.matcher(decomposed).replaceAll("");
}
@VisibleForTesting
public static class ItemViewHolder<T extends BaseTimeZoneAdapter.AdapterItem>
extends RecyclerView.ViewHolder implements View.OnClickListener {
@@ -241,13 +259,14 @@ public class BaseTimeZoneAdapter<T extends BaseTimeZoneAdapter.AdapterItem>
if (TextUtils.isEmpty(prefix)) {
newItems = mOriginalItems;
} else {
final String prefixString = prefix.toString().toLowerCase(mLocale);
final String prefixString = removeDiacritics(
prefix.toString().toLowerCase(mLocale));
newItems = new ArrayList<>();
for (T item : mOriginalItems) {
outer:
for (String searchKey : item.getSearchKeys()) {
searchKey = searchKey.toLowerCase(mLocale);
searchKey = removeDiacritics(searchKey.toLowerCase(mLocale));
// First match against the whole, non-splitted value
if (searchKey.startsWith(prefixString)) {
newItems.add(item);

View File

@@ -111,7 +111,7 @@ public class RegionZonePicker extends BaseTimeZoneInfoPicker {
/**
* Returns a list of {@link TimeZoneInfo} objects. The returned list will be sorted properly for
* display in the locale.It may be smaller than the input collection, if equivalent IDs are
* display in the locale. It may be smaller than the input collection, if equivalent IDs are
* passed in.
*
* @param timeZoneIds a list of Olson IDs.