为什么使用2路数据绑定时我的Android自定义ArrayAdapter不起作用?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么使用2路数据绑定时我的Android自定义ArrayAdapter不起作用?相关的知识,希望对你有一定的参考价值。
我们正在研究的项目使用MVVM体系结构,房间和2路数据绑定。在我的layout.xml文件中,我们使用AutoCompleteTextView
作为国家/地区选择器。国家是我们项目中的模型:
以下是代码,但是很显然,我无法发布整个项目,因此,如果您需要更多数据,请告诉我。
Country.java
@Entity
public class Country
@PrimaryKey
@ColumnInfo(name = "ID")
private Long id;
@ColumnInfo(name = "Name")
private String countryName;
@ColumnInfo(name = "Code")
private String countryCode;
public Long getId()
return id;
public void setId(Long id)
this.id = id;
public String getCountryName()
return countryName;
public void setCountryName(String countryName)
this.countryName = countryName;
public String getCountryCode()
return countryCode;
public void setCountryCode(String countryCode)
this.countryCode = countryCode;
layout.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<import type="android.view.View" />
<variable name="myViewModel" type="ViewModel" />
</data>
<android.support.v4.widget.NestedScrollView>
<AutoCompleteTextView
android:id="@+id/countryAutoCompleteTextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:completionThreshold="1"
android:dropDownWidth="match_parent"
android:imeOptions="actionNext"
android:inputType="text"
android:maxLines="1"
android:text="@=myViewModel.countryObservable"
android:textIsSelectable="false"
android:textColor="@color/edit_text_black_color_selector" />
<android.support.v4.widget.NestedScrollView>
</layout>
View.java
public class View
onCreate()
ViewModel myViewModel = new ViewModel();
ActivityViewBinding binding = DataBindingUtil();
binding.setViewModel(myViewModel);
AutoCompleteCountryAdapter countryAdapter = new AutoCompleteAdapter();
binding.countryAutoCompleteTextView.setAdapter(countryAdapter);
ViewModel.java
public class ViewModel extends AndroidViewModel
private final ObservableField<String> countryObservable = new ObservableField<>();
AutoCompleteCountryAdapter.java我从here
复制了代码public class AutoCompleteCountryAdapter extends ArrayAdapter<CountryItem>
private List<CountryItem> countryListFull;
public AutoCompleteCountryAdapter(@NonNull Context context, @NonNull List<CountryItem> countryList)
super(context, 0, countryList);
countryListFull = new ArrayList<>(countryList);
@NonNull
@Override
public Filter getFilter()
return countryFilter;
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent)
if (convertView == null)
convertView = LayoutInflater.from(getContext()).inflate(android.R.layout.simple_dropdown_item_1line, parent, false);
TextView textViewName = convertView.findViewById(R.id.text_view_name);
CountryItem countryItem = getItem(position);
if (countryItem != null)
textViewName.setText(country.getCountryName());
return convertView;
private Filter countryFilter = new Filter()
@Override
protected FilterResults performFiltering(CharSequence constraint)
FilterResults results = new FilterResults();
List<CountryItem> suggestions = new ArrayList<>();
if (constraint == null || constraint.length() == 0)
suggestions.addAll(countryListFull);
else
String filterPattern = constraint.toString().toLowerCase().trim();
for (CountryItem item : countryListFull)
if (item.getCountryName().toLowerCase().contains(filterPattern))
suggestions.add(item);
results.values = suggestions;
results.count = suggestions.size();
return results;
@Override
protected void publishResults(CharSequence constraint, FilterResults results)
clear();
addAll((List) results.values);
notifyDataSetChanged();
@Override
public CharSequence convertResultToString(Object resultValue)
return ((CountryItem) resultValue).getCountryName();
;
如您所见,我的可观察字段是String
类型。这个工作...有点。每当我从AutoCompleteTextView的下拉列表中选择一个国家时,它都会填充AutoCompleteTextView
android:text
字段;但是,我需要Country对象中的数据库ID才能在我们的另一个模型中使用它作为外键。
所以,我以为我会将可观察对象转换为Country
类型,但这根本不起作用。一位同事说,我需要@BindingAdapter
和@InverseBindingAdapter
来完成这项工作,因此我创建了它们。
@BindingAdapter(value = "android:text", "android:onItemSelected", requireAll = false)
public static void setText(AutoCompleteTextView autoCompleteTextView, Country newSelectedValue, final InverseBindingListener newTextAttrChanged)
autoCompleteTextView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
@Override
public void onItemSelected(AdapterView<?> adapterView, View subView, int position, long id)
newTextAttrChanged.onChange();
@Override
public void onNothingSelected(AdapterView<?> adapterView)
);
if (newSelectedValue != null)
int pos = autoCompleteTextView.getListSelection();
autoCompleteTextView.setText(autoCompleteTextView.getAdapter().getItemViewType(pos));
@InverseBindingAdapter(attribute = "android:text", event = "android:onItemSelected")
public static Country getText(AutoCompleteTextView textView)
int pos = textView.getListSelection();
Country country = (Country) textView.getAdapter().getItem(pos);
return countryISO;
我的问题是,我的@BindingAdapter
会在活动加载后立即被调用,但是再也不会...尤其是当我更改值时,这是我需要做的。
所以,我在做什么错,我该怎么做才能解决此问题?
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle? ): View?
val application = requireNotNull(this.activity).application
val viewModelFactory = HomePageViewModelFactory(application)
val homePageViewModel = activity?.run
ViewModelProviders.of(
this, viewModelFactory
).get(HomePageViewModel::class.java)
val binding: FragmentReviewPageBinding = DataBindingUtil.inflate(
inflater,
R.layout.fragment_review_page,
container,
false
)
binding.homePageViewModel = homePageViewModel
这是通过绑定链接xml变量的方式
binding.homePageViewModel = homePageViewModel
工厂类
class HomePageViewModelFactory(
private val application: Application) : ViewModelProvider.Factory
@Suppress("unchecked_cast")
override fun <T : ViewModel?> create(modelClass: Class<T>): T
if (modelClass.isAssignableFrom(HomePageViewModel::class.java))
return HomePageViewModel(application) as T
throw IllegalArgumentException("Unknown ViewModel class")
像这样,您可以在多个片段之间共享相同的viewmodel实例。
以上是关于为什么使用2路数据绑定时我的Android自定义ArrayAdapter不起作用?的主要内容,如果未能解决你的问题,请参考以下文章