Model类变量变更未在RecyclerView中刷新问题求助
解决切换currentUser后RecyclerView不刷新的问题
我来帮你排查并解决这个问题,你遇到的核心问题是DataBinding没有感知到currentUser的变化,再加上BindingAdapter的实现存在一些逻辑瑕疵,咱们一步步来修复:
一、先修复ViewModel的属性通知机制
你的DashBoardViewModel虽然继承了BaseObservable,但currentUser是静态变量且没有绑定DataBinding的属性变更通知,这会导致DataBinding完全察觉不到这个变量的变化。咱们需要调整成实例变量并添加必要的注解和通知逻辑:
public class DashBoardViewModel extends BaseObservable { private Activity context; // 去掉static修饰符,改成实例变量并添加@Bindable注解 @Bindable private Enum currentUser = com.stampmemories.app.AppConstants.USER_ROLES.PROVIDER; // 添加setter方法,在值变更时触发DataBinding的属性通知 public void setCurrentUser(Enum currentUser) { this.currentUser = currentUser; // 通知DataBinding该属性已更新,BR类是DataBinding自动生成的 notifyPropertyChanged(BR.currentUser); } // 添加对应的getter方法 public Enum getCurrentUser() { return currentUser; } // 保留你原有的其他代码... }
注意:确保你的项目已经开启了DataBinding(在app模块的build.gradle中配置
dataBinding.enabled = true),否则BR类不会自动生成。
二、优化BindingAdapter的逻辑
原来的BindingAdapter每次调用都会新建列表和Adapter,不仅浪费资源,还可能导致数据更新不及时。咱们改成复用已有Adapter和列表的逻辑:
@BindingAdapter({"menu_recycler", "current_user"}) public static void bindNavigationMenu(RecyclerView recyclerView, Activity context, Enum user) { NavMenuAdapter adapter = (NavMenuAdapter) recyclerView.getAdapter(); ArrayList<DrawerModel.Drawer.Sub_menu> navMenuList; if (adapter == null) { // 第一次初始化时创建列表和Adapter navMenuList = new ArrayList<>(); adapter = new NavMenuAdapter(context, navMenuList); recyclerView.setLayoutManager(new LinearLayoutManager(context)); recyclerView.setHasFixedSize(true); recyclerView.setAdapter(adapter); } else { // 已有Adapter,清空旧数据复用列表 navMenuList = adapter.getNavMenuList(); navMenuList.clear(); } // 根据当前用户角色加载对应菜单数据 if (user == USER_ROLES.CUSTOMER) { navMenuList.addAll(CommonFunction.getMenuList(context, false)); } else if (user == USER_ROLES.PROVIDER) { navMenuList.addAll(CommonFunction.getMenuList(context, true)); } // 通知Adapter数据已更新 adapter.notifyDataSetChanged(); }
补充:给NavMenuAdapter添加列表获取方法
上面的逻辑需要从Adapter中获取内部的菜单列表,所以要给NavMenuAdapter加一个getter方法:
public class NavMenuAdapter extends RecyclerView.Adapter<NavMenuAdapter.ViewHolder> { private ArrayList<DrawerModel.Drawer.Sub_menu> navMenuList; // ...你的其他已有代码 // 添加获取菜单列表的方法 public ArrayList<DrawerModel.Drawer.Sub_menu> getNavMenuList() { return navMenuList; } // ...你的其他已有代码 }
三、确保布局中正确绑定ViewModel
在你的布局XML中,要正确绑定ViewModel的currentUser属性,示例如下:
<layout> <data> <variable name="viewModel" type="你的包名.DashBoardViewModel" /> </data> <androidx.recyclerview.widget.RecyclerView android:id="@+id/menu_recycler" app:menu_recycler="@{viewModel.context}" app:current_user="@{viewModel.currentUser}" <!-- 其他布局属性 --> /> </layout>
四、切换用户时调用setter方法
最后,当你需要切换用户角色时,不要直接修改currentUser变量,而是调用我们刚才添加的setter方法:
// 示例:切换到CUSTOMER角色 viewModel.setCurrentUser(com.stampmemories.app.AppConstants.USER_ROLES.CUSTOMER);
这样操作后,DataBinding会感知到currentUser的变化,自动重新执行BindingAdapter方法,RecyclerView就会跟着刷新了。
内容的提问来源于stack exchange,提问作者Insane Developer
相关产品推荐
相关产品推荐

