设备旋转后不显示 AutoCompleteTextView 下拉列表
AutoCompleteTextView dropdown not showing after device rotation
我有以下自动完成文本视图:
<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>
在我的 Activity 的 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);
初始 运行 一切正常,下拉菜单显示正确:
现在我将设备旋转到横向。执行与上面完全相同的代码但是这次,下拉框只显示当前选择:
由于某种原因,适配器中的所有其他条目都消失了。在设置适配器之前,我曾尝试过 setAdapter(null)
等技巧,但没有成功。 谁能告诉我为什么在轮换后,即使执行了完全相同的代码,下拉菜单仍缺少条目?
就像@Gabriele Mariotti 提到的那样,这是一个错误。正如发布的 link 中提到的,我做了这个工作很好的解决方法:
public class ExposedDropDown extends MaterialAutoCompleteTextView {
public ExposedDropDown(@NonNull final Context context, @Nullable final AttributeSet attributeSet) {
super(context, attributeSet);
}
@Override
public boolean getFreezesText() {
return false;
}
}
目前 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)
将过滤器应用于适配器值。
这个习俗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)
我有以下自动完成文本视图:
<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>
在我的 Activity 的 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);
初始 运行 一切正常,下拉菜单显示正确:
现在我将设备旋转到横向。执行与上面完全相同的代码但是这次,下拉框只显示当前选择:
由于某种原因,适配器中的所有其他条目都消失了。在设置适配器之前,我曾尝试过 setAdapter(null)
等技巧,但没有成功。 谁能告诉我为什么在轮换后,即使执行了完全相同的代码,下拉菜单仍缺少条目?
就像@Gabriele Mariotti 提到的那样,这是一个错误。正如发布的 link 中提到的,我做了这个工作很好的解决方法:
public class ExposedDropDown extends MaterialAutoCompleteTextView {
public ExposedDropDown(@NonNull final Context context, @Nullable final AttributeSet attributeSet) {
super(context, attributeSet);
}
@Override
public boolean getFreezesText() {
return false;
}
}
目前 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)
将过滤器应用于适配器值。
这个习俗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)