Мой адаптер не обновляет правильно мой вариант просмотра списка - PullRequest
0 голосов
/ 12 февраля 2019

У меня следующая проблема.Когда я удаляю элемент из моего ListView в моем адаптере, состояние CheckBox меняется с элемента в списке, Почему?и как можно решить эту проблему?

public class CustomAdapter extends ArrayAdapter<RowModel> implements View.OnClickListener {

private ArrayList<RowModel> DataSet;
Context context;

public CustomAdapter(ArrayList<RowModel> data, Context context) {
    super(context, R.layout.list_item_main, data);
    this.DataSet = data;
    this.context = context;
}

@Override
public void onClick(View v) {
    int position = (Integer) v.getTag();
    Object object = getItem(position);
    RowModel dataRowModel = (RowModel) object;

    switch (v.getId()) {
        case R.id.list_checkbox:
            CheckBox checkBox = v.findViewById(R.id.list_checkbox);
            int bool = (checkBox.isChecked()) ? 1 : 0;
            new ListFacade(context).UpdateState(dataRowModel.getRowid(), bool);
            break;
        case R.id.list_delete_button:
            new ListFacade(context).DeleteRow(dataRowModel.getRowid());
            DataSet.remove(object);
            break;
    }
    notifyDataSetChanged();
    updateWidgetToChange();
}

, если я удаляю элемент 4

enter image description here

флажок элемент 5 случайно выбирается удалением элемент 4

enter image description here

РЕДАКТИРОВАТЬ 1: добавлен getView

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // Get the data item for this position
    RowModel dataRowModel = getItem(position);
    // Check if an existing view is being reused, otherwise inflate the view
    ViewHolder viewHolder; // view lookup cache stored in tag

    if (convertView == null) {
        viewHolder = new ViewHolder();
        LayoutInflater inflater = LayoutInflater.from(getContext());
        convertView = inflater.inflate(R.layout.list_item_main, parent, false);
        viewHolder.checkbox = convertView.findViewById(R.id.list_checkbox);
        viewHolder.checkbox.setChecked(dataRowModel.isChecked());
        viewHolder.title = convertView.findViewById(R.id.list_title);
        viewHolder.classes = convertView.findViewById(R.id.list_classes);
        viewHolder.rowid = convertView.findViewById(R.id.list_rowid);
        viewHolder.delete_button = convertView.findViewById(R.id.list_delete_button);

        convertView.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }

    viewHolder.rowid.setText(dataRowModel.getStringRowid());
    viewHolder.title.setText(dataRowModel.getAction());
    viewHolder.classes.setText(dataRowModel.getType());
    viewHolder.checkbox.setOnClickListener(this);
    viewHolder.checkbox.setTag(position);
    viewHolder.delete_button.setOnClickListener(this);
    viewHolder.delete_button.setTag(position);
    // Return the completed view to render on screen
    return convertView;
}

Редактировать 2: добавлен ListFacade

public void UpdateState(int rowid, int bool){
    SQLiteDatabase conn = new SqliteHandler(context).getWritableDatabase();
    String strSQL = "UPDATE TODO_LIST SET CHECKED='"+ bool +"' WHERE ROWID = "+ rowid;
    conn.execSQL(strSQL);
    conn.close();
}

public void DeleteRow(int rowid){
    SQLiteDatabase conn = new SqliteHandler(context).getWritableDatabase();
    conn.delete("TODO_LIST", "ROWID=?", new String[]{String.valueOf(rowid)});
    conn.close();
}

Ответы [ 2 ]

0 голосов
/ 12 февраля 2019

Чтобы добавить ответ @ vilpe89, проблема не в том, что вы не звоните setChecked() в getView(), а в том, что вы звоните не в ту точку:

viewHolder.checkbox.setChecked(dataRowModel.isChecked());

Вы вызываете эту строку, только если convertView == null, за исключением того, что при обновлении списка convertView не будет нулевым.Поэтому, чтобы решить вашу проблему, вам нужно переместить эту строку после оператора if else, например:

viewHolder.checkbox.setOnClickListener(this);
viewHolder.checkbox.setChecked(dataRowModel.isChecked());
viewHolder.checkbox.setTag(position);
0 голосов
/ 12 февраля 2019

Просто догадываюсь, но я думаю, что вам нужно обновить состояние флажка в getView-методе.Когда вы удаляете объект из dataSet, вам нужно убедиться, что isChecked обновлен в getView-методе.Теперь, когда вы удаляете одни данные из набора данных, и элементы списка обновляются, состояние CheckBox не изменяется.

У вас есть что-то подобное в вашем коде?:

@Override
public View getView(int position, View convertView, @NonNull ViewGroup parent) {
    // Other code...
    RowModel model = getItem(position);
    CheckBox cb = (CheckBox) convertView.findViewById(R.id.list_checkbox);
    cb.setChecked(model.isChecked());
    // ...
}

Потому чтоЯ вижу, что вы не обновляете набор данных в прослушивателе кликов вашего CheckBox.

Так что вам нужно добавить это туда или что-то вроде этого:

case R.id.list_checkbox:
        CheckBox checkBox = v.findViewById(R.id.list_checkbox);
        dataRowModel.isChecked(checkBox.isChecked());
        // ... rest of the code

Редактировать:

Проблема в том, что вы обновляете CheckBox только тогда, когда View (convertView) равен нулю!Вам нужно убрать этот код из if (convertView == null), потому что он вызывается только при создании представления и при вызове notifyDataSetChanged, представления не создаются снова и ваш блок if не достигается.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...