过去两周,当我退出并打开应用程序时,我一直在努力制作一个解决方案,以便在我的每个listview项目旁边存储我的复选框值。基本上,我有一个自定义的BaseAdapter类,它使用用户手机上已安装的应用程序填充列表视图,并在每个已安装的应用程序旁边打开一个复选框。当我向下滚动复选框时,状态保持不变;但是,当我单击后退或退出并返回时它不会停留。
我几乎以各种可能的方式使用了SharedPreferences。我的最后一种方法是使用for循环为每个创建一个SharedPreference,并在for循环中恢复布尔值,并在if和else语句中存储布尔值true和false(分别用于checked和unchecked)。
以下是使用SharedPreferences的我的BaseAdapter类的代码:
package com.ibc.android.demo.appslist.app;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.TextView;
import com.spicycurryman.getdisciplined10.app.R;
import java.util.List;
//
public class ApkAdapter extends BaseAdapter {
//Pastebin link: http://pastebin.com/LGRicg4U , http://pastebin.com/c4WfmhMK , http://pastebin.com/gFuuM4dY, http://pastebin.com/4Q7EP9G4
// http://pastebin.com/Te2g072w, http://pastebin.com/NLT5iUiA ,
SharedPreferences sharedPrefs;
List<PackageInfo> packageList;
Activity context;
PackageManager packageManager;
boolean[] itemChecked;
String PACKAGE_NAME;
public ApkAdapter(Activity context, List<PackageInfo> packageList,
PackageManager packageManager) {
super();
this.context = context;
this.packageList = packageList;
this.packageManager = packageManager;
itemChecked = new boolean[packageList.size()];
}
private class ViewHolder {
TextView apkName;
CheckBox ck1;
TextView packageName;
}
public int getCount() {
return packageList.size();
}
public Object getItem(int position) {
return packageList.get(position);
}
public long getItemId(int position) {
return 0;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
LayoutInflater inflater = context.getLayoutInflater();
if (convertView == null) {
convertView = inflater.inflate(R.layout.installed_apps, null);
holder = new ViewHolder();
holder.apkName = (TextView) convertView
.findViewById(R.id.appname);
holder.ck1= (CheckBox)convertView
.findViewById(R.id.checkBox1);
convertView.setTag(holder);
//holder.ck1.setTag(packageList.get(position));
} else {
holder = (ViewHolder) convertView.getTag();
}
// ViewHolder holder = (ViewHolder) convertView.getTag();
PackageInfo packageInfo = (PackageInfo) getItem(position);
Drawable appIcon = packageManager
.getApplicationIcon(packageInfo.applicationInfo);
// Make sure to define it again!
PACKAGE_NAME = packageInfo.packageName;
final String appName = packageManager.getApplicationLabel(
packageInfo.applicationInfo).toString();
appIcon.setBounds(0, 0, 80, 80);
holder.apkName.setCompoundDrawables(appIcon, null, null, null);
holder.apkName.setCompoundDrawablePadding(15);
holder.apkName.setText(appName);
holder.ck1.setChecked(false);
if (itemChecked[position])
holder.ck1.setChecked(true);
else
holder.ck1.setChecked(false);
Log.d("just loaded??", PACKAGE_NAME);
Log.d("just loaded 2?", appName+position);
// CHANGE UP EVERYTHING! MAKE THIS SHIT WORK, TIGGA!
for(int i= 0; i<packageList.size(); i++){
sharedPrefs = context.getSharedPreferences(String.valueOf(i), Context.MODE_PRIVATE);
holder.ck1.setChecked(sharedPrefs.getBoolean(String.valueOf(i),false));
}
holder.ck1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
SharedPreferences.Editor editor = context.getSharedPreferences(String.valueOf(position), Context.MODE_PRIVATE).edit();
if (holder.ck1.isChecked()) {
itemChecked[position] = true;
holder.ck1.setChecked(true);
Log.i("This is", " checked: " + position);
editor.putBoolean(String.valueOf(position), true);
Log.d("put true", appName+position);
editor.apply();
} else {
itemChecked[position] = false;
holder.ck1.setChecked(false);
Log.i("This is", " not checked: " + position);
editor.putBoolean(String.valueOf(position), false);
Log.d("put false", appName+position);
editor.apply();
}
}
});
return convertView;
}
}
我还创建了一个DatabaseHandler类和Object类,用于在使用SharedPreferences将其存储失败后使用SQLite数据库存储我的复选框值。
以下是pastebin链接,所以我不会堵塞帖子:
DatabaseHandler类:http://pastebin.com/NzKhBiZ3
对象类:http://pastebin.com/Jp3BLXba
我知道有许多关于使用自定义适配器/列表视图以及使用SQLite和SharedPreferences保存复选框和按钮状态等的帖子,博客和链接,但我向您保证,我已经完成了数周的研究,但是我我们找不到适用于我特定情况的东西。
一些例子:
Saving State of the checkbox in a custom list view with Checkboxes
http://blog.csdn.net/qu213/article/details/9289349
在我的特定情况下,什么是最优选的选项?如何在我的情况下生成一个解决方案,以成功保存每个已安装的app listview项旁边的复选框状态,这些状态将在我退出应用程序后保存重新输入?有些代码真的很有帮助。
感谢您的时间。
如果您需要我包含任何xml文件,请告诉我。
答案 0 :(得分:1)
我建议您使用的是定义一个处理存储和检索状态数据的对象。假设您有一个AppHandler类作为主要对象和AppState类 用于保存状态相关数据,例如复选框。
public class AppHandler {
private List<AppState> lastInstalledApp;
@transient
private Gson gson;
public void retrieve(SharedPreferences pref){
// parse the gson from shared preferences
// create the lastInstalledApp list
String jsonState = pref.getString("APP_STATE", null);
if(jsonState != null)
lastInstalledApp = gson.fromJson(jsonState, lastInstalledApp.getClass());
}
public void store(SharedPreferences pref){
// store the data to shared preferences
}
public List<AppState> getAppList(){
return lastInstalledApp;
}
public static class AppState{
protected boolean lastCheckbox;
protected String name;
public boolean isLastCheckbox() {
return lastCheckbox;
}
public void setLastCheckbox(boolean lastCheckbox) {
this.lastCheckbox = lastCheckbox;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
使用共享首选项将整个AppHandler对象存储为JSON字符串(为此使用GSON),因此您只能访问一次存储文件,而不是每次只想访问一个复选框状态。您可以在活动中检索并存储此数据(适配器使用您的appHandler.getAppList()
数据启动它):
@Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
setContentView(R.layout.list_layout);
appHandler = new AppHandler();
appHandler.retrieve(getSharedPreferences());
}
@Override
protected void onDestroy() {
appHandler.store(getSharedPreferences());
super.onDestroy();
}
您的自定义适配器中的通过其包名访问特定应用程序,以获取复选框的状态。您甚至可以扩展ArrayList
并添加一些方法,例如getAppByName()
,这样您就可以清楚地区分对象。
更改复选框状态时,更新AppState
对象的等效布尔值。这是一般性的。
答案 1 :(得分:1)
我想我可能已经解决了你的问题。请尝试使用此代码,看看它是否有效。
for(int i= 0; i<packageList.size(); i++){
PACKAGE_NAME = packageInfo.packageName;
sharedPrefs = context.getSharedPreferences(PACKAGE_NAME, Context.MODE_PRIVATE);
Log.d("just got sharedpref??", PACKAGE_NAME);
holder.ck1.setChecked(sharedPrefs.getBoolean(PACKAGE_NAME,false));
Log.d("just got boolean??", PACKAGE_NAME);
}
holder.ck1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
SharedPreferences.Editor editor = context.getSharedPreferences(packageInfo.packageName, Context.MODE_PRIVATE).edit();
if (holder.ck1.isChecked()) {
itemChecked[position] = true;
holder.ck1.setChecked(true);
Log.i("This is", " checked: " + position);
editor.putBoolean(packageInfo.packageName, true);
Log.d("put true", packageInfo.packageName);
editor.apply();
} else {
itemChecked[position] = false;
holder.ck1.setChecked(false);
Log.i("This is", " not checked: " + position);
editor.putBoolean(packageInfo.packageName, false);
Log.d("put false", packageInfo.packageName);
editor.apply();
}
}
});
我传入了密钥的包名。 :)
答案 2 :(得分:0)
使用sqlite数据库...每次用户检查/取消选中该值时,都会在数据库中创建一个条目。
检查了App1
检查App2
检查App3
App4取消选中