设备旋转后未显示AutoCompleteTextView下拉列表

问题描述

我有以下AutoCompleteTextView:

<com.google.android.material.textfield.TextInputLayout
    android:id="@+id/offering_type_dropdown_layout"
    style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginEnd="@dimen/date_card_spacing"
    android:layout_marginStart="4dp"
    app:layout_constraintStart_toEndOf="@+id/offering_details_header_image"
    app:layout_constraintEnd_toStartOf="@+id/offering_details_date_layout"
    app:layout_constraintTop_toTopOf="parent"
    android:hint="@string/offering_type_hint">
    <AutoCompleteTextView
        android:id="@+id/offering_details_type_dropdown"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:inputType="textNoSuggestions"
        android:clickable="false"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:cursorVisible="false"/>
</com.google.android.material.textfield.TextInputLayout>

在活动的onCreate中,我像这样填充AutoCompleteTextView:

    String[] TYPES = new String[] {getString(R.string.burnt_offering),getString(R.string.meal_offering),getString(R.string.peace_offering),getString(R.string.sin_offering)};
    ArrayAdapter<String> adapter = new ArrayAdapter<>(OfferingInputActivity.this,R.layout.offering_types_dropdown,TYPES);
    mOfferingTypeCombo.setAdapter(adapter);

然后,我使用Room数据库填充视图,并预先选择其中一个值。在Room回调中,我这样做:

  mOfferingTypeCombo.setText(getString(R.string.meal_offering)),false);

在初始运行中一切正常,并且下拉列表正确显示

enter image description here

现在我将设备旋转到横向。执行与上面完全相同的代码,但是这次,下拉框仅显示当前选择

enter image description here

由于某种原因,适配器中的所有其他条目均已消失。在设置适配器之前,我曾尝试过setAdapter(null)之类的黑客攻击,但没有成功。 有人可以告诉我为什么轮换后,即使执行了完全相同的代码,下拉列表仍缺少条目吗?

解决方法

当前this topic上存在一个未解决的错误。

您可以使用 setFreezesText 方法作为解决方法:

AutoCompleteTextView autoCompleteTextView =
    view.findViewById(R.id.offering_details_type_dropdown);
autoCompleteTextView.setFreezesText(false);

EditText设置了freezesText=true。由于旋转后使用了该值,因此TextView#onRestoreInstanceState(Parcelable)调用autoCompleteTextView.setText(value,true)会将过滤器应用于适配器值。

,

就像@Gabriele Mariotti提到的,​​这是一个错误。如发布的链接中所述,我做了一个很好的解决方法:

public class ExposedDropDown extends MaterialAutoCompleteTextView {
       public ExposedDropDown(@NonNull final Context context,@Nullable final AttributeSet attributeSet) {
          super(context,attributeSet);
       }

       @Override
       public boolean getFreezesText() {
         return false;
       }
}
,

这个自定义MaterialAutoCompleteTextView 解决所有问题:

class ExposedDropdownMenu : MaterialAutoCompleteTextView {

constructor(context: Context) : super(context)
constructor(context: Context,attrs: AttributeSet?) : super(context,attrs)
constructor(context: Context,attrs: AttributeSet?,defStyleAttr: Int) : super(
    context,attrs,defStyleAttr
)

override fun getFreezesText(): Boolean {
    return false
}

init {
    inputType = InputType.TYPE_NULL
}

override fun onSaveInstanceState(): Parcelable? {
    val parcelable = super.onSaveInstanceState()
    if (TextUtils.isEmpty(text)) {
        return parcelable
    }
    val customSavedState = CustomSavedState(parcelable)
    customSavedState.text = text.toString()
    return customSavedState
}

override fun onRestoreInstanceState(state: Parcelable?) {
    if (state !is CustomSavedState) {
        super.onRestoreInstanceState(state)
        return
    }
    setText(state.text,false)
    super.onRestoreInstanceState(state.superState)
}

private class CustomSavedState(superState: Parcelable?) : BaseSavedState(superState) {
    var text: String? = null

    override fun writeToParcel(out: Parcel,flags: Int) {
        super.writeToParcel(out,flags)
        out.writeString(text)
    }
}
}

Source