Skip to content

Commit

Permalink
[TextField] Provide set simple items API with default item layout for…
Browse files Browse the repository at this point in the history
… MaterialAutoCompleteTextView

Resolves #692

PiperOrigin-RevId: 428832331
  • Loading branch information
drchen authored and raajkumars committed Feb 15, 2022
1 parent 13dbc9f commit 85ed993
Show file tree
Hide file tree
Showing 10 changed files with 120 additions and 50 deletions.
Expand Up @@ -22,8 +22,6 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import androidx.annotation.LayoutRes;
import androidx.annotation.Nullable;
Expand All @@ -41,38 +39,11 @@ public int getTextFieldContent() {
return R.layout.cat_textfield_exposed_dropdown_menu_content;
}

@LayoutRes
public int getAdapterItemLayout() {
return R.layout.cat_exposed_dropdown_popup_item;
}

@Override
public View onCreateDemoView(
LayoutInflater layoutInflater, @Nullable ViewGroup viewGroup, @Nullable Bundle bundle) {
View view = super.onCreateDemoView(layoutInflater, viewGroup, bundle);

ArrayAdapter<CharSequence> adapter =
new ArrayAdapter<>(
getContext(),
getAdapterItemLayout(),
getResources().getStringArray(R.array.cat_textfield_exposed_dropdown_content));

AutoCompleteTextView editTextFilledExposedDropdown =
view.findViewById(R.id.filled_exposed_dropdown);
editTextFilledExposedDropdown.setAdapter(adapter);

AutoCompleteTextView editTextFilledEditableExposedDropdown =
view.findViewById(R.id.filled_exposed_dropdown_editable);
editTextFilledEditableExposedDropdown.setAdapter(adapter);

AutoCompleteTextView editTextOutlinedExposedDropdown =
view.findViewById(R.id.outlined_exposed_dropdown);
editTextOutlinedExposedDropdown.setAdapter(adapter);

AutoCompleteTextView editTextOutlinedEditableExposedDropdown =
view.findViewById(R.id.outlined_exposed_dropdown_editable);
editTextOutlinedEditableExposedDropdown.setAdapter(adapter);

// Initialize button for toggling the leading icon's visibility.
Button toggleLeadingIconButton = view.findViewById(R.id.button_toggle_leading_icon);
toggleLeadingIconButton.setVisibility(View.VISIBLE);
Expand Down
Expand Up @@ -37,7 +37,8 @@
android:id="@+id/filled_exposed_dropdown"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none"/>
android:inputType="none"
app:simpleItems="@array/cat_textfield_exposed_dropdown_content"/>
</com.google.android.material.textfield.TextInputLayout>


Expand All @@ -54,7 +55,8 @@
<AutoCompleteTextView
android:id="@+id/filled_exposed_dropdown_editable"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
android:layout_height="wrap_content"
app:simpleItems="@array/cat_textfield_exposed_dropdown_content"/>
</com.google.android.material.textfield.TextInputLayout>

<com.google.android.material.textfield.TextInputLayout
Expand All @@ -71,7 +73,8 @@
android:id="@+id/outlined_exposed_dropdown"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none"/>
android:inputType="none"
app:simpleItems="@array/cat_textfield_exposed_dropdown_content"/>
</com.google.android.material.textfield.TextInputLayout>


Expand All @@ -88,7 +91,8 @@
<AutoCompleteTextView
android:id="@+id/outlined_exposed_dropdown_editable"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
android:layout_height="wrap_content"
app:simpleItems="@array/cat_textfield_exposed_dropdown_content"/>
</com.google.android.material.textfield.TextInputLayout>

</LinearLayout>
21 changes: 16 additions & 5 deletions docs/components/Menu.md
Expand Up @@ -474,9 +474,8 @@ using `Theme.Material3.*` themes.

The following is an example of a filled exposed dropdown menu:

![2 menu states with text field element: 1) has "item 1", 2) has an empty text
field and a 4-item menu
container.](assets/menu/menus_exposed_dropdown_filled.png)
![2 menu states with text field element: 1) has "item 1", 2) has "item 1" and a
4-item menu container.](assets/menu/menus_exposed_dropdown_filled.png)

