Java 在RecyclerView中根据先前选择的设置复选框

Java 在RecyclerView中根据先前选择的设置复选框,java,android,android-recyclerview,android-sqlite,android-package-managers,Java,Android,Android Recyclerview,Android Sqlite,Android Package Managers,我已经为此挣扎了一段时间,但找不到解决办法。目前,我正在使用PackageManager填充我的RecyclerView以及设备上安装的所有应用程序。这非常有效,下面是我得到的结果: 我遇到的问题是,我不知道如何存储/检索选中的复选框,让我详细说明一下 当我选中一个复选框时,我会在onBindViewHolder中执行以下操作: holder.mAppSelect.setOnCheckedChangeListener(null); holder.mAppSelect.setChecke

我已经为此挣扎了一段时间,但找不到解决办法。目前,我正在使用
PackageManager
填充我的
RecyclerView
以及设备上安装的所有应用程序。这非常有效,下面是我得到的结果:

我遇到的问题是,我不知道如何存储/检索选中的复选框,让我详细说明一下

当我选中一个
复选框时,我会在
onBindViewHolder
中执行以下操作:

holder.mAppSelect.setOnCheckedChangeListener(null);
    holder.mAppSelect.setChecked(mDataSet.get(position).isSelected());
    holder.mAppSelect.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            mDataSet.get(position).setSelected(isChecked);

            if (holder.mAppSelect.isChecked()){
                //Ok great, I can use this to get the position, package name and app name that was selected/checked
            }else{
                //and it was un-sellected
            }
因此,我可以使用上面的方法来存储所选复选框的包名,还可以在
SQLite
中存储
checkbox
状态的
boolean
,如下所示:

holder.mAppSelect.setOnCheckedChangeListener(null);
    holder.mAppSelect.setChecked(mDataSet.get(position).isSelected());
    holder.mAppSelect.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            mDataSet.get(position).setSelected(isChecked);

            if (holder.mAppSelect.isChecked()){
                dbManager.insert(holder.mTextViewPackage.getText().toString(), true);
            }else{
                dbManager.insert(holder.mTextViewPackage.getText().toString(), false);
            }
这就是我遇到困难的地方。。假设我关闭
活动
并再次打开它,我希望获得从
SQLite
中选择的包/复选框并再次设置它

因此,我正在寻找一种方法来“循环”每个持有者,从持有者那里获取包名,这样我就可以签入
SQLite
,如果之前选中了复选框,并相应地设置它


我认为还值得一提的是,自上次启动应用程序以来,应用程序可能已被卸载或安装。因此,这意味着
getAdapterPosition
将不会保持不变


编辑1:

这就是我如何填充名为
mDataSet
数组的方法:

public class AppManager {
private Context mContext;
private AppInfo appInfo;
private ArrayList<AppInfo> myApps;

public AppManager(Context c) {
    mContext = c;
    myApps = new ArrayList<AppInfo>();
}

public ArrayList<AppInfo> getApps() {
    loadApps();
    return myApps;
}

private void loadApps() {
    List<ApplicationInfo> packages = mContext.getPackageManager().getInstalledApplications(0);
    for (ApplicationInfo packageInfo : packages) {
        AppInfo newApp = new AppInfo();
        newApp.setAppName(getApplicationLabelByPackageName(packageInfo.packageName));
        newApp.setAppPackage(packageInfo.packageName);
        newApp.setAppIcon(getAppIconByPackageName(packageInfo.packageName));
        myApps.add(newApp);
    }

    Collections.sort(myApps, new Comparator<AppInfo>() {
        @Override
        public int compare(AppInfo s1, AppInfo s2) {
            return s1.getAppName().compareToIgnoreCase(s2.getAppName());

        }
    });

}


// Custom method to get application icon by package name
private Drawable getAppIconByPackageName(String packageName) {
    Drawable icon;
    try {
        icon = mContext.getPackageManager().getApplicationIcon(packageName);
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
        // Get a default icon
        icon = ContextCompat.getDrawable(mContext, R.drawable.ic_launcher_background);
    }
    return icon;
}

// Custom method to get application label by package name
private String getApplicationLabelByPackageName(String packageName) {
    PackageManager packageManager = mContext.getPackageManager();
    ApplicationInfo applicationInfo;
    String label = "Unknown";
    try {
        applicationInfo = packageManager.getApplicationInfo(packageName, 0);
        if (applicationInfo != null) {
            label = (String) packageManager.getApplicationLabel(applicationInfo);
        }

    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    }
    return label;
}
}
公共类AppManager{
私有上下文;
私有AppInfo-AppInfo;
私有ArrayList myApps;
公共应用程序管理器(上下文c){
mContext=c;
myApps=newarraylist();
}
公共阵列列表getApps(){
loadApps();
返回myApps;
}
私有void loadApps(){
List packages=mContext.getPackageManager().getInstalledApplication(0);
对于(ApplicationInfo packageInfo:packages){
AppInfo newApp=新AppInfo();
newApp.setAppName(getApplicationLabelByPackageName(packageInfo.packageName));
newApp.setAppPackage(packageInfo.packageName);
newApp.setAppIcon(getAppIconByPackageName(packageInfo.packageName));
myApps.add(newApp);
}
Collections.sort(myApps,newcomparator(){
@凌驾
公共整数比较(AppInfo s1、AppInfo s2){
返回s1.getAppName().compareToIgnoreCase(s2.getAppName());
}
});
}
//按包名获取应用程序图标的自定义方法
私有可绘图getAppIconByPackageName(字符串packageName){
可绘制图标;
试一试{
icon=mContext.getPackageManager().getApplicationName(packageName);
}捕获(PackageManager.NameNotFounde异常){
e、 printStackTrace();
//获取默认图标
icon=ContextCompat.getDrawable(mContext,R.drawable.ic_launcher_后台);
}
返回图标;
}
//按包名获取应用程序标签的自定义方法
私有字符串getApplicationLabelByPackageName(字符串packageName){
PackageManager PackageManager=mContext.getPackageManager();
应用信息应用信息;
字符串标签=“未知”;
试一试{
applicationInfo=packageManager.getApplicationInfo(packageName,0);
if(applicationInfo!=null){
label=(字符串)packageManager.getApplicationLabel(applicationInfo);
}
}捕获(PackageManager.NameNotFounde异常){
e、 printStackTrace();
}
退货标签;
}
}

