java - RecyclerView Adapter 无故改变对象的值
问题描述
我正在收听通知,因此我想创建一个 RecyclerView 用户可以用来排除某些应用程序。它显示了应用程序的徽标和名称,以及用于启用/禁用每个应用程序的切换按钮。
我创建了一个App
包含每个应用程序的一些数据的类。
public class App {
private String name;
private String packageName;
private Drawable icon;
private boolean enabled;
public App(String name, String packageName, Drawable icon, boolean enabled) {
this.name = name;
this.packageName = packageName;
this.icon = icon;
this.enabled = enabled;
}
public String getName() {
return name;
}
public String getPackageName() {
return packageName;
}
public Drawable getIcon() {
return icon;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public boolean isEnabled() {
return enabled;
}
}
这是适配器:
public class AppsAdapter extends RecyclerView.Adapter<AppsAdapter.AppViewHolder> {
private List<App> apps;
public AppsAdapter(PackageManager packageManager) {
apps = packageManager.getInstalledApplications(PackageManager.GET_META_DATA)
.stream()
.filter(applicationInfo -> packageManager.getLaunchIntentForPackage(applicationInfo.packageName) != null)
.map(applicationInfo -> new App(applicationInfo.loadLabel(packageManager).toString(), applicationInfo.packageName, applicationInfo.loadIcon(packageManager), true))
.collect(Collectors.toList());
}
@Override
public AppViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new AppViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.app_item, parent, false));
}
@Override
public void onBindViewHolder(AppsAdapter.AppViewHolder holder, int position) {
App app = apps.get(position);
holder.nameTextView.setText(app.getName());
holder.appToggleButton.setChecked(app.isEnabled());
holder.iconImageView.setImageDrawable(app.getIcon());
holder.appToggleButton.setOnCheckedChangeListener((buttonView, isChecked) -> {
app.setEnabled(isChecked);
});
}
@Override
public int getItemCount() {
return apps.size();
}
protected static class AppViewHolder extends RecyclerView.ViewHolder {
private TextView nameTextView;
private ToggleButton appToggleButton;
private ImageView iconImageView;
public AppViewHolder(View itemView) {
super(itemView);
nameTextView = itemView.findViewById(R.id.name_text_view);
appToggleButton = itemView.findViewById(R.id.app_toggle_button);
iconImageView = itemView.findViewById(R.id.icon_image_view);
}
}
}
当我通过单击按钮“禁用”应用程序时,它似乎工作正常。但是当我在 RecyclerView 中向下滚动然后备份时,我禁用的应用程序的条目再次显示在屏幕上,该应用程序不再被禁用。
不幸的是,我不知道如何调试它以及可能导致此问题的原因。
编辑:如果我setOnCheckedChangeListener
之前setChecked
在切换按钮上打电话,它似乎正在工作。我不懂为什么。
解决方案
在适配器构造函数中启用 setHasStableIds(true)。
AppsAdapter(){
setHasStableIds(true);
}
推荐阅读
- reactjs - TypeError: (0 , _reactNative.unstable_createElement) 不是函数
- docker - 我可以在 GitHub Actions 工作流程中引用 Dockerfile 而不是图像吗?
- java - 如何对具有使用数据库连接的方法的类进行单元测试?
- windows - shell:startup打开的echo目录
- tensorflow - 关于量化 Mobilenet-SSD V2 所需的 300x300 输入的一些问题
- reactjs - 我无法通过单击按钮安装 PWA
- reactjs - 喊/发送 Blob 对象在 webRTC 中不起作用
- java - 使用 PowerMockito 进行 JUnit 参数化和非参数化测试
- mql4 - 为什么我在下面的代码中出现参数转换不允许错误?
- swift - 如何快速复制 Snapchat Map?