material-components / material-components-android

Modular and customizable Material Design UI components for Android
Apache License 2.0
16.42k stars 3.08k forks source link

[com.google.android.material.textfield.MaterialAutoCompleteTextView] Using ArrayAdapter don't wrap text correctly #3218

Closed juvs closed 1 year ago

juvs commented 1 year ago

Description: Using com.google.android.material.textfield.MaterialAutoCompleteTextView, define an ArrayAdapter and setting is layout adapter, but TextView is not wrapping correctly in the dropdown, on an regular Spinner, same ArrayAdapter works ok.

Expected behavior:

Both AutoCompleteTextView and Spinner.

image

AutoCompleteTextView dropDown won't wrap text.

image

Spinner dropDown works ok.

image

Source code:

Layout activity:

<com.google.android.material.textfield.TextInputLayout
                android:id="@+id/regimenFiscalTIL"
                style="@style/Widget.Material3.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginStart="@dimen/start_end_margin"
                android:layout_marginTop="16dp"
                android:layout_marginEnd="@dimen/start_end_margin"
                android:hint="@string/admin_dato_fiscal_regimen_fiscal">

                <AutoCompleteTextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:inputType="none"
                    android:labelFor="@id/regimenFiscalTIL" />
            </com.google.android.material.textfield.TextInputLayout>

Code in activity:

mAdapterDomicilio = new ArrayAdapter<>(this, R.layout.list_item_multiline);

Item layout, for dropDown item in ArrayAdapter:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tool="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:ellipsize="marquee"
    android:padding="16dp"
    android:singleLine="false"
    android:textAppearance="?android:attr/textAppearanceLargePopupMenu"
    tool:text="Sample text" />

Minimal sample app repro: MyApplication.zip

Android API version: 33

Material Library version: 1.8.0

Device: All Devices

drchen commented 1 year ago

I think it's WAI. Your spinner is wider than the text field. If you don't want your menu item to be ellipsized, please make the text input layout wider so the drop down menu can contain all the characters.

juvs commented 1 year ago

@drchen Thanks, but in my sample app, both the Spinner and TextInputLayout + AutoCompleteTextView have the same height, "wrap_content", and if you select a value int both they show the value correctly, the problem is on the dropDown items.

image

<com.google.android.material.textfield.TextInputLayout
    android:id="@+id/regimenFiscalTIL"
    style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginStart="16dp"
    android:layout_marginTop="16dp"
    android:layout_marginEnd="16dp"
    android:hint="Test 1">

    <AutoCompleteTextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="none" />
</com.google.android.material.textfield.TextInputLayout>

<Spinner
    android:id="@+id/regimenFiscal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginStart="16dp"
    android:layout_marginTop="16dp"
    android:layout_marginEnd="16dp" />
drchen commented 1 year ago

TextInputLayout has its own paddings. So the actual measured width of AutoCompleteTextView will be narrower than the Spinner I believe. (it can also be seen in your previous screenshots.)

juvs commented 1 year ago

@drchen Sorry to insist, the problem is not the width of both components (Spinner/AutoCompleteTextView) the problem is the way AutoCompleteTextView render the dropdown list, as you can see the item layout have the necessary to wrap text in each item on the dropDown.

Not wrapping text, this text is almost 2 lines

image

This dropDown is from the Spinner, it's intent just has an example in order to rest my case that AutoCompleteTextView is not wraping. image

Both ArrayAdaters have the same item layout

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tool="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:ellipsize="marquee"
    android:padding="16dp"
    android:singleLine="false"
    android:textAppearance="?android:attr/textAppearanceLargePopupMenu"
    tool:text="Este es un texto de prueba largo en multiples líneas para probar el texti \nCon un salto de línea como prueba adicional" />

Please, take a look an my attached sample app.

drchen commented 1 year ago

Oh ok. I see, so you want your drop down items to be multi-line. Let me check if there's an easy way for you to do that.

drchen commented 1 year ago

Hi so MaterialAutoCompleteTextView will use ?attr/simpleItemLayout to render its autocomplete item. By default it specifies android:maxLines="1".

To override that settings you need to (it's a little bit complicated, I apologize for that):

  1. Define your own layout, with android:singleLine="false".
  2. Create a custom auto-complete text view style:
    <style name="CustomAutoCompleteStyle" parent="Widget.Material3.AutoCompleteTextView.OutlinedBox">
    <item name="simpleItemLayout">@layout/m3_auto_complete_simple_item</item>
    </style>
  3. Create a custom theme overlay to use the custom style:
    <style name="ThemeOverlay.CustomAutoCompleteTextView">
    <item name="autoCompleteTextViewStyle">@style/CustomAutoCompleteStyle</item>
    </style>
  4. Create a custom text field style to use the custom theme overlay:
    <style name="CustomExposedDropdownMenu" parent="Widget.Material3.TextInputLayout.OutlinedBox.ExposedDropdownMenu">
    <item name="materialThemeOverlay">@style/ThemeOverlay.CustomAutoCompleteTextView</item>
    </style>
  5. Use the custom text field style in your TextInputLayout

Hope this helps! : )

drchen commented 1 year ago

Or you can just set app:simpleItemLayout="...your custom layout" on the AutoCompleteTextView in your text field layout file, btw. : )