[Autofill] Create new UI classes for the Autofill Dropdown on Android.
This code changes no behavior. It's simply in preparation for changing
the autofill dropdown in the next CLs.
Change-Id: I682c245d728c8bf3e8d5c57139b02e28a326111a
Reviewed-on: https://chromium-review.googlesource.com/1147428
Commit-Queue: Sebastien Seguin-Gagnon <sebsg@chromium.org>
Reviewed-by: Theresa <twellington@chromium.org>
Cr-Commit-Position: refs/heads/master@{#578332}
diff --git a/components/autofill/android/BUILD.gn b/components/autofill/android/BUILD.gn
index fea7272..cd72694 100644
--- a/components/autofill/android/BUILD.gn
+++ b/components/autofill/android/BUILD.gn
@@ -59,6 +59,7 @@
resource_dirs = [ "java/res" ]
deps = [
":autofill_strings_grd",
+ "//ui/android:ui_java_resources",
]
}
@@ -78,6 +79,7 @@
]
java_files = [
"java/src/org/chromium/components/autofill/AutofillDelegate.java",
+ "java/src/org/chromium/components/autofill/AutofillDropdownAdapter.java",
"java/src/org/chromium/components/autofill/AutofillPopup.java",
"java/src/org/chromium/components/autofill/AutofillSuggestion.java",
]
diff --git a/components/autofill/android/java/res/layout/autofill_dropdown_item.xml b/components/autofill/android/java/res/layout/autofill_dropdown_item.xml
new file mode 100644
index 0000000..93512e2
--- /dev/null
+++ b/components/autofill/android/java/res/layout/autofill_dropdown_item.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2018 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:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_vertical"
+ android:orientation="horizontal" >
+
+ <!-- These layout params are overwritten in DropdownAdapter.java -->
+ <ImageView
+ android:id="@+id/start_dropdown_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="@dimen/autofill_dropdown_icon_margin"
+ tools:ignore="ContentDescription" />
+
+ <LinearLayout
+ android:id="@+id/dropdown_label_wrapper"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:gravity="center_vertical"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+id/dropdown_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="@dimen/autofill_dropdown_item_label_margin"
+ android:layout_marginStart="@dimen/autofill_dropdown_item_label_margin"
+ android:ellipsize="end"
+ android:includeFontPadding="false"
+ android:singleLine="true"
+ android:textAlignment="viewStart"
+ android:textAppearance="@style/BlackTitle1" />
+
+ <TextView
+ android:id="@+id/dropdown_sublabel"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="@dimen/autofill_dropdown_item_label_margin"
+ android:layout_marginStart="@dimen/autofill_dropdown_item_label_margin"
+ android:ellipsize="end"
+ android:includeFontPadding="false"
+ android:singleLine="true"
+ android:textAlignment="viewStart"
+ android:textAppearance="@style/BlackCaption" />
+ </LinearLayout>
+
+ <ImageView
+ android:id="@+id/end_dropdown_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="8dp"
+ tools:ignore="ContentDescription" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/components/autofill/android/java/res/values/dimens.xml b/components/autofill/android/java/res/values/dimens.xml
index 1327d16e..a7224ad 100644
--- a/components/autofill/android/java/res/values/dimens.xml
+++ b/components/autofill/android/java/res/values/dimens.xml
@@ -5,4 +5,8 @@
found in the LICENSE file.
-->
<resources>
+ <dimen name="autofill_dropdown_item_height">50dp</dimen>
+ <dimen name="autofill_dropdown_item_divider_height">1px</dimen>
+ <dimen name="autofill_dropdown_item_label_margin">10dp</dimen>
+ <dimen name="autofill_dropdown_icon_margin">8dp</dimen>
</resources>
diff --git a/components/autofill/android/java/src/org/chromium/components/autofill/AutofillDropdownAdapter.java b/components/autofill/android/java/src/org/chromium/components/autofill/AutofillDropdownAdapter.java
new file mode 100644
index 0000000..42fc54c
--- /dev/null
+++ b/components/autofill/android/java/src/org/chromium/components/autofill/AutofillDropdownAdapter.java
@@ -0,0 +1,190 @@
+// Copyright 2018 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.
+
+package org.chromium.components.autofill;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.Typeface;
+import android.support.v4.view.MarginLayoutParamsCompat;
+import android.support.v4.view.ViewCompat;
+import android.support.v7.content.res.AppCompatResources;
+import android.text.TextUtils;
+import android.util.TypedValue;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AbsListView.LayoutParams;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import org.chromium.base.ApiCompatibilityUtils;
+import org.chromium.ui.DropdownDividerDrawable;
+import org.chromium.ui.DropdownItem;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Dropdown item adapter for the AutofillPopup.
+ */
+public class AutofillDropdownAdapter extends ArrayAdapter<DropdownItem> {
+ private final Context mContext;
+ private final Set<Integer> mSeparators;
+ private final boolean mAreAllItemsEnabled;
+ private final int mLabelMargin;
+
+ /**
+ * Creates an {@code ArrayAdapter} with specified parameters.
+ * @param context Application context.
+ * @param items List of labels and icons to display.
+ * @param separators Set of positions that separate {@code items}.
+ */
+ public AutofillDropdownAdapter(
+ Context context, List<? extends DropdownItem> items, Set<Integer> separators) {
+ super(context, R.layout.autofill_dropdown_item);
+ mContext = context;
+ addAll(items);
+ mSeparators = separators;
+ mAreAllItemsEnabled = checkAreAllItemsEnabled();
+ mLabelMargin = context.getResources().getDimensionPixelSize(
+ R.dimen.autofill_dropdown_item_label_margin);
+ }
+
+ private boolean checkAreAllItemsEnabled() {
+ for (int i = 0; i < getCount(); i++) {
+ DropdownItem item = getItem(i);
+ if (item.isEnabled() && !item.isGroupHeader()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View layout = convertView;
+ if (convertView == null) {
+ LayoutInflater inflater = LayoutInflater.from(mContext);
+ layout = inflater.inflate(R.layout.autofill_dropdown_item, null);
+ layout.setBackground(new DropdownDividerDrawable(/*backgroundColor=*/null));
+ }
+ DropdownDividerDrawable divider = (DropdownDividerDrawable) layout.getBackground();
+ int height = mContext.getResources().getDimensionPixelSize(
+ R.dimen.autofill_dropdown_item_height);
+
+ if (position == 0) {
+ divider.setDividerColor(Color.TRANSPARENT);
+ } else {
+ int dividerHeight = mContext.getResources().getDimensionPixelSize(
+ R.dimen.autofill_dropdown_item_divider_height);
+ height += dividerHeight;
+ divider.setHeight(dividerHeight);
+ int dividerColor;
+ if (mSeparators != null && mSeparators.contains(position)) {
+ dividerColor = ApiCompatibilityUtils.getColor(
+ mContext.getResources(), R.color.dropdown_dark_divider_color);
+ } else {
+ dividerColor = ApiCompatibilityUtils.getColor(
+ mContext.getResources(), R.color.dropdown_divider_color);
+ }
+ divider.setDividerColor(dividerColor);
+ }
+
+ DropdownItem item = getItem(position);
+
+ // Note: trying to set the height of the root LinearLayout breaks accessibility,
+ // so we have to adjust the height of this LinearLayout that wraps the TextViews instead.
+ // If you need to modify this layout, don't forget to test it with TalkBack and make sure
+ // it doesn't regress.
+ // http://crbug.com/429364
+ LinearLayout wrapper = (LinearLayout) layout.findViewById(R.id.dropdown_label_wrapper);
+ if (item.isMultilineLabel()) height = LayoutParams.WRAP_CONTENT;
+ wrapper.setOrientation(LinearLayout.VERTICAL);
+ wrapper.setLayoutParams(new LinearLayout.LayoutParams(0, height, 1));
+
+ // Layout of the main label view.
+ TextView labelView = (TextView) layout.findViewById(R.id.dropdown_label);
+ labelView.setText(item.getLabel());
+ labelView.setSingleLine(!item.isMultilineLabel());
+ if (item.isMultilineLabel()) {
+ // If there is a multiline label, we add extra padding at the top and bottom because
+ // WRAP_CONTENT, defined above for multiline labels, leaves none.
+ int existingStart = ViewCompat.getPaddingStart(labelView);
+ int existingEnd = ViewCompat.getPaddingEnd(labelView);
+ ViewCompat.setPaddingRelative(
+ labelView, existingStart, mLabelMargin, existingEnd, mLabelMargin);
+ }
+
+ labelView.setEnabled(item.isEnabled());
+ if (item.isGroupHeader() || item.isBoldLabel()) {
+ labelView.setTypeface(null, Typeface.BOLD);
+ } else {
+ labelView.setTypeface(null, Typeface.NORMAL);
+ }
+
+ labelView.setTextColor(ApiCompatibilityUtils.getColor(
+ mContext.getResources(), item.getLabelFontColorResId()));
+ labelView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
+ mContext.getResources().getDimension(R.dimen.text_size_large));
+
+ // Layout of the sublabel view, which has a smaller font and usually sits below the main
+ // label.
+ TextView sublabelView = (TextView) layout.findViewById(R.id.dropdown_sublabel);
+ CharSequence sublabel = item.getSublabel();
+ if (TextUtils.isEmpty(sublabel)) {
+ sublabelView.setVisibility(View.GONE);
+ } else {
+ sublabelView.setText(sublabel);
+ sublabelView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
+ mContext.getResources().getDimension(item.getSublabelFontSizeResId()));
+ sublabelView.setVisibility(View.VISIBLE);
+ }
+
+ ImageView iconViewStart = (ImageView) layout.findViewById(R.id.start_dropdown_icon);
+ ImageView iconViewEnd = (ImageView) layout.findViewById(R.id.end_dropdown_icon);
+ if (item.isIconAtStart()) {
+ iconViewEnd.setVisibility(View.GONE);
+ } else {
+ iconViewStart.setVisibility(View.GONE);
+ }
+
+ ImageView iconView = item.isIconAtStart() ? iconViewStart : iconViewEnd;
+ if (item.getIconId() == DropdownItem.NO_ICON) {
+ iconView.setVisibility(View.GONE);
+ } else {
+ int iconSizeResId = item.getIconSizeResId();
+ int iconSize = iconSizeResId == 0
+ ? LayoutParams.WRAP_CONTENT
+ : mContext.getResources().getDimensionPixelSize(iconSizeResId);
+ ViewGroup.MarginLayoutParams iconLayoutParams =
+ (ViewGroup.MarginLayoutParams) iconView.getLayoutParams();
+ iconLayoutParams.width = iconSize;
+ iconLayoutParams.height = iconSize;
+ int iconMargin =
+ mContext.getResources().getDimensionPixelSize(item.getIconMarginResId());
+ MarginLayoutParamsCompat.setMarginStart(iconLayoutParams, iconMargin);
+ MarginLayoutParamsCompat.setMarginEnd(iconLayoutParams, iconMargin);
+ iconView.setLayoutParams(iconLayoutParams);
+ iconView.setImageDrawable(AppCompatResources.getDrawable(mContext, item.getIconId()));
+ iconView.setVisibility(View.VISIBLE);
+ }
+
+ return layout;
+ }
+
+ @Override
+ public boolean areAllItemsEnabled() {
+ return mAreAllItemsEnabled;
+ }
+
+ @Override
+ public boolean isEnabled(int position) {
+ if (position < 0 || position >= getCount()) return false;
+ DropdownItem item = getItem(position);
+ return item.isEnabled() && !item.isGroupHeader();
+ }
+}
diff --git a/components/autofill/android/java/src/org/chromium/components/autofill/AutofillPopup.java b/components/autofill/android/java/src/org/chromium/components/autofill/AutofillPopup.java
index 914e6fb5..891731c 100644
--- a/components/autofill/android/java/src/org/chromium/components/autofill/AutofillPopup.java
+++ b/components/autofill/android/java/src/org/chromium/components/autofill/AutofillPopup.java
@@ -13,7 +13,6 @@
import android.widget.AdapterView;
import android.widget.PopupWindow;
-import org.chromium.ui.DropdownAdapter;
import org.chromium.ui.DropdownItem;
import org.chromium.ui.DropdownPopupWindow;
@@ -86,7 +85,7 @@
}
}
- setAdapter(new DropdownAdapter(mContext, cleanedData, separators));
+ setAdapter(new AutofillDropdownAdapter(mContext, cleanedData, separators));
setRtl(isRtl);
show();
getListView().setOnItemLongClickListener(this);
@@ -107,7 +106,7 @@
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- DropdownAdapter adapter = (DropdownAdapter) parent.getAdapter();
+ AutofillDropdownAdapter adapter = (AutofillDropdownAdapter) parent.getAdapter();
int listIndex = mSuggestions.indexOf(adapter.getItem(position));
assert listIndex > -1;
mAutofillDelegate.suggestionSelected(listIndex);
@@ -115,7 +114,7 @@
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
- DropdownAdapter adapter = (DropdownAdapter) parent.getAdapter();
+ AutofillDropdownAdapter adapter = (AutofillDropdownAdapter) parent.getAdapter();
AutofillSuggestion suggestion = (AutofillSuggestion) adapter.getItem(position);
if (!suggestion.isDeletable()) return false;
diff --git a/ui/android/java/src/org/chromium/ui/DropdownDividerDrawable.java b/ui/android/java/src/org/chromium/ui/DropdownDividerDrawable.java
index 1b45064f..8a6f4782 100644
--- a/ui/android/java/src/org/chromium/ui/DropdownDividerDrawable.java
+++ b/ui/android/java/src/org/chromium/ui/DropdownDividerDrawable.java
@@ -11,8 +11,10 @@
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
-class DropdownDividerDrawable extends Drawable {
-
+/**
+ * A drawable divider to be used by dropdown adapters.
+ */
+public class DropdownDividerDrawable extends Drawable {
private final Paint mPaint;
private final Rect mDividerRect;
private final Integer mBackgroundColor;