Android: Wie requery, Cursor-refresh ListView-nach löschen der Datenbank Zeile?

Könnte dies eine noob Frage, aber ich bin ganz neu auf all dies SQLite-Datenbank-Cursor-Adapter-ListView-Machen-Es-Richtig-Zeug.

Was ich habe:

In meinem MainActivity ich habe eine ListView. Ich verwende eine SQLite database und füllen Sie die ListView mit einem benutzerdefinierten adapter Verlängerung SimpleCursorAdapter. Durch Klick auf ein Element in meinem ActionBar ich aktiviere Contextual Action Mode. Alles funktioniert so weit.

, Was ich will:

Durch klicken auf ein bestimmtes Symbol in meiner ListView item die nach Datenbank-Zeile gelöscht werden soll, und die ListView aktualisiert werden soll.

Meine Frage:

Wie aktualisiere ich meine Cursor und meine ListView richtig? Wenn ich nicht verwenden cursor.requery() in meinem OnClickListener und verwenden cursor = dbm.getIOIOSensorsCursor() stattdessen bekomme ich eine CursorIndexOutOfBoundsException ein paar Zeilen weiter unten auf der Linie

int state = cursor.getInt(cursor.getColumnIndex(IOIOSensorSchema.STATE));

Meine app abstürzt, aber nach neu laden der Datenbank gelöscht wurden und die nach ListView item ist Weg.

Ich denke der Absturz hat etwas damit zu tun, mit _position get getView Methode, weil _position ist final. Allerdings, wenn ich cursor.requery() funktioniert alles wie es soll.

Aber diese Methode ist veraltet und es ist die Dokumentation sagt "verwenden Sie nicht dieses...". Ich bin ein Freund von Codierung richtig (ich bin noch Anfänger und will lernen, um code, der richtige Weg und nicht die quick-and-dirty) und wollen wissen, wie Sie dieses Recht tun. Ich weiß nicht, ob es wichtig ist aber ich Teste meine app nur auf meinem (wirklich schnell) Nexus 4. Es scheint keine Probleme bei der Aktualisierung der Cursor schnell genug, aber ich Frage mich, ob es auch auf langsameren Geräten. In einem Fall ist es wichtig für Sie, meine Datenbank enthält über 10-20 Zeilen mit etwa 12 Spalten. Ich denke, das ist eine sehr kleine Datenbank.

Hier ist der relevante code der meine benutzerdefinierte adapter:

