[英]Error saving checked state of checkbox in custom listview
我想將復選框的選中狀態保存在我的列表視圖中,這樣當我轉到另一個活動然后又回到該活動時,所選的checkox應保持選中狀態。 我使用了自定義適配器來顯示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;
}
}
如果轉到grep代碼 ,我們將看到:
public SparseBooleanArray More ...getCheckedItemPositions() {
if (mChoiceMode != CHOICE_MODE_NONE) {
return mCheckStates;
}
return null;
}
我們還記得,在調用listView.getCheckedItemPositions()
時,您將獲得null。 所以我想可能是因為您沒有使用listView.setChoiceMode
。
MultipleLayoutAdapter
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, final 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.setOnCheckedChangeListener(null);
viewHolder.checkBox.setChecked(item.isBox());
viewHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
item.setBox(b);
}
});
return convertView;
}
private View inflateImageView(View convertView, ViewGroup parent, final 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.setOnCheckedChangeListener(null);
viewHolder.checkBox.setChecked(item.isBox());
viewHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
item.setBox(b);
}
});
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 MainActivity extends AppCompatActivity {
SharedPreferences sharedPreferences;
ListView listView;
List<Item> items = new ArrayList<>();
MultipleLayoutAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listview);
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));
}
findViewById(R.id.btn_go).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(MainActivity.this, Main2Activity.class));
}
});
}
@Override
protected void onResume() {
super.onResume();
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);
items.get(checkedPosition).setBox(true);
}
if (adapter == null) {
adapter = new MultipleLayoutAdapter(this, items);
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listView.setAdapter(adapter);
} else {
adapter.notifyDataSetChanged();
}
}
@Override
protected void onPause() {
Set<String> stringSet = new HashSet<>();
for (int i = 0; i < items.size(); i++) {
if (items.get(i).isBox()) {
stringSet.add(String.valueOf(i));
}
}
sharedPreferences.edit()
.putStringSet("checked_items", stringSet)
.apply();
super.onPause();
}
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<>();
for (int i = 0; i < checkedItems.size(); i++) {
result.add(String.valueOf(checkedItems.keyAt(i)));
}
return result;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.