9

これは初歩的な質問かもしれませんが、私はこの SQLite-Database-Cursor-Adapter-ListView-Do-It-Properly-Stuff のすべてにまったく慣れていません。

私が持っているもの:

私のMainActivity中にはListView. を使用し、SQLite databaseListView拡張するカスタム アダプタを設定しSimpleCursorAdapterます。私のアイテムをクリックして、私ActionBarはアクティブにしContextual Action Modeます。これまでのところすべてが機能しています。

私が欲しいもの:

私の特定のアイコンをクリックするとListView item、対応するデータベース行が削除され、ListView更新されます。

私の質問:

どうすれば自分Cursorと自分をListView適切にリフレッシュできますか? cursor.requery()使用しないで代わりにOnClickListener使用すると、行の下に数行が表示されますcursor = dbm.getIOIOSensorsCursor()CursorIndexOutOfBoundsException

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

アプリがクラッシュしましたが、リロードした後、データベースが削除され、それに応じたListView itemものがなくなりました。

_positionクラッシュは getgetViewメソッドで何か関係があるに違いないと思い_positionますfinal。ただし、cursor.requery()すべてを使用すると、正常に機能します。

しかし、このメソッドは推奨されておらず、ドキュメントには「これを使用しないでください...」と書かれています。私は適切なコーディングの友人であり (私はまだ初心者であり、迅速かつ汚い方法ではなく正しい方法でコーディングすることを学びたいと思っています)、これを正しく行う方法を知りたいと思っています。重要かどうかはわかりませんが、(非常に高速な) Nexus 4 でのみアプリをテストしていますCursor。十分に高速に更新しても問題ないようですが、遅いデバイスでも動作するかどうかは疑問です。あなたにとって重要な場合、私のデータベースには約12列の約10〜20行が含まれます。これは本当に小さなデータベースだと思います。

私のカスタムアダプターの関連コードは次のとおりです。

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;
}
}

編集:

ソリューションを実装した後の OnCickListener からの関連コードは次のとおりです。

// 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();
    }
});
4

1 に答える 1

15

Cursor と ListView を適切に更新するにはどうすればよいですか?

Cursor元の作成に使用したコードを使用して、コードを再度実行して を取得し、「[your] Cursor を更新」しますCursor(バックグラウンド スレッドでお願いします)。またはにListView電話してリフレッシュします。changeCursor()swapCursor()CursorAdapter

于 2013-06-05T11:04:32.993 に答える