AutoCompleteTextView - 如何删除顶部和底部的边距?

DIR*_*AVE 4 android autocompletetextview material-design android-textinputlayout material-components-android

我正在使用创建一个下拉菜单AutoCompleteTextView。如何删除列表顶部和底部的默认边距?

在此输入图像描述

重新创建:

<com.google.android.material.textfield.TextInputLayout
        style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:boxBackgroundColor="@color/white"
        android:focusable="false"
        app:boxStrokeWidth="1.5dp"
        app:layout_constraintTop_toBottomOf="@+id/spinner_network">

        <AutoCompleteTextView
            android:id="@+id/autoCompleteTextView"
            android:layout_width="250dp"
            android:layout_height="match_parent"
            android:inputType="none"
            android:dropDownHeight="200dp"
            android:text="Select age" />

    </com.google.android.material.textfield.TextInputLayout>
Run Code Online (Sandbox Code Playgroud)
        List<String> dropdownItems = new ArrayList<>();
        for(int i = 1; i <= 100; i++){
            dropdownItems.add(String.valueOf(i));
        }

        ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<>(
                this, R.layout.dropdown_item, dropdownItems
        );

        AutoCompleteTextView autoCompleteTextView = findViewById(R.id.autoCompleteTextView);
        autoCompleteTextView.setAdapter(spinnerAdapter);
Run Code Online (Sandbox Code Playgroud)

R.layout.dropdown_item

<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/textView"
    android:layout_width="match_parent"
    android:textColor="@color/black"
    android:padding="14dp"
    android:layout_height="wrap_content"
    android:text="TextView" />
Run Code Online (Sandbox Code Playgroud)

Zai*_*ain 6


更新

所有功劳和努力都归于@MikeM。从评论中。非常感谢他的努力。

原因 填充来自其TextInputLayout本身,它DropdownMenuEndIconDelegate设置了一些MaterialShapeDrawables作为下拉菜单的背景。垂直内边距的值为 8dp,取自该资源 dimen

解决方案一:

将此资源尺寸覆盖为 0dp:

<dimen name="mtrl_exposed_dropdown_menu_popup_vertical_padding" tools:override="true">0dp</dimen>
Run Code Online (Sandbox Code Playgroud)

解决方案2:

前面的解决方案将应用于所有AutoCompleteTextView的,但如果您想对某些特定的解决方案执行此操作:更改默认的 dropDown 背景可绘制对象,例如:

autoCompleteTextView.setDropDownBackgroundDrawable(new ColorDrawable(Color.WHITE));
Run Code Online (Sandbox Code Playgroud)

带反射(不推荐,因为它是反模式)

的下拉弹出窗口可以通过fieldAutoCompleteTextView在内部访问。要通过反射来获取它:mPopup

// Java:

public static ListPopupWindow getPopup(AutoCompleteTextView autoCompleteTextView) {
    try {
        Field field = AutoCompleteTextView.class.getDeclaredField("mPopup");
        field.setAccessible(true);
        return (ListPopupWindow) field.get(autoCompleteTextView);
    } catch (NoSuchFieldException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
    return null;
}


//  Kotlin:

fun AutoCompleteTextView.getPopup(): ListPopupWindow? {
    try {
        val field = AutoCompleteTextView::class.java.getDeclaredField("mPopup")
        field.isAccessible = true
        return field.get(this) as ListPopupWindow
    } catch (e: NoSuchFieldException) {
        e.printStackTrace()
    } catch (e: IllegalAccessException) {
        e.printStackTrace()
    }
    return null
}
Run Code Online (Sandbox Code Playgroud)

然后通过将其设置为内部的父视图来删除填充ListView

// Java:

autoCompleteTextView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        ListPopupWindow popup = getPopup(autoCompleteTextView);
        if (popup != null) {
            ListView listView = popup.getListView();
            if (listView!= null)
                ((View) listView.getParent()).setPadding(0, 0, 0, 0);
        }
    }
});

// Kotlin

autoCompleteTextView.setOnClickListener {
    val popUp = autoCompleteTextView2.getPopup()?.listView?.parent
    if (popUp != null)
        (popUp as View).setPadding(0, 0, 0, 0)
}
Run Code Online (Sandbox Code Playgroud)

这样做是OnClickListener因为当用户点击列表时,可空性检查将不匹配,因为列表是形成的。