public class IOIOSensorCursorAdapterCam extends SimpleCursorAdapter
{
static class ViewHolder
{
ImageView stateIV, removeIV;
TextView nameTV, pinNumberTV, feedIDTV, freqTV;
}

private Context ctx;
private Cursor cursor;
private IodDatabaseManager dbm;

public IOIOSensorCursorAdapterCam(Context _context, int _layout,
    Cursor _cursor, String[] _from, int[] _to, int _flags)
{
super(_context, _layout, _cursor, _from, _to, _flags);
ctx = _context;
cursor = _cursor;
dbm = new IodDatabaseManager(_context);
}

@Override
public View getView(final int _position, View _convertView,
    ViewGroup _parent)
{
ViewHolder holder = null;

LayoutInflater inflater = (LayoutInflater) ctx
    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

//There is no view at this position, we create a new one. In this case
//by inflating an xml layout.
if (_convertView == null)
{
    //Inflate a layout
    _convertView = inflater.inflate(R.layout.listview_item_sensor_cam,
        null);

    holder = new ViewHolder();
    holder.stateIV = (ImageView) _convertView
        .findViewById(R.id.stateImageView);
    holder.nameTV = (TextView) _convertView
        .findViewById(R.id.sensorNameTextView);
    holder.pinNumberTV = (TextView) _convertView
        .findViewById(R.id.sensorPinNumberTextView);
    holder.feedIDTV = (TextView) _convertView
        .findViewById(R.id.sensorFeedIDTextView);
    holder.freqTV = (TextView) _convertView
        .findViewById(R.id.sensorFrequencyTextView);
    holder.removeIV = (ImageView) _convertView
        .findViewById(R.id.removeImageView);
    _convertView.setTag(holder);
}
//We recycle a View that already exists.
else
{
    holder = (ViewHolder) _convertView.getTag();
}

//Set an OnClickListener to the "Delete Icon"
holder.removeIV.setOnClickListener(new OnClickListener()
{
    @SuppressWarnings("deprecation")
    @Override
    public void onClick(View _view)
    {
    cursor.moveToPosition(_position);

    //Delete sensor from database here
    int sensorID = cursor.getInt(cursor
        .getColumnIndex(IOIOSensorSchema.SENSOR_ID));
    dbm.deleteIOIOSensor(sensorID);

    //This leads to a "CursorIndexOutOfBoundsException" and cannot
    //be used to refresh the ListView
//     cursor = dbm.getIOIOSensorsCursor();

    //Refresh ListView
    cursor.requery();
    notifyDataSetChanged();
    }
});

cursor.moveToPosition(_position);

if (cursor.getCount() > 0)
{
    int state = cursor.getInt(cursor
        .getColumnIndex(IOIOSensorSchema.STATE));

    if (state == 0)
    {
    holder.stateIV.setImageResource(R.drawable.av_play_over_video);
    holder.stateIV.setColorFilter(ctx.getResources().getColor(
        R.color.hint_lighter_gray));
    //_convertView.setAlpha((float) 0.5);
    holder.nameTV.setTextColor(ctx.getResources().getColor(
        R.color.hint_darker_gray));
    }
    else
    {
    holder.stateIV.setImageResource(R.drawable.av_pause_over_video);
    holder.stateIV.setColorFilter(ctx.getResources().getColor(
        android.R.color.holo_green_light));
    //_convertView.setAlpha((float) 1);
    holder.nameTV.setTextColor(ctx.getResources().getColor(
        android.R.color.black));
    }

    //Set the sensor's name to the according TextView
    String sensorName = cursor.getString(cursor
        .getColumnIndex(IOIOSensorSchema.NAME));
    holder.nameTV.setText(sensorName);

    //Set the sensor's pin number to the according TextView
    int pinNumber = cursor.getInt(cursor
        .getColumnIndex(IOIOSensorSchema.PIN_NUMBER));
    holder.pinNumberTV.setText("" + pinNumber);

    //Set the sensor's feed ID to the according TextView
    int feedID = cursor.getInt(cursor
        .getColumnIndex(IOIOSensorSchema.FEED_ID));
    holder.feedIDTV.setText("" + feedID);

    //Set the sensor's frequency to the according TextView
    int frequency = cursor.getInt(cursor
        .getColumnIndex(IOIOSensorSchema.FREQUENCY));
    int timeUnit = cursor.getInt(cursor
        .getColumnIndex(IOIOSensorSchema.TIME_UNIT));
    String frequencyTextViewText = "";
    switch (timeUnit)
    {
    case IodIOIOSensor.TIME_UNIT_MINUTES:
    frequencyTextViewText = frequency + " min";
    break;
    case IodIOIOSensor.TIME_UNIT_HOURS:
    frequencyTextViewText = frequency + " h";
    break;
    default:
    frequencyTextViewText = frequency + " sec";
    break;
    }
    holder.freqTV.setText(frequencyTextViewText);
}
return _convertView;
}
}

Edit:

Hier ist mein entsprechender code aus dem OnCickListener nach der Implementierung der Lösung:

//Set an OnClickListener to the "Delete Icon"
holder.removeIV.setOnClickListener(new OnClickListener()
{
    @Override
    public void onClick(View _view)
    {
    cursor.moveToPosition(_position);

    //Delete sensor from database here
    int sensorID = cursor.getInt(cursor
        .getColumnIndex(IOIOSensorSchema.SENSOR_ID));
    dbm.deleteIOIOSensor(sensorID);

    Toast.makeText(ctx, R.string.toast_sensor_deleted,
        Toast.LENGTH_SHORT).show();

    //Refresh ListView
    cursor = dbm.getIOIOSensorsCursor();
    swapCursor(cursor);

    notifyDataSetChanged();
    }
});
InformationsquelleAutor kaolick | 2013-06-05
Schreibe einen Kommentar