android - SQLite 行 ID 与 ListView 行 ID 不匹配

标签 android sqlite listview android-sqlite

我有一个 SQLite 数据库和一个在主 Activity 中显示的 ListView。在 ListView 中,我显示每个列表编号的详细信息,按下列表项后,会打开一个新 Activity ,在 TextView 中显示详细信息。

我对每个 ListView 都有一个删除功能,但它们无法正常工作。本质上,为每个创建的 ListView 赋予一个唯一的 ID,这就是 SQLite 数据库应有的工作方式。但是,在 ListView 中删除一行后,唯一 ID 会增加,但行 ID 会删除该数字并将所有内容向上移动。这意味着删除某个项目后,行 ID 和数据库 ID 不再匹配,并且当尝试在 ListView 中选择项目时,它会崩溃。这是我的数据库适配器类的摘录:

 public Integer deleteStat(Integer id) {
    SQLiteDatabase db = this.getWritableDatabase();
    return db.delete(STATS_TABLE, "id = ? ", new String[]{Integer.toString(id)});
}

这是我在主要 Activity 中的第一次尝试。我从this得到了一些信息发布但未能获得正确的整数并收到语法错误:

obj.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {

 TextView pos = (TextView) findViewById(R.id.editTitle);
 displayText(Integer.parseInt(pos.getText().toString()));
        }
    });
}

public void displayText(int pos)
{
    pos++;
    String s = "";
    s += pos;

    Intent intent = new Intent(getApplicationContext(), DisplayStatsActivity.class);
    intent.putExtra("id", s);
    startActivity(intent);

}

这是我在主要 Activity 中的第二次尝试。我用过this教程来帮助我。我从该网站使用的代码破坏了整个删除功能:

 obj.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
           int id_To_Search = arg2 + 1;
           int id_To_Search = arg0.getCount() - arg2;

           Bundle dataBundle = new Bundle();
            dataBundle.putInt("id", id_To_Search);

            Intent intent = new Intent(getApplicationContext(), DisplayStatsActivity.class);

           intent.putExtras(dataBundle);
           startActivity(intent);

如何使数据库 ID 与行 ID 相匹配?关于如何做到这一点有什么建议吗?

编辑:添加到 HashMap 代码中。当我按下 ListView 项目时,没有任何反应

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_home);

    mydb = new StatisticsDbAdapter(this);
    ArrayList array_list = mydb.getAllStats();
    ArrayAdapter arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, array_list);

    obj = (ListView) findViewById(R.id.listView1);
    obj.setAdapter(arrayAdapter);
    /*
     New code starts here
    */
   Bundle extras = getIntent().getExtras();
    if (extras != null) {
        int Value = extras.getInt("id");

        if (Value > 0) {
            //means this is the view part not the add contact part
            Cursor cursor = mydb.getData(Value);
            hashMap.put(cursor.getString(1), cursor.getInt(0));

 obj.setOnItemClickListener(new OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> adapterView, View view, int arg2, long arg3) {
     TextView textView = (TextView) view.findViewById(R.id.editTitle);
                    Bundle dataBundle = new Bundle();
                    dataBundle.putInt("id", hashMap.get(textView.getText().toString()));

                    Intent intent = new Intent(getApplicationContext(), DisplayStatsActivity.class);

                    intent.putExtras(dataBundle);
                    startActivity(intent);
 }
            });
        }
    }
}

最佳答案

您永远不应该传递 ListView 位置来删除数据库中的行。我以前已经做过很多次了。首先,在您管理点击事件的类中,创建一个新的HashMap。这个HashMap将用于存储数据库中的行ID,我们将引用它而不是ListView项目位置。要创建它,请键入以下代码:

public HashMap<String, Integer> hashMap = new HashMap<>();

完成此操作后,在显示 ListView 中所有行的函数中,您还必须将相同的项目加载到 HashMap 中,如下所示:

hashMap.put(cursor.getString(1), cursor.getInt(0));

请注意,cursor.getString(1) 可能不是您使用的。请将 1 替换为其中存储有名称的相应列号。 cursor.getInt(0) 从数据库获取行 ID,列号也可能与您不同。现在,在 OnClickListener 函数中,我们可以输入:

obj.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> adapterView, View view) {
       TextView textView = (TextView) view.findViewById(R.id.editTitle);
       Bundle bundle = new Bundle();
       bundle.putInt("id", hashMap.get(textView.getText().toString()));

       Intent intent = new Intent(getApplicationContext(), DisplayStatsActivity.class);

       intent.putExtras(bundle);
       startActivity(intent);
}

请注意,hashMap 变量需要位于管理 ListView 的点击事件的同一类中,否则会出错。您最初传递的一些参数已被删除,因为您不需要它们。另外,我发现使用 RecyclerView 效果更好,但现在由您决定。如果您遇到问题,请随时在下面发表评论,我会尽快回复。

关于android - SQLite 行 ID 与 ListView 行 ID 不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37797041/

相关文章:

Android append 文本文件

android - 为 EmptyView android 设置一个按钮 onClickListener

Android SQLite 问题 "Cannot perform this operation because the connection pool has been closed"

sqlite - 如何忽略sqlite3插入失败以允许tcl脚本在失败后继续?

sql - SQL 中的别名作用域

android - ListView 自定义过滤器在过滤时给出错误的项目选择 [Android]

android - 如何检索网页上的列表并将其返回到android中的列表?

android - Webview 应用程序在第一次安装应用程序时工作,但之后只显示空白屏幕

android - 动态 ListView 扩展 Activity

android - 通过单击 ListItem 中的 ImageView 删除 ListItem