通过 MVVM 方法使用 DataBinding 和 ViewModel 创建 RecycleView Adapter
Creating RecycleView Adaptor using DataBinding and ViewModel through MVVM approach
我想在数据绑定的帮助下在 RecyclerListview
中显示数据,而 ViewModel
使用 MVVM
方法。在我的 XML 中创建了视图模型 class 的数据变量,但是我在我的适配器 class 中的语句
中遇到错误
holder.chatlistitemBinding.setChatlistVM(mChatList.get(position));
因为 mChatList.get(position)
是 ChatList
模型的数组而不是 ViewModel
的数组。我该如何纠正它?请不要建议更改指向模型 Class(ChatList)
的数据变量。我想通过视图模型实现 MVVM
方法。提前致谢。
我的XML文件:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
>
<data >
<variable name="handlers" type="com.support.android.designlibdemo.View.Handlers.ChatListHandlers"/>
<variable name="chatlistVM" type="com.support.android.designlibdemo.ViewModel.ChatListViewModel" />
</data>
<RelativeLayout
.......
<TextView
android:id="@+id/placeholder2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{chatlistVM.chatList.first_name}"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
...
</layout>
适配器Class:
public class AdapterChatList extends RecyclerView.Adapter<AdapterChatList.ChatListViewHolder> {
private LayoutInflater mInflater;
private static final String TAG = "ChatListAdapter";
public List<ChatListViewModel> mChatList = new ArrayList<>();
public AdapterChatList(Context context) {
mInflater = LayoutInflater.from(context);
}
class ChatListViewHolder extends RecyclerView.ViewHolder{
private ChatlistitemBinding chatlistitemBinding;
public ChatListViewHolder(ChatlistitemBinding itemBinding) {
super(itemBinding.getRoot());
chatlistitemBinding = itemBinding;
}
}
@NonNull
@Override
public ChatListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (mInflater == null) { mInflater = LayoutInflater.from(parent.getContext()); }
ChatlistitemBinding chatListUserItemBinding = DataBindingUtil.inflate(mInflater, R.layout.chatlistitem, parent, false);
return new ChatListViewHolder(chatListUserItemBinding);
}
@Override
public void onBindViewHolder(@NonNull ChatListViewHolder holder, int position) {
holder.chatlistitemBinding.setChatlistVM(mChatList.get(position));
holder.chatlistitemBinding.setHandlers(new ChatListHandlers());
holder.chatlistitemBinding.executePendingBindings();
}
@Override
public int getItemCount() {
if (mChatList != null)
return mChatList.size();
else return 0;
}
void add(ChatList chatList) {
mChatList.add(chatList);
notifyItemInserted(getItemCount());
}
public void updatelist(List<ChatList> userlist){//Need to rethink on this method
mChatList = userlist;
notifyDataSetChanged();
}
}
ViewModel:
public class ChatListViewModelextends AndroidViewModel {
private ChatList chatList ;
public ChatListViewModel(Application application){
super(application);
chatList = new ChatList();
}
}
在这种情况下,我不会扩展框架提供的 ViewModel
class,因为您只想将 ViewModel 绑定到特定视图。
所以解决方法很简单:
在 VM
中将 chatList
作为构造函数参数,然后将其设置为
holder.chatlistitemBinding.setChatlistVM(new ChatListViewModel(mChatList.get(position)));
工厂class:
@Suppress("UNCHECKED_CAST")
class Factory @Inject constructor(
private val chatList: ChatList
) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(ChatListViewModel::class.java)) {
return ChatListViewModel(chatList) as T
}
throw IllegalArgumentException("Unknown ViewModel class: ${modelClass.canonicalName}")
}
}
然后你用同样的方法得到你的虚拟机,你只需要传递Factory
实例
例如从你的 Fragment
或 FragmentActivity
你会打电话:
viewModel = ViewModelProviders.of(this, viewModelFactory).get(ChatListViewModel:class.java);
我想在数据绑定的帮助下在 RecyclerListview
中显示数据,而 ViewModel
使用 MVVM
方法。在我的 XML 中创建了视图模型 class 的数据变量,但是我在我的适配器 class 中的语句
holder.chatlistitemBinding.setChatlistVM(mChatList.get(position));
因为 mChatList.get(position)
是 ChatList
模型的数组而不是 ViewModel
的数组。我该如何纠正它?请不要建议更改指向模型 Class(ChatList)
的数据变量。我想通过视图模型实现 MVVM
方法。提前致谢。
我的XML文件:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
>
<data >
<variable name="handlers" type="com.support.android.designlibdemo.View.Handlers.ChatListHandlers"/>
<variable name="chatlistVM" type="com.support.android.designlibdemo.ViewModel.ChatListViewModel" />
</data>
<RelativeLayout
.......
<TextView
android:id="@+id/placeholder2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{chatlistVM.chatList.first_name}"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
...
</layout>
适配器Class:
public class AdapterChatList extends RecyclerView.Adapter<AdapterChatList.ChatListViewHolder> {
private LayoutInflater mInflater;
private static final String TAG = "ChatListAdapter";
public List<ChatListViewModel> mChatList = new ArrayList<>();
public AdapterChatList(Context context) {
mInflater = LayoutInflater.from(context);
}
class ChatListViewHolder extends RecyclerView.ViewHolder{
private ChatlistitemBinding chatlistitemBinding;
public ChatListViewHolder(ChatlistitemBinding itemBinding) {
super(itemBinding.getRoot());
chatlistitemBinding = itemBinding;
}
}
@NonNull
@Override
public ChatListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (mInflater == null) { mInflater = LayoutInflater.from(parent.getContext()); }
ChatlistitemBinding chatListUserItemBinding = DataBindingUtil.inflate(mInflater, R.layout.chatlistitem, parent, false);
return new ChatListViewHolder(chatListUserItemBinding);
}
@Override
public void onBindViewHolder(@NonNull ChatListViewHolder holder, int position) {
holder.chatlistitemBinding.setChatlistVM(mChatList.get(position));
holder.chatlistitemBinding.setHandlers(new ChatListHandlers());
holder.chatlistitemBinding.executePendingBindings();
}
@Override
public int getItemCount() {
if (mChatList != null)
return mChatList.size();
else return 0;
}
void add(ChatList chatList) {
mChatList.add(chatList);
notifyItemInserted(getItemCount());
}
public void updatelist(List<ChatList> userlist){//Need to rethink on this method
mChatList = userlist;
notifyDataSetChanged();
}
}
ViewModel:
public class ChatListViewModelextends AndroidViewModel {
private ChatList chatList ;
public ChatListViewModel(Application application){
super(application);
chatList = new ChatList();
}
}
在这种情况下,我不会扩展框架提供的 ViewModel
class,因为您只想将 ViewModel 绑定到特定视图。
所以解决方法很简单:
在 VM
中将 chatList
作为构造函数参数,然后将其设置为
holder.chatlistitemBinding.setChatlistVM(new ChatListViewModel(mChatList.get(position)));
工厂class:
@Suppress("UNCHECKED_CAST")
class Factory @Inject constructor(
private val chatList: ChatList
) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(ChatListViewModel::class.java)) {
return ChatListViewModel(chatList) as T
}
throw IllegalArgumentException("Unknown ViewModel class: ${modelClass.canonicalName}")
}
}
然后你用同样的方法得到你的虚拟机,你只需要传递Factory
实例
例如从你的 Fragment
或 FragmentActivity
你会打电话:
viewModel = ViewModelProviders.of(this, viewModelFactory).get(ChatListViewModel:class.java);