我想在listview中保存复选框的选中状态,以便当我转到另一个活动然后返回此活动时,所选的检查工具应保持选中状态。我使用自定义适配器来显示两种类型的布局。我使用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;
}
}
答案 0 :(得分:0)
如果我们转到grep code,我们会看到:
public SparseBooleanArray More ...getCheckedItemPositions() {
if (mChoiceMode != CHOICE_MODE_NONE) {
return mCheckStates;
}
return null;
}
我们记得,当你致电listView.getCheckedItemPositions()
时,你收到了空。所以我认为可能是,因为你没有使用listView.setChoiceMode
。
答案 1 :(得分:0)
<强> 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);
}
}
}
<强> MainActivity 强>
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;
}
}