Android SparseBooleanArray ArrayIndexOutOfBounds

时间:2018-01-02 18:19:58

标签: java android android-sparsearray

我的应用程序有一个SparseBooleanArray,用于在ListAdapter中存储选定的条目。 数组在构造函数中初始化为空。

private SparseBooleanArray mSelectedItemsIds;

public TaskArrayAdapter(@NonNull Context context, @NonNull List<Task> objects) {
    super(context, R.layout.item_task, objects);
    mSelectedItemsIds = new SparseBooleanArray();
    Log.d("Booleansize", String.valueOf(mSelectedItemsIds.size()));
}

现在在getView方法中我检查当前位置是否在数组中:

if (mSelectedItemsIds.valueAt(position)) {
        convertView.setBackgroundColor(Color.BLUE);
        convertView.getBackground().setAlpha(100);
    } else {

在我的测试过程中,mSelectedItemsIds没有改变。我正在列表中插入条目。在正好12个条目之后,它在mSelectedItemsIds.valueAt(position)上与ArrayIndexOutOfBound在11处崩溃。 在另一台设备上,它在14次插入后崩溃。 每次检查前,数组的大小始终为0。

这怎么可能?

以下是适配器类的所有相关部分(我剪切了On Click侦听器,从未触发过)

public class TaskArrayAdapter extends ArrayAdapter<Task> {
// Array with all selectedIds
private SparseBooleanArray mSelectedItemsIds;

public TaskArrayAdapter(@NonNull Context context, @NonNull List<Task> objects) {
    super(context, R.layout.item_task, objects);
    mSelectedItemsIds = new SparseBooleanArray();
    Log.d("Booleansize", String.valueOf(mSelectedItemsIds.size()));
}/**
 * Called for the ListView to get the view at position
 * @param position
 * @param convertView
 * @param parent
 * @return
 */
@NonNull
@Override
public View getView(final int position, @Nullable View convertView, @NonNull ViewGroup parent) {
    // Get the data item for this position
    final Task task = getItem(position);
    // Check if an existing view is being reused, otherwise inflate the view
    if (convertView == null) {
        convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_task, parent, false);
    }
    // Lookup view for data population
    TextView tvDescription = (TextView) convertView.findViewById(R.id.tvDescription);
    TextView tvDueDate = (TextView) convertView.findViewById(R.id.tvDueDate);
    CheckBox cbDone = (CheckBox) convertView.findViewById(R.id.cbDone);
    // Populate the data into the template view using the data object
    tvDescription.setText(task.description);
    if (task.dueDate != null) {
        tvDueDate.setText(task.dueDate.toString());
    } else {
        tvDueDate.setText(R.string.no_due_date);
    }
    cbDone.setChecked(task.done);
    cbDone.setTag(position);
    convertView.setTag(position);

    // Set listeners
    cbDone.setOnClickListener(checkBoxListener);

    convertView.setOnClickListener(viewClickListener);

    convertView.setOnLongClickListener(viewLongClickListener);
    Log.d("Booleansize", String.valueOf(mSelectedItemsIds.size()));
    // check if the current item is selected for background color
    if (mSelectedItemsIds.valueAt(position)) {
        convertView.setBackgroundColor(Color.BLUE);
        convertView.getBackground().setAlpha(100);
    } else {
        convertView.setBackgroundColor(Color.TRANSPARENT);
        convertView.getBackground().setAlpha(255);
    }

    // Return the completed view to render on screen
    return convertView;
}/**
 * Change the isSelected value
 * @param position
 */
public void toggleSelection(int position) {
    selectView(position, !mSelectedItemsIds.get(position));
}

/**
 * Completely forget the current selection
 */
public void removeSelection() {
    mSelectedItemsIds = new SparseBooleanArray();
    notifyDataSetChanged();
}

/**
 * Set the select view to the given value
 * @param position
 * @param value
 */
public void selectView(int position, boolean value) {
    if (value) {
        mSelectedItemsIds.put(position, value);
    } else {
        mSelectedItemsIds.delete(position);
    }
    notifyDataSetChanged();
}

/**
 * get number of selected entries
 * @return
 */
public int getSelectedCount() {
    return mSelectedItemsIds.size();
}

public SparseBooleanArray getSelectedIds() {
    return mSelectedItemsIds;
}

1 个答案:

答案 0 :(得分:0)

您可能打算使用SparseBooleanArray.get方法:

  

boolean get (int key)

     

获取从指定键映射的布尔值,如果没有进行此类映射,则返回false。

像这样使用:

if (mSelectedItemsIds.get(position)) {
    convertView.setBackgroundColor(Color.BLUE);
    convertView.getBackground().setAlpha(100);
} else {
    ....
}
另一方面,

valueAt(int position)占据数组中的位置,即0size() - 1。您可以使用它来迭代数组中的所有值。