Android 限制微调器弹出高度

Android limit the spinner popup height

我找到了一些关于这个问题的线索,但没有解决方案适用于我的情况。我只想设置微调器弹出窗口的高度,例如到 200dp,或限制下拉弹出窗口中显示的项目并使其可滚动。

mainactivity.xml:

 <FrameLayout
        android:id="@+id/frame1"
        android:layout_below="@+id/contact_form_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:background="@drawable/custom_spn_background">

        <Spinner
            android:id="@+id/spinner1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:dropDownSelector="@color/colorAccent"
            android:popupBackground="@drawable/custombg"
            style="@style/Myspinner"
            android:layout_margin="5dp"
            android:gravity="center_vertical"
            android:spinnerMode="dropdown"/>
    </FrameLayout>

my_spinnerlist.xml

<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    android:paddingStart="8dp"
    android:paddingEnd="8dp"
    android:singleLine="true"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:textSize="18sp"
    android:gravity="start"
    android:textColor="#000000"
    android:paddingTop="2dip"
    android:paddingBottom="2dip"
    android:ellipsize="marquee"/>

spinner_item.xml:

<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textSize="18sp"
    android:gravity="center_vertical"
    android:textColor="#000000"
    android:paddingStart="8dp"
    android:paddingEnd="8dp"
    android:paddingTop="2dp"
    android:paddingBottom="4dp"
    android:textStyle="normal"
    />

MainActivity.java:

final Spinner sp1 = findViewById(R.id.spinner1);
    String[] arrayItems = myList.categories;

    ArrayAdapter<String> adp1 = new ArrayAdapter<>(this, R.layout.spinner_item, arrayItems);
    adp1.setDropDownViewResource(R.layout.my_spinnerlist);
    sp1.setAdapter(adp1);
    sp1.setSelected(false);
    sp1.setSelection(0, true);

    sp1.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> arg0, View arg1, int position, long id) {

        }

        @Override
        public void onNothingSelected(AdapterView<?> arg0) {
        }
    });

我试图在所有微调器相关的 XML 布局文件中设置 200dp 高度,但它只影响项目高度,而不影响整个弹出窗口。我还尝试了 here 的建议解决方案和反射,例如:

Spinner spinner = (Spinner) findViewById(R.id.spinner);
    try {
        Field popup = Spinner.class.getDeclaredField("mPopup");
        popup.setAccessible(true);

        android.widget.ListPopupWindow popupWindow = (android.widget.ListPopupWindow) popup.get(spinner);

        popupWindow.setHeight(200);
    }
    catch (NoClassDefFoundError | ClassCastException | NoSuchFieldException | IllegalAccessException e) {
    }

但这并没有改变下拉列表的高度而且我有一个警告:对mPopup的反射访问,这不是public SDK,因此可能会在未来的 Android 版本中发生变化。

我也试过在样式文件的Myspinner样式中设置<item name="android:dropDownHeight">200dp</item>,但没有影响高度。

我真的没有办法解决这个问题。我的下拉列表中有一个包含 50 个项目的列表,它覆盖了我设备的整个显示区域。

好的,唯一适合我的解决方案是使用第三方 MaterialSpinner 库。也许它对其他人也有用,因为没有本地方法可以更改下拉高度。

只是为了实施:implementation 'com.jaredrummler:material-spinner:1.3.1'

spinner.xml:

 <com.jaredrummler.materialspinner.MaterialSpinner
            android:id="@+id/spinner1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:ms_dropdown_max_height="200dp"
            android:dropDownSelector="@color/colorAccent"
            android:popupBackground="@drawable/custombg"
            style="@style/Myspinner"
            android:layout_margin="5dp"
            android:gravity="center_vertical"
            android:spinnerMode="dropdown"/>

Java代码:

 final MaterialSpinner sp1 = (MaterialSpinner) findViewById(R.id.spinner1);

        String[] arrayItems = myList.categories;

        ArrayAdapter<String> adp1 = new ArrayAdapter<>(this, R.layout.spinner_item, arrayItems);
        adp1.setDropDownViewResource(R.layout.my_spinnerlist);
        sp1.setAdapter(adp1);

        sp1.setSelected(false);
 
        sp1.setOnItemSelectedListener(new MaterialSpinner.OnItemSelectedListener() {
            @Override
            public void onItemSelected(MaterialSpinner view, int position, long id, Object item) {

            }
        } );

很有魅力,请参阅 XML 文件中的 app:ms_dropdown_max_height="200dp"