【发布时间】:2016-12-03 22:52:05
【问题描述】:
我想在我的列表视图中保存复选框的选中状态,以便当我转到另一个活动然后返回此活动时,选定的复选框应该保持选中状态。我使用自定义适配器来显示 2 种类型的布局。我使用 sparsebooleanarray 和 sharedpreference 来保存选中状态。这在使用 List 时有效,但在使用 List 时出现 NullPointerException。有什么办法可以保存这里的状态吗?
public class ListViewActivity extends AppCompatActivity {
SharedPreferences sharedPreferences;
ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_view);
listView = (ListView) findViewById(R.id.listview);
List<Item> items = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
items.add(new Item("I am TextView layout #" + i, Item.TYPE_TEXTVIEW, false));
items.add(new Item("I am ImageView layout #" + i, Item.TYPE_IMAGEVIEW, false));
}
MultipleLayoutAdapter adapter = new MultipleLayoutAdapter(this, items);
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listView.setAdapter(adapter);
sharedPreferences = getSharedPreferences("MySharedPrefs", Context.MODE_PRIVATE);
Set<String> checkedItemsSource = sharedPreferences.getStringSet("checked_items", new HashSet<String>());
SparseBooleanArray checkedItems = convertToCheckedItems(checkedItemsSource);
for (int i = 0; i < checkedItems.size(); i++) {
int checkedPosition = checkedItems.keyAt(i);
listView.setItemChecked(checkedPosition, true);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
SparseBooleanArray checkedItems = listView.getCheckedItemPositions();
////got exception here
Set<String> stringSet = convertToStringSet(checkedItems);
sharedPreferences.edit()
.putStringSet("checked_items", stringSet)
.apply();
}
private SparseBooleanArray convertToCheckedItems(Set<String> checkedItems) {
SparseBooleanArray array = new SparseBooleanArray();
for(String itemPositionStr : checkedItems) {
int position = Integer.parseInt(itemPositionStr);
array.put(position, true);
}
return array;
}
private Set<String> convertToStringSet(SparseBooleanArray checkedItems) {
Set<String> result = new HashSet<>();
////got exception here
for (int i = 0; i < checkedItems.size(); i++) {
result.add(String.valueOf(checkedItems.keyAt(i)));
}
return result;
}
}
public class MultipleLayoutAdapter extends BaseAdapter {
private Context context;
private List<Item> items;
public MultipleLayoutAdapter(Context context, List<Item> items) {
this.context = context;
this.items = new ArrayList<>(items);
}
@Override
public int getCount() {
return items.size();
}
@Override
public Item getItem(int position) {
return items.get(position);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public int getViewTypeCount() {
return 2;
}
@Override
public int getItemViewType(int position) {
return getItem(position).getType();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Item item = getItem(position);
int viewType = getItemViewType(position);
switch (viewType) {
case Item.TYPE_TEXTVIEW:
convertView = inflateTextView(convertView, parent, item);
break;
case Item.TYPE_IMAGEVIEW:
convertView = inflateImageView(convertView, parent, item);
break;
}
return convertView;
}
private View inflateTextView(View convertView, ViewGroup parent, Item item) {
TextViewHolder viewHolder;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.textview_list_row, parent, false);
viewHolder = new TextViewHolder(convertView);
convertView.setTag(viewHolder);
}
else {
viewHolder = (TextViewHolder) convertView.getTag();
}
viewHolder.textView.setText(item.getData());
viewHolder.checkBox.setChecked(item.isBox());
return convertView;
}
private View inflateImageView(View convertView, ViewGroup parent, Item item) {
ImageViewHolder viewHolder;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.imageview_list_row, parent, false);
viewHolder = new ImageViewHolder(convertView);
convertView.setTag(viewHolder);
}
else {
viewHolder = (ImageViewHolder) convertView.getTag();
}
viewHolder.textView.setText(item.getData());
viewHolder.checkBox.setChecked(item.isBox());
return convertView;
}
static class TextViewHolder {
private TextView textView;
private CheckBox checkBox;
public TextViewHolder(View convertView) {
this.textView = (TextView) convertView.findViewById(R.id.textview);
this.checkBox = (CheckBox) convertView.findViewById(R.id.checkbox);
}
}
static class ImageViewHolder {
private ImageView imageView;
private TextView textView;
private CheckBox checkBox;
public ImageViewHolder(View convertView) {
this.imageView = (ImageView) convertView.findViewById(R.id.imageview);
this.textView = (TextView) convertView.findViewById(R.id.textview);
this.checkBox = (CheckBox) convertView.findViewById(R.id.checkbox);
}
}
}
public class Item {
public static final int TYPE_TEXTVIEW = 0;
public static final int TYPE_IMAGEVIEW = 1;
private String data;
private int type;
private boolean box;
private Context context;
public Item(Context context) {
this.context = context;
}
public Item(String data, int type, boolean box) {
this.data = data;
this.type = type;
this.box = box;
}
public String getData() {
return data;
}
public int getType() {
return type;
}
public boolean isBox() {
return box;
}
public void setBox(boolean box) {
this.box = box;
}
}
【问题讨论】:
-
我认为您应该将代码缩减为一个最小的示例,并指出错误发生的位置。
-
你提供的链接没有任何东西可以保存检查状态@AndroidDeveloper
-
我已经编辑了我的代码以显示我在哪里得到了错误,这里是 logcat 链接hastebin.com/mamecibupa.avrasm@Eiko
-
您是否提供了列表视图的选择模式?
标签: android listview android-sharedpreferences