【问题标题】:SQLite row IDs do not match the ListView row IDsSQLite 行 ID 与 ListView 行 ID 不匹配
【发布时间】:2016-10-14 07:15:17
【问题描述】:

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

我对每个ListViews 都有一个删除功能,但它们无法正常工作。本质上,每个创建的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)});
}

这是我在主要活动中的第一次尝试。我从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);

}

这是我在主要活动中的第二次尝试。我用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);
 }
            });
        }
    }
}

【问题讨论】:

  • SQLite Row IDs do not match ListView 这很明显。想象一下您的 id 以 953 开头(因为您进行了很多试验,并且多次删除了所有测试记录)。您是否假装您的 ListView 从项目编号 953 开始?不,显然不是。它将开始在 ITS 项目编号 0 处填充其项目。
  • 那么当我尝试单击它们以回调它们时,如何确保在从列表视图中删除行后数据库 ID 与行 ID 保持一致?
  • 谷歌关键词:android listview database delete

标签: android sqlite listview android-sqlite


【解决方案1】:

您不应该传递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 可以更好地工作,但这现在取决于您。如果您遇到问题,请不要犹豫,在下面发表评论,我会尽快回复。

【讨论】:

  • 嘿,非常感谢您的出色回复!我试图添加一些东西,并且 hashMap 似乎正在工作。但是,当我点击我当前正在添加的一些项目时,现在什么都没有发生。我相信这可能与TextView pos = (TextView) findViewById(R.id.editTitle); 行有关,您认为我不应该在这里称呼标题行吗?当我认为该行只是为了获取数据应该来自的 ID 时,我不确定应该在 TextView 中引用什么变量。让我知道你的想法!
  • 这可能是你提到的那一行。我建议您访问 this 链接并获取所选项目的 TextView 值并传递它。
  • 请再次检查我提供给您的代码。我已经调整了一些现在应该可以工作的东西。
  • 如果您认为我提供的代码和提示对您有所帮助,请按绿色勾号接受此作为答案。
  • 我以前从未见过public void onItemClick(AdapterView&lt;?&gt; adapterView, View view) 这样写的行。当我尝试这样输入时(没有 int arg2, long arg3 的参数),它对语法不满意。我做错了吗?
猜你喜欢
  • 2015-03-08
  • 1970-01-01
  • 1970-01-01
  • 2020-03-19
  • 1970-01-01
  • 2021-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多