Java 暴露下拉菜单只有一项
Java Exposed DropDown Menu only one item
我尝试创建一个 Android 带有公开下拉菜单的应用程序,如下所示:
https://material.io/components/menus/android#exposed-dropdown-menus
左图出现在第一次打开菜单时。选择一项,变化到合适的情况。再次重新选择相同的项目,又变回左边的情况。
这是我的适配器的实现:
public class FilterMenuCategoryAdapter extends ArrayAdapter<String> {
private static final String TAG = "FilterMenuCategoryAdapter";
List<String> categoryList;
LvElCategoryBinding binding;
Context context;
public FilterMenuCategoryAdapter(Context context) {
super(context, 0, getCompleteCategoryList());
this.context = context;
this.categoryList = getCompleteCategoryList();
}
public FilterMenuCategoryAdapter(Context context, List<String> categoryList) {
super(context, 0, categoryList);
this.context = context;
this.categoryList = new ArrayList<>(categoryList);
}
@Override
public int getCount() {
return categoryList.size();
}
@Override
public String getItem(int position) {
return categoryList.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.lv_el_category, parent, false);
}
String category = categoryList.get(position);
binding.tvTitle.setText(category);
binding.icon.setImageResource(new IconNameMapper().get(category));
return binding.getRoot();
}
}
这是用过的 XML:
<com.google.android.material.textfield.TextInputLayout
style="@style/dropDownMenuOnWhite"
android:layout_width="match_parent"
android:layout_height="50dp">
<AutoCompleteTextView
android:id="@+id/filterMenu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:inputType="none"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:text="@string/show_all"
android:textAlignment="textEnd"
android:textColor="@color/primaryTextColor"
android:textSize="@dimen/font_size" />
</com.google.android.material.textfield.TextInputLayout>
在我的片段中 Class 我这样称呼它:
FilterMenuCategoryAdapter adapter = new FilterMenuCategoryAdapter(this.getContext());
binding.filterMenu.setAdapter(adapter);
目前,菜单中的每个选择都会中断我的 onClick
事件。所以我很高兴能得到任何帮助!
更新:
我修好了它!在 getView() 中使用 DataBinding 对我来说每次都会杀死它。
以下解决方案有效:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(
R.layout.lv_el_category, parent, false
);
}
TextView title = convertView.findViewById(R.id.tv_title);
ShapeableImageView image = convertView.findViewById(R.id.icon);
String category = categoryList.get(position);
title.setText(category);
image.setImageResource(new IconNameMapper().get(category));
return convertView;
}
如果您知道如何在 getView() 中使用 DataBinding,请告诉我!
问题不在 dataBinding
本身;但是它的实现方式。
当您第一次点击菜单时,它会正确显示,因为 converView
是 null
并且满足建立绑定对象的条件。
点击项目时菜单项消失的原因;当再次调用 getView()
时,它有一个新的 convertView
对象,该对象具有不同于旧调用 getView()
的新状态;但你忽略了它,并使用旧的 binding
对象及其原始状态来查找视图;这使得dataBinding无法膨胀新状态的视图(可能是指旧回收的视图)。
这就是 convertView
作为方法参数传递的原因;因此每次回收视图时都需要使用全新的 convertView
。
解决这个问题;您需要通过保存 dataBinding 的视图来做同样的事情; binding.getRoot()
返回。并且您必须使用 convertView
来保存此 dataBinding 视图状态。这通常可以通过 ViewHolder
并使用 setTag()
:
保存视图及其状态来完成
ViewHolder 与 RecyclerView
view holder 的想法相似:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ItemViewHolder holder;
if (convertView == null) {
LvElCategoryBinding binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.lv_el_category, parent, false);
holder = new ItemViewHolder(binding);
holder.view = binding.getRoot();
holder.view.setTag(holder);
} else {
holder = (ItemViewHolder) convertView.getTag();
}
String category = categoryList.get(position);
holder.binding.tvTitle.setText(category);
holder.binding.icon.setImageResource(new IconNameMapper().get(category));
return holder.view;
}
private static class ItemViewHolder {
private View view;
private LvElCategoryBinding binding;
ItemViewHolder(LvElCategoryBinding binding) {
this.view = binding.getRoot();
this.binding = binding;
}
}
我尝试创建一个 Android 带有公开下拉菜单的应用程序,如下所示:
https://material.io/components/menus/android#exposed-dropdown-menus
左图出现在第一次打开菜单时。选择一项,变化到合适的情况。再次重新选择相同的项目,又变回左边的情况。
这是我的适配器的实现:
public class FilterMenuCategoryAdapter extends ArrayAdapter<String> {
private static final String TAG = "FilterMenuCategoryAdapter";
List<String> categoryList;
LvElCategoryBinding binding;
Context context;
public FilterMenuCategoryAdapter(Context context) {
super(context, 0, getCompleteCategoryList());
this.context = context;
this.categoryList = getCompleteCategoryList();
}
public FilterMenuCategoryAdapter(Context context, List<String> categoryList) {
super(context, 0, categoryList);
this.context = context;
this.categoryList = new ArrayList<>(categoryList);
}
@Override
public int getCount() {
return categoryList.size();
}
@Override
public String getItem(int position) {
return categoryList.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.lv_el_category, parent, false);
}
String category = categoryList.get(position);
binding.tvTitle.setText(category);
binding.icon.setImageResource(new IconNameMapper().get(category));
return binding.getRoot();
}
}
这是用过的 XML:
<com.google.android.material.textfield.TextInputLayout
style="@style/dropDownMenuOnWhite"
android:layout_width="match_parent"
android:layout_height="50dp">
<AutoCompleteTextView
android:id="@+id/filterMenu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:inputType="none"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:text="@string/show_all"
android:textAlignment="textEnd"
android:textColor="@color/primaryTextColor"
android:textSize="@dimen/font_size" />
</com.google.android.material.textfield.TextInputLayout>
在我的片段中 Class 我这样称呼它:
FilterMenuCategoryAdapter adapter = new FilterMenuCategoryAdapter(this.getContext());
binding.filterMenu.setAdapter(adapter);
目前,菜单中的每个选择都会中断我的 onClick
事件。所以我很高兴能得到任何帮助!
更新:
我修好了它!在 getView() 中使用 DataBinding 对我来说每次都会杀死它。
以下解决方案有效:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(
R.layout.lv_el_category, parent, false
);
}
TextView title = convertView.findViewById(R.id.tv_title);
ShapeableImageView image = convertView.findViewById(R.id.icon);
String category = categoryList.get(position);
title.setText(category);
image.setImageResource(new IconNameMapper().get(category));
return convertView;
}
如果您知道如何在 getView() 中使用 DataBinding,请告诉我!
问题不在 dataBinding
本身;但是它的实现方式。
当您第一次点击菜单时,它会正确显示,因为 converView
是 null
并且满足建立绑定对象的条件。
点击项目时菜单项消失的原因;当再次调用 getView()
时,它有一个新的 convertView
对象,该对象具有不同于旧调用 getView()
的新状态;但你忽略了它,并使用旧的 binding
对象及其原始状态来查找视图;这使得dataBinding无法膨胀新状态的视图(可能是指旧回收的视图)。
这就是 convertView
作为方法参数传递的原因;因此每次回收视图时都需要使用全新的 convertView
。
解决这个问题;您需要通过保存 dataBinding 的视图来做同样的事情; binding.getRoot()
返回。并且您必须使用 convertView
来保存此 dataBinding 视图状态。这通常可以通过 ViewHolder
并使用 setTag()
:
ViewHolder 与 RecyclerView
view holder 的想法相似:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ItemViewHolder holder;
if (convertView == null) {
LvElCategoryBinding binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.lv_el_category, parent, false);
holder = new ItemViewHolder(binding);
holder.view = binding.getRoot();
holder.view.setTag(holder);
} else {
holder = (ItemViewHolder) convertView.getTag();
}
String category = categoryList.get(position);
holder.binding.tvTitle.setText(category);
holder.binding.icon.setImageResource(new IconNameMapper().get(category));
return holder.view;
}
private static class ItemViewHolder {
private View view;
private LvElCategoryBinding binding;
ItemViewHolder(LvElCategoryBinding binding) {
this.view = binding.getRoot();
this.binding = binding;
}
}