使用OnItemClickListener从ListView和数据库中删除项目 [英] Deleting item from ListView and Database with OnItemClickListener

查看:68
本文介绍了使用OnItemClickListener从ListView和数据库中删除项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个数据库,并设法将添加的项目显示到ListView中.现在,我需要一种从ListView和数据库中删除项目的方法.

I created a database and managed to display the added items into a ListView. Now I need a method to delete an item from the ListView and the Database.

public class ZeigeFaecherListe extends AppCompatActivity {

    DatabaseHelper myDb;

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

        myDb = new DatabaseHelper(this);
        ListView listViewFaecher = (ListView) findViewById(R.id.listViewFaecher);

        final ArrayList<String> faecherListe = new ArrayList<>();
        Cursor res = myDb.zeigeFaecher();

        if (res.getCount() == 0){
            Toast.makeText(ZeigeFaecherListe.this, "Keine Fächer gefunden", Toast.LENGTH_LONG).show();
        } else {
            while (res.moveToNext()){
                faecherListe.add(res.getString(1));
                ListAdapter fachListAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, faecherListe);
                listViewFaecher.setAdapter(fachListAdapter);
            }
        }

        listViewFaecher.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {

            }
        });
    }
}

推荐答案

简而言之,您需要能够通过ListView可用的数据来区分要删除的行.如果从游标中检索到的值作为第二列(即使用res.getString(1))提取的字符串,并且该值是唯一的),则可以检索该值并将其用于删除.

In short, you need to be able to distinguish a row for deletion by the data available to the ListView. If the value retrieved from the cursor, as the 2nd column (i.e. the String extracted by using res.getString(1)), and the value is going the be unique, you can retrieve this and use it for the deletion.

但是,有一些问题,使用ListAdapter可能还不够.还有其他适配器,例如ArrayAdapter,提供更多功能,重要的是 notifyDatasetChanged 方法(将刷新关联的ListView).

However, there are a few issues, using a ListAdapter will probably not be sufficient. There are other adapters, such as an ArrayAdapter that offer more features and importantly a notifyDatasetChanged method (that will refresh the associated ListView).

为游标的每次迭代创建一个新的适配器是一种浪费.因此,适配器应该在循环外部创建,并且只能创建一次.

It is a waste to create a new adapter for each iteration of the cursor. So the adapter should be created outside of the loop and just the once.

我建议删除项目单击会太容易导致意外点击,而删除项目LongClick会容易导致意外删除.

I'd suggest that deleting on item click will be too prone to accidental clicking, deleting on item LongClick would be far less prone to accidental deletion.

如果将变量移动为类变量,则不必将其声明为final.

If you move variables to be class variables you don't have to declare them as final.

因此,根据以上所述,您可能会:-

So based upon the above, you could have :-

public class ZeigeFaecherListe extends AppCompatActivity {

    DatabaseHelper myDb;
    Cursor res;
    ListView listViewFaecher;
    ArrayAdapter<String> fachListAdapter;
    ArrayList<String> faecherListe;

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

        listViewFaecher = (ListView) this.findViewById(R.id.listview);
        myDb = new DatabaseHelper(this);
        addSomeData(); //<<<<<<<<<< ADDED for testing

        faecherListe = new ArrayList<>();
        res = myDb.zeigeFaecher();
        while (res.moveToNext()) {
            faecherListe.add(res.getString(1));
        }

        //<<<< NOTE outside of the loop as this only needs to be done once
        fachListAdapter = new ArrayAdapter<String>(
                this,
                android.R.layout.simple_list_item_1,
                faecherListe
        );
        listViewFaecher.setAdapter(fachListAdapter);

        //<<<<< NOTE used LONG CLICK listener (less likely to accidentally delete)
        listViewFaecher.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                myDb.deleteRow((String)fachListAdapter.getItem(position));
                faecherListe.remove(position);
                fachListAdapter.notifyDataSetChanged(); 
                return true; //<<<< Indicate that this longclick has been used
            }
        });
    }

    private void addSomeData() {
        for (int i=1; i <= 10; i++) {
            myDb.addRow("Row " + String.valueOf(i));
        }
    }
}

与上述 deletRow 方法相同的是:-

Along with the above the deletRow method is :-

public int deleteRow(String col2) {
    SQLiteDatabase db = this.getWritableDatabase();
    return db.delete(TB001,COL_TB001_DATA + "=?",new String[]{col2});
}

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