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

问题描述 投票:0回答:6
android material-components-android android-textinputlayout
6个回答
5
投票

这个习俗

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)
    }
}
}

来源

注意: 它可能无法在 23 或更低版本等较旧的 API 中正常工作。 一种方法是使用自定义

ArrayAdapter
来防止 Filter 文本。

class NoFilterArrayAdapter : ArrayAdapter<Any?> {

constructor(context: Context, resource: Int) : super(context, resource)
constructor(context: Context, resource: Int, objects: Array<out Any?>) : super(context, resource, objects)

override fun getFilter(): Filter {
    return object : Filter() {
        override fun performFiltering(constraint: CharSequence?): FilterResults? {
            return null
        }

        override fun publishResults(constraint: CharSequence?, results: FilterResults?) {}
       }
   }
}

用途:

val adapter = NoFilterArrayAdapter(requireContext(), android.R.layout.simple_list_item_1, items)
          

4
投票

目前此主题有一个未解决的错误。

您可以使用

setFreezesText
方法作为解决方法:

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

EditText
设置
freezesText=true
。由于旋转后的这个值,
TextView#onRestoreInstanceState(Parcelable)
调用
autoCompleteTextView.setText(value,true)
,它将过滤器应用于适配器值。


0
投票

就像 @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;
       }
}

0
投票
  1. 我通过从 AutoCompleteTextView 中删除 id 解决了这个问题。这个id负责保存旋转后的文本。
  2. 在 onSaveInstanceState 方法中保存来自 AutoCompleteTextView 的字符串。

代码:

  <com.google.android.material.textfield.TextInputLayout
                android:id="@+id/inputAddress"
                style="@style/Widget.MaterialComponents.TextInputLayout.FilledBox.ExposedDropdownMenu"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="@string/Address">

                <AutoCompleteTextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:inputType="none"
                    />

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

list_item.xml

<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="?attr/textAppearanceSubtitle1"
/>

片段.类

class CashierAddFragment : Fragment() {

var mBinding: FragmentCashierAddBinding? = null

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {

    val binding = FragmentCashierAddBinding.inflate(inflater, container, false)

    if(savedInstanceState == null) {
        initAddressSpinner(binding, "")
    } else {
        initAddressSpinner(binding, savedInstanceState.getString(KEY_ADDRESS))
    }

    mBinding = binding

    return binding.root
}

override fun onSaveInstanceState(outState: Bundle) {
    val address = mBinding!!.inputAddress.getTrimText()
    outState.putString(KEY_ADDRESS, address)

    super.onSaveInstanceState(outState)
}

private fun initAddressSpinner(binding: FragmentCashierAddBinding, initValue: String?) {
    val items = listOf("Option 1", "Option 2", "Option 3", "Option 4")
    val adapter = ArrayAdapter(requireContext(), R.layout.list_item, items)

    val autoTxtAddress = binding.inputAddress.editText as? AutoCompleteTextView
    autoTxtAddress?.setText(initValue)
    autoTxtAddress?.setAdapter(adapter)
}

}


0
投票

@Mohsents 提出的解决方案对我有用。这是我使用的他的代码的java版本:

public class NoFilterArrayAdapter extends ArrayAdapter<Object> {

public NoFilterArrayAdapter(Context context, int resource) {
    super(context, resource);
}

public NoFilterArrayAdapter(Context context, int resource, Object[] objects) {
    super(context, resource, objects);
}

@Override
public Filter getFilter() {
    return new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            return null;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
        }
    };
}
}

0
投票

要在方向更改时解决此问题,请在 XML 中添加此内容

android:saveEnabled =“假”

© www.soinside.com 2019 - 2024. All rights reserved.