单击

时间:2017-09-21 19:22:34

标签: android sqlite listview

我试图通过点击删除带有SQLite数据的列表视图行。

当我按下listview项时没有任何反应,日志中没有错误。

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_new_meal);

    userList = (ListView) findViewById(R.id.listView8);

    mHelper = new DbHelper(this);
    userList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
            dataBase.delete(DbHelper.TABLE_NAME, DbHelper.MEAL_ID + "=" + mealId.get(arg2), null);
            displayData();
        }
    });

    private void displayData() {
        dataBase = mHelper.getWritableDatabase();
        Cursor mCursor = dataBase.rawQuery("SELECT * FROM "+ DbHelper.TABLE_NAME, null);
        mealId.clear();
        mealName.clear();
        if (mCursor.moveToFirst()) {
            do {
                mealId.add(mCursor.getString(mCursor.getColumnIndex(DbHelper.MEAL_ID)));
                mealName.add(mCursor.getString(mCursor.getColumnIndex(DbHelper.MEAL_NAME)));
            } while (mCursor.moveToNext());
        }
        DisplayAdapter disadpt = new DisplayAdapter(NewMealActivity.this, mealId, mealName);
        userList.setAdapter(disadpt);
        mCursor.close();
    }
}

1 个答案:

答案 0 :(得分:0)

我认为您的问题是 arg2 是列表中的位置,不等于显示的行的ID。

即如果您选择第一个项目,那么它的位置因此 arg2 0

假设您使用INTEGER PRIMARY KEYINTEGER PRIMARY KEY AUTOINCREMENT作为 id 列,那么第一个ID可能是1,接下来的2等等(但是您永远不应该依赖例如,如果删除了一行,那么很可能不会重复使用该ID并且序列被破坏了。

如果listview使用CursorAdapter,那么

arg3 会有id BUT ONLY (我建议这样做,因为那时你不需要中间件数组,刷新列表只需要重建光标并使用swapCursornotifyOnDatasetChanged,我更喜欢前者,因为它更具描述性。)

PS如果你确实使用了CursorAdapter,那么必须将id列称为 _id (有些方法可以在SELECT查询中通过AS重命名/创建列,但最好使用< strong> _id 作为表格中的列名。)

昨天我回答了一个非常相似的问题(更新而不是删除),我会指出你How can i update a field of my spinner with user input in EditText

具体答案:

您可以进行以下更改(将ID列提取到数组中时): -

更改行

        dataBase.delete(DbHelper.TABLE_NAME,
                DbHelper.MEAL_ID + "=" + mealId.get(arg2), null);

        dataBase.delete(DbHelper.TABLE_NAME,DbHelper.MEAL_ID + "=" +
                    mealId.get(arg2),null);

因此,您使用position作为mealId数组的索引,该数组具有正确的ID。

请注意!理想情况下mealId应该是Long而不是字符串,然后上面将是: -

        dataBase.delete(DbHelper.TABLE_NAME,DbHelper.MEAL_ID + "=" +
                    Long.toString(mealId.get(arg2)),null);

一起
        mealName.add(mCursor.getString(mCursor.getColumnIndex(DbHelper.MEAL_NAME)));

改为

        mealName.add(mCursor.getLong(mCursor.getColumnIndex(DbHelper.MEAL_NAME)));

比较ArrayAdapter和CursorAdapter

的工作示例

使用ArrayAdpater(DBHlper应该关闭反映你的代码(至少对于相关/使用的列)),你的代码非常相似。)

注意!使用ArrayAdapter而不是DisplayAdapter(我猜是自定义适配器)。

: -

类变量: -

    DbHelper mHelper;
    SQLiteDatabase dataBase;
    ArrayList<String> mealName = new ArrayList<>();
    ArrayList<Long> mealId = new ArrayList<>();
    ArrayAdapter<String> arrayAdapter;
    SimpleCursorAdapter sca;
    Cursor mCursor2;

活动的onCreate 中的代码(或由onCreate调用): -

    mHelper = new DbHelper(this);
    userList = (ListView) findViewById(R.id.listview);
    userList2 = (ListView) findViewById(R.id.listview2);


    // Add some data (note will add rows each time this is run)
    mHelper.insertMeal("Fish");
    mHelper.insertMeal("Beef");
    mHelper.insertMeal("Lamb");
    mHelper.insertMeal("Rice");


    // Array method
    // Looks shorter but relies upon code if displayData
    userList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
            dataBase.delete(DbHelper.TABLE_NAME,DbHelper.MEAL_ID + "=" +
                    Long.toString(mealId.get(i)),null);
            displayData();
        }
    });

    // Alternative using Cursor Adapter and thus long l (4th parameter) (the ID)
    // No Need for intermediate arrays, uses the cursor directly
    // (Only calls displayData to sync lists)
    userList2.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
            dataBase.delete(DbHelper.TABLE_NAME,DbHelper.MEAL_ID + "=" +
            Long.toString(l),null);
            mCursor2 = dataBase.query(DbHelper.TABLE_NAME,null,null,null,null,null,null);
            sca.swapCursor(mCursor2);
            // keep userList in sync with userList2
            displayData();
        }
    });

    //Initial setup of userList2
    dataBase = mHelper.getWritableDatabase();
    mCursor2 = dataBase.query(DbHelper.TABLE_NAME,null,null,null,null,null,null);
    sca = new SimpleCursorAdapter(this,
            android.R.layout.simple_list_item_1,
            mCursor2,
            new String[] {DbHelper.MEAL_NAME},
            new int[] {android.R.id.text1},
            0
    );
    userList2.setAdapter(sca);

    //Initial setup of userList
    displayData();
}

displayData 方法(除了调用同步列表之外,仅对ArrayAdpater非常需要): -

private void displayData() {
    dataBase = mHelper.getWritableDatabase();
    Cursor mCursor = dataBase.rawQuery("SELECT * FROM " + DbHelper.TABLE_NAME,null);
    mealId.clear();
    mealName.clear();
    while (mCursor.moveToNext()) {
        mealId.add(mCursor.getLong(mCursor.getColumnIndex(DbHelper.MEAL_ID)));
        mealName.add(mCursor.getString(mCursor.getColumnIndex(DbHelper.MEAL_NAME)));
        arrayAdapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_selectable_list_item,
                mealName
        );
        userList.setAdapter(arrayAdapter);
    }
    // keep userlist 2 in sync userList
    mCursor2 = mCursor; // cheat by using userList's cursor
    sca.swapCursor(mCursor2);
}

示例显示: -

enter image description here

点击左侧列表(ArrayAdapter)中的 Lamb (第1项)后: -

enter image description here

点击右侧列表(CursorAdapter)中的牛肉(现在第3项)后: -

enter image description here