In the layout:

Expand All @@ -492,20 +491,30 @@ In the layout:
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none"
app:simpleItems="@array/simple_items"
/>

</com.google.android.material.textfield.TextInputLayout>
```

In code:
The string array specified by `app:simpleItems` will be used as the default
item strings for auto-completion. Or you can also set it programmatically:

```kt
val items = arrayOf("Item 1", "Item 2", "Item 3", "Item 4")
(textField.editText as? MaterialAutoCompleteTextView)?.setSimpleItems(items)
```

Alternatively, to have more control over the auto-completion items rendering,
you can also provide a custom item adapter by:

```kt
val items = listOf("Item 1", "Item 2", "Item 3", "Item 4")
val adapter = ArrayAdapter(requireContext(), R.layout.list_item, items)
(textField.editText as? AutoCompleteTextView)?.setAdapter(adapter)
```

In the item layout (`list_item.xml`):
And a custom item layout (`list_item.xml`):

```xml
<TextView
Expand Down Expand Up @@ -564,6 +573,8 @@ Element | Attribute
**Cursor color** | N/A (color comes from the theme attr `?attr/colorControlActivated`) | N/A | `?attr/colorPrimary`
**Dropdown menu<br/>container color** | N/A | N/A | `?attr/colorSurface`
**Dropdown menu elevation** | `android:popupElevation` | N/A | `8dp`
**Simple items** | `app:simpleItems` | `setSimpleItems` | `null`
**Simple item layout** | `app:simpleItemLayout` | N/A | `@layout/m3_auto_complete_simple_item`

#### Styles

Expand Down
14 changes: 12 additions & 2 deletions docs/components/TextField.md
Expand Up @@ -219,20 +219,30 @@ In the layout:
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none"
app:simpleItems="@array/simple_items"
/>

</com.google.android.material.textfield.TextInputLayout>
```

In code:
The string array specified by `app:simpleItems` will be used as the default
item strings for auto-completion. Or you can also set it programmatically:

```kt
val items = arrayOf("Item 1", "Item 2", "Item 3", "Item 4")
(textField.editText as? MaterialAutoCompleteTextView)?.setSimpleItems(items)
```

Alternatively, to have more control over the auto-completion items rendering,
you can also provide a custom item adapter by:

```kt
val items = listOf("Item 1", "Item 2", "Item 3", "Item 4")
val adapter = ArrayAdapter(requireContext(), R.layout.list_item, items)
(textField.editText as? AutoCompleteTextView)?.setAdapter(adapter)
```

In the item layout (`list_item.xml`):
And a custom item layout (`list_item.xml`):

```xml
<TextView
Expand Down
Expand Up @@ -35,8 +35,11 @@
import android.view.accessibility.AccessibilityManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Filterable;
import android.widget.ListAdapter;
import androidx.annotation.ArrayRes;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.internal.ManufacturerUtils;
Expand All @@ -60,6 +63,7 @@ public class MaterialAutoCompleteTextView extends AppCompatAutoCompleteTextView
@NonNull private final ListPopupWindow modalListPopup;
@Nullable private final AccessibilityManager accessibilityManager;
@NonNull private final Rect tempRect = new Rect();
@LayoutRes private final int simpleItemLayout;

public MaterialAutoCompleteTextView(@NonNull Context context) {
this(context, null);
Expand Down Expand Up @@ -95,6 +99,10 @@ public MaterialAutoCompleteTextView(
}
}

simpleItemLayout = attributes.getResourceId(
R.styleable.MaterialAutoCompleteTextView_simpleItemLayout,
R.layout.mtrl_auto_complete_simple_item);

accessibilityManager =
(AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);

Expand Down Expand Up @@ -127,6 +135,11 @@ public void onItemClick(AdapterView<?> parent, View selectedView, int position,
}
});

if (attributes.hasValue(R.styleable.MaterialAutoCompleteTextView_simpleItems)) {
setSimpleItems(
attributes.getResourceId(R.styleable.MaterialAutoCompleteTextView_simpleItems, 0));
}

attributes.recycle();
}