您可以使用共享首选项

当您从共享首选项启动“活动检索”状态时,如下所示

SharedPreferences sharedPreference PreferenceManager.getDefaultSharedPreferences(getAppContext());
for(i=0;i<mDataSet.size();i++)
{    
mDataSet.get(i).setSelected(sharedPreference.getBoolean(mDataSet.get(i).getAppPackage(),false));
}

正如我所看到的,如果isSelected()返回true,您将按照正确的步骤显示选中的复选框,并在
SQLite
中保存复选框的状态(选中/未选中)

要在关闭并再次打开
活动
时显示SQLite中复选框的保存状态,只需执行以下操作:

  • 首先,您需要获得已安装软件包的最新列表

  • SQLite
    中选择数据/复选框值,其中包名与 最新的包裹清单

  • 现在,当您从SQLite保存了复选框值时,创建数据集 使用最新安装的应用程序列表和选中的复选框值 从
    SQLite
    获取

  • 将其传递给您的
    RecycleWebDeptor


  • 它应该可以正常工作。

    您可以尝试OnClickListener而不是oncheckedchangestener

    试试这个方法,

    1.使用包含选定项目的列表<代码>//selectedlist
    如果您想永久存储它,请使用SharedPref

    2.选择项目的数据,该数据将是唯一的
    //appname作为字符串

    3.根据所选列表项设置选中状态

    if(selectedlist.get(appname)!=null
                && (selectedlist.get(appname).equals("selected"))) {
            holder.checkBox.setChecked(true);
        }
        else {
            holder.checkBox.setChecked(false);
        }
    
    四,。将侦听器添加到复选框中

        View.OnClickListener listener=new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (selectedlist.get(appname)==null) {
                    selectedlist.put(appname, "selected");
                else if (selectedlist.get(appname).equals("selected"))
                    selectedlist.put(appname, "not selected");
                else 
                    selectedlist.put(appname, "selected");
                notifyDataSetChanged();
            }
        };
    
        holder.checkBox.setOnClickListener(listener);
    

    如何生成mDataSetvalues@VinayakB是
    数组
    填充在
    回收视图
    中,我正在使用
    PackageManager
    填充
    数组
    ,你在哪里用你的sqlite值检查它是否在mDataSet值中被选中。好的,我已经测试过了,它可以工作。我唯一的问题是,当我从我的
    活动
    调用
    SharedReferences
    时,它返回null。但是,当我从
    onBindViewHolder
    onCreateViewHolder
    中的适配器调用它时,它会被反复调用。。有没有一种方法可以在我的适配器中调用它一次?它不应该返回null。如果您是从活动内部调用它,请确保您传递了正确的上下文。。。尝试执行此PreferenceManager.GetDefaultSharedReferences(此选项);它不再为空,但我仍然存在获取所选复选框的程序包名称的问题,因为我没有从活动中引用viewholder。没关系,我可以在选中复选框时将程序包名称保存在SharedReferences中。谢谢,这会很好用的
        View.OnClickListener listener=new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (selectedlist.get(appname)==null) {
                    selectedlist.put(appname, "selected");
                else if (selectedlist.get(appname).equals("selected"))
                    selectedlist.put(appname, "not selected");
                else 
                    selectedlist.put(appname, "selected");
                notifyDataSetChanged();
            }
        };
    
        holder.checkBox.setOnClickListener(listener);