Skip to content

Commit

Permalink
[Merge][AppLanguagePrompt] Add Other Languages Item
Browse files Browse the repository at this point in the history
This CL makes it so the AppLanguagePrompt only shows the suggested
languages to start.  A "Other languages" item is added to the end
of the list that when click expands the list to include all languages.

(cherry picked from commit bdfa334)

Bug: 1323985
Change-Id: I0ade9f39ccfd4f8e364a50d54a89f378a52d5d03
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3648393
Reviewed-by: Josh Simmons <jds@google.com>
Commit-Queue: Trevor Perrier <perrier@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1003444}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3651354
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/5060@{#51}
Cr-Branched-From: b83393d-refs/heads/main@{#1002911}
  • Loading branch information
Trevor Perrier authored and Chromium LUCI CQ committed May 17, 2022
1 parent 48151bd commit 4d9741b
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 31 deletions.
1 change: 1 addition & 0 deletions chrome/browser/language/android/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ android_resources("java_resources") {
"java/res/layout/add_languages_main.xml",
"java/res/layout/app_language_confirm_content.xml",
"java/res/layout/app_language_prompt_content.xml",
"java/res/layout/app_language_prompt_more_languages.xml",
"java/res/layout/app_language_prompt_row.xml",
"java/res/layout/language_ask_prompt_content.xml",
"java/res/layout/language_ask_prompt_row.xml",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@
android:src="@drawable/modern_toolbar_shadow"
android:scaleType="fitXY"
android:importantForAccessibility="no"
android:layout_gravity="top"
android:visibility="invisible" />
android:layout_gravity="top" />

<ImageView
android:id="@+id/bottom_shadow"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2017 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/app_language_prompt_row"
style="@style/ListItemContainer"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="horizontal">

<!-- Invisible but used for alignment of the TextView -->
<RadioButton
android:id="@+id/app_language_prompt_radiobutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible"
android:paddingEnd="8dp" />

<!-- TODO(https://crbug.com/1325465) Change wording -->
<TextView
android:id="@+id/more_languages_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/languages_select_other"
style="@style/TextAppearance.Button.Text.Blue" />

</LinearLayout>
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;

/**
Expand All @@ -60,11 +59,12 @@ public class AppLanguagePromoDialog {
private long mStartTime;

/** Annotation for row item type. Either a LanguageItem or separator */
@IntDef({ItemType.LANGUAGE, ItemType.SEPARATOR})
@IntDef({ItemType.LANGUAGE, ItemType.SEPARATOR, ItemType.MORE_LANGUAGES})
@Retention(RetentionPolicy.SOURCE)
private @interface ItemType {
int LANGUAGE = 0;
int SEPARATOR = 1;
int MORE_LANGUAGES = 2;
}

/**
Expand Down Expand Up @@ -122,11 +122,14 @@ public AppLanguagePromoDialog(Activity activity,

/**
* Internal class for managing a list of languages in a RecyclerView.
* TODO(https://crbug.com/1325473) Refactor this to a separate file.
*/
private class LanguageItemAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<LanguageItem> mTopLanguages;
private List<LanguageItem> mOtherLanguages;
protected static class LanguageItemAdapter
extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private ArrayList<LanguageItem> mTopLanguages;
private ArrayList<LanguageItem> mOtherLanguages;
private LanguageItem mCurrentLanguage;
private boolean mShowOtherLanguages;

/**
* @param topLanguages - LanguageItems to appear at the top of the adapter list.
Expand All @@ -142,17 +145,23 @@ public LanguageItemAdapter(Collection<LanguageItem> topLanguages,

@Override
public int getItemViewType(int position) {
// The seperator is between top and other languages.
return (position == mTopLanguages.size()) ? ItemType.SEPARATOR : ItemType.LANGUAGE;
// The separator or "More languages" item is between top and other languages.
if (position != mTopLanguages.size()) return ItemType.LANGUAGE;
return mShowOtherLanguages ? ItemType.SEPARATOR : ItemType.MORE_LANGUAGES;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case ItemType.LANGUAGE:
View row = LayoutInflater.from(parent.getContext())
.inflate(R.layout.app_language_prompt_row, parent, false);
return new AppLanguagePromptRowViewHolder(row);
return new AppLanguagePromptRowViewHolder(
LayoutInflater.from(parent.getContext())
.inflate(R.layout.app_language_prompt_row, parent, false));
case ItemType.MORE_LANGUAGES:
return new MoreLanguagesRowViewHolder(
LayoutInflater.from(parent.getContext())
.inflate(R.layout.app_language_prompt_more_languages, parent,
false));
case ItemType.SEPARATOR:
return new SeparatorViewHolder(
LayoutInflater.from(parent.getContext())
Expand All @@ -166,33 +175,46 @@ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
switch (getItemViewType(position)) {
case ItemType.LANGUAGE:
LanguageItem languageItem = getLanguageItemAt(position);
((AppLanguagePromptRowViewHolder) holder)
.bindViewHolder(languageItem, languageItem.equals(mCurrentLanguage));
break;
case ItemType.SEPARATOR:
// No binding necessary for the separator.
break;
default:
assert false : "No matching viewType";
if (getItemViewType(position) == ItemType.LANGUAGE) {
LanguageItem languageItem = getLanguageItemAt(position);
((AppLanguagePromptRowViewHolder) holder)
.bindViewHolder(languageItem, languageItem.equals(mCurrentLanguage));
}
}

/**
* Modify the LanguageItemAdapter to show the other languages in addition to the top
* languages. Can only called once. The other languages can not be hidden once shown.
*/
public void showOtherLanguages() {
mShowOtherLanguages = true;
notifyItemRemoved(mTopLanguages.size()); // Remove "More languages" item.
// Other languages plus a horizontal separator have been added.
notifyItemRangeInserted(mTopLanguages.size(), mOtherLanguages.size() + 1);
}

/**
* Set the currently selected LanguageItem based on the position.
* @param postion Offset of the LanguageItem to select.
* TODO(https://crbug.com/1325522) Refactor to not use notifyDataSetChanged.
* @param position Offset of the LanguageItem to select.
*/
public void setSelectedLanguage(int position) {
mCurrentLanguage = getLanguageItemAt(position);
notifyDataSetChanged();
}

/**
* Return the number of items in the list making room for the list separator or more
* languages item.
*/
@Override
public int getItemCount() {
// Sum of both lists + a separator.
return mTopLanguages.size() + mOtherLanguages.size() + 1;
// The top languages and a separator or "More languages" item are always shown.
int count = mTopLanguages.size() + 1;
if (mShowOtherLanguages) {
count += mOtherLanguages.size();
}
return count;
}

public LanguageItem getSelectedLanguage() {
Expand All @@ -203,7 +225,7 @@ public boolean isTopLanguageSelected() {
return mTopLanguages.contains(mCurrentLanguage);
}

private LanguageItem getLanguageItemAt(int position) {
protected LanguageItem getLanguageItemAt(int position) {
if (position < mTopLanguages.size()) {
return mTopLanguages.get(position);
} else if (position > mTopLanguages.size()) {
Expand All @@ -218,7 +240,7 @@ private LanguageItem getLanguageItemAt(int position) {
/**
* Internal class representing an individual language row.
*/
private class AppLanguagePromptRowViewHolder
private static class AppLanguagePromptRowViewHolder
extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView mPrimaryNameTextView;
private TextView mSecondaryNameTextView;
Expand Down Expand Up @@ -267,10 +289,28 @@ public void bindViewHolder(LanguageItem languageItem, boolean checked) {
}
}

/**
* Internal class representing the "More languages" list item.
*/
private static class MoreLanguagesRowViewHolder
extends RecyclerView.ViewHolder implements View.OnClickListener {
MoreLanguagesRowViewHolder(View view) {
super(view);
view.setOnClickListener(this);
}

@Override
public void onClick(View row) {
// TODO(https://crbug.com/1325471) Add meteric recording action.
LanguageItemAdapter adapter = (LanguageItemAdapter) getBindingAdapter();
adapter.showOtherLanguages();
}
}

/**
* Internal class representing the separator row.
*/
private class SeparatorViewHolder extends RecyclerView.ViewHolder {
private static class SeparatorViewHolder extends RecyclerView.ViewHolder {
SeparatorViewHolder(View view) {
super(view);
}
Expand Down Expand Up @@ -298,7 +338,6 @@ protected void showAppLanguageModal() {
R.layout.app_language_prompt_content, null, false);
RecyclerView list = customView.findViewById(R.id.app_language_prompt_content_recycler_view);
list.setAdapter(mAdapter);
list.setHasFixedSize(true);

LinearLayoutManager linearLayoutManager = new LinearLayoutManager(mActivity);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
Expand All @@ -309,7 +348,7 @@ protected void showAppLanguageModal() {
ImageView bottomShadow = customView.findViewById(R.id.bottom_shadow);
list.setOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (recyclerView.canScrollVertically(-1)) {
topShadow.setVisibility(View.VISIBLE);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import org.chromium.base.LocaleUtils;
import org.chromium.base.test.util.Batch;
import org.chromium.chrome.browser.language.AppLanguagePromoDialog.LanguageItemAdapter;
import org.chromium.chrome.browser.language.settings.LanguageItem;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;

Expand Down Expand Up @@ -110,4 +111,23 @@ public void testIsOverrideLanguageOriginalSystemLanguage() {
Assert.assertFalse(AppLanguagePromoDialog.isOverrideLanguageOriginalSystemLanguage(
FOLLOW_SYSTEM, LocaleUtils.forLanguageTag("zu")));
}

// Test LanguageItemAdapter
@Test
@SmallTest
public void testLanguageItemAdapter() {
ArrayList<LanguageItem> topLanguages = new ArrayList<>(Arrays.asList(LANG_AF, LANG_AZ));
ArrayList<LanguageItem> otherLanguages =
new ArrayList<>(Arrays.asList(LANG_EN_GB, LANG_EN_US, LANG_ZU));
LanguageItem currentLanguage = LANG_AF;
LanguageItemAdapter adapter =
new LanguageItemAdapter(topLanguages, otherLanguages, currentLanguage);

// Only the top languages plus "More languages" item are showing to start.
Assert.assertEquals(3, adapter.getItemCount());

adapter.showOtherLanguages();
// All languages should now be showing.
Assert.assertEquals(6, adapter.getItemCount());
}
}

0 comments on commit 4d9741b

Please sign in to comment.