Expand All @@ -145,6 +158,30 @@ public <T extends ListAdapter & Filterable> void setAdapter(@Nullable T adapter)
modalListPopup.setAdapter(getAdapter());
}

/**
* Sets the simple string items of auto-completion with the given string array resource. This
* method will create a default {@link ArrayAdapter} with a default item layout specified by
* {@code R.attr.simpleItemLayout} to display auto-complete items.
*
* @see #setSimpleItems(String[])
* @see #setAdapter(ListAdapter)
*/
public void setSimpleItems(@ArrayRes int stringArrayResId) {
setSimpleItems(getResources().getStringArray(stringArrayResId));
}

/**
* Sets the simple string items of auto-completion with the given string array. This method will
* create a default {@link ArrayAdapter} with a default item layout specified by
* {@code R.attr.simpleItemLayout} to display auto-complete items.
*
* @see #setSimpleItems(int)
* @see #setAdapter(ListAdapter)
*/
public void setSimpleItems(@NonNull String[] stringArray) {
setAdapter(new ArrayAdapter<>(getContext(), simpleItemLayout, stringArray));
}

@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
Expand Down
Expand Up @@ -98,6 +98,8 @@
<public name="passwordToggleTintMode" type="attr"/>

<public name="textInputLayoutFocusedRectEnabled" type="attr"/>
<public name="simpleItemLayout" type="attr"/>
<public name="simpleItems" type="attr"/>

<public name="Widget.Design.TextInputLayout" type="style"/>
<public name="Widget.MaterialComponents.TextInputLayout.FilledBox" type="style"/>
Expand Down
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2019 The Android Open Source Project
Copyright 2022 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.
Expand All @@ -15,12 +15,12 @@
limitations under the License.
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="13dp"
android:paddingTop="13dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="?attr/textAppearanceSubtitle1"/>
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="13dp"
android:paddingTop="13dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="?attr/textAppearanceBodyLarge"/>
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2022 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.
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="13dp"
android:paddingTop="13dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="?attr/textAppearanceSubtitle1"/>
Expand Up @@ -301,6 +301,11 @@

<declare-styleable name="MaterialAutoCompleteTextView" parent="AppCompatAutoCompleteTextView">
<attr name="android:inputType"/>

<!-- The default layout used to inflate auto-complete items -->
<attr name="simpleItemLayout" format="reference"/>
<!-- The default auto-completion items in a string array -->
<attr name="simpleItems" format="reference"/>
</declare-styleable>

</resources>
Expand Up @@ -443,18 +443,22 @@
<!-- Styles for the M3 AutoCompleteTextView. -->
<style name="Widget.Material3.AutoCompleteTextView.OutlinedBox" parent="Widget.MaterialComponents.AutoCompleteTextView.OutlinedBox">
<item name="android:textAppearance">?attr/textAppearanceBodyLarge</item>
<item name="simpleItemLayout">@layout/m3_auto_complete_simple_item</item>
</style>

<style name="Widget.Material3.AutoCompleteTextView.OutlinedBox.Dense" parent="Widget.MaterialComponents.AutoCompleteTextView.OutlinedBox.Dense">
<item name="android:textAppearance">?attr/textAppearanceBodyLarge</item>
<item name="simpleItemLayout">@layout/m3_auto_complete_simple_item</item>
</style>

<style name="Widget.Material3.AutoCompleteTextView.FilledBox" parent="Widget.MaterialComponents.AutoCompleteTextView.FilledBox">
<item name="android:textAppearance">?attr/textAppearanceBodyLarge</item>
<item name="simpleItemLayout">@layout/m3_auto_complete_simple_item</item>
</style>

<style name="Widget.Material3.AutoCompleteTextView.FilledBox.Dense" parent="Widget.MaterialComponents.AutoCompleteTextView.FilledBox.Dense">
<item name="android:textAppearance">?attr/textAppearanceBodyLarge</item>
<item name="simpleItemLayout">@layout/m3_auto_complete_simple_item</item>
</style>

<!-- ThemeOverlays to be used internally in the TextInputLayout styles to automatically apply the correct TextInputEditText style to the TextInputEditText. -->
Expand Down

0 comments on commit 85ed993

Please sign in to comment.