SQLite
 sql >> Teknologi Basis Data >  >> RDS >> SQLite

Menghapus item dari ListView dan Database dengan OnItemClickListener

Singkatnya, Anda harus dapat membedakan baris untuk dihapus dengan data yang tersedia untuk ListView. Jika nilai diambil dari kursor, sebagai kolom ke-2 (yaitu String diekstraksi dengan menggunakan res.getString(1)) , dan nilainya akan menjadi unik , Anda dapat mengambil ini dan menggunakannya untuk penghapusan.

Namun, ada beberapa masalah, menggunakan ListAdapter mungkin tidak akan cukup. Ada adaptor lain, seperti ArrayAdapter yang menawarkan lebih banyak fitur dan yang terpenting notifyDatasetChanged metode (yang akan menyegarkan ListView terkait).

Adalah sia-sia untuk membuat adaptor baru untuk setiap iterasi kursor. Jadi adaptor harus dibuat di luar loop dan sekali saja.

Saya menyarankan bahwa menghapus pada klik item akan terlalu rentan terhadap klik yang tidak disengaja, menghapus item LongClick akan jauh lebih rentan terhadap penghapusan yang tidak disengaja.

Jika Anda memindahkan variabel menjadi variabel kelas, Anda tidak perlu mendeklarasikannya sebagai final.

Jadi berdasarkan hal di atas, Anda dapat memiliki :-

Metode Adaptor Array

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

Bersamaan dengan deletRow di atas caranya :-

public int deleteRow(String col2) {
    SQLiteDatabase db = this.getWritableDatabase();
    return db.delete(TB001,COL_TB001_DATA + "=?",new String[]{col2});
}
  • dimana
    • TB001 adalah String konstan yang disetel ke nama tabel.
    • COL_TB001_DATA adalah nama kolom dari kolom ke-2.

PERINGATAN Solusi di atas hanya akan berfungsi dengan benar jika kolom ke-2 berisi data unik, jika tidak, beberapa baris akan dihapus.

Ada juga anggapan bahwa penghapusan berhasil, mungkin lebih baik memiliki :-

        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
            if (myDb.deleteRow((String)fachListAdapter.getItem(position))<0) {
                faecherListe.remove(position);
            }
            fachListAdapter.notifyDataSetChanged(); 
            return true; //<<<< Indicate that this longclick has been used
        }

Metode Adaptor Kursor

Namun, ada adaptor lain yang cocok untuk Kursor yang dapat menghilangkan kebutuhan akan Array perantara. Anda dapat menggunakan CursorAdapter . Untuk CursorAdapter nama kolom _id wajib diisi dan kolom ini harus panjang dan juga mengidentifikasi baris dengan tidak jelas. Maksud dan namanya adalah alias dari rowid digunakan (karenanya juga mengapa CONSTANT BaseColumns._ID ada).

Alias ​​​​dari rowid dibuat dengan mendefinisikan ?? INTEGER PRIMARY KEY di mana ?? adalah nama kolom. Jadi idealnya tabel harus didefinisikan termasuk definisi kolom dengan _id INTEGER PRIMARY KEY misalnya CREATE mytable (_id INTEGER PRIMARY KEY, myothercolumn TEXT) (Anda dapat mengikuti INTEGER PRIMARY KEY dengan kata kunci AUTOINCREMENT, namun umumnya Anda tidak akan melakukannya, karena memiliki overhead SQLite Autoincrement)

Jika tabel Anda tidak memiliki kolom seperti itu, Anda selalu dapat membuat kolom di kursor saat mengkueri data, dengan menggunakan rowid AS _id misalnya jika Anda SQL sama dengan SELECT * FROM mytable maka Anda dapat menggunakan SELECT *, rowid AS _id FROM mytable .

Dalam contoh ini stok SimpleCursorAdapter akan digunakan, kodenya bisa :-

public class ZeigeFaecherListe extends AppCompatActivity {

    DatabaseHelper myDb;
    Cursor res;
    ListView listViewFaecher;
    SimpleCursorAdapter fachSimpleCursorAdapter;

    @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();
        fachSimpleCursorAdapter = new SimpleCursorAdapter(this,
                android.R.layout.simple_list_item_1, //<<<< The layout
                res, //<<<< The Cursor
                new String[]{"_data"}, //<<<< The column names from which to get the data
                new int[]{android.R.id.text1} //<<<< The ids of the views in which the data is placed
                );
        listViewFaecher.setAdapter(fachSimpleCursorAdapter);
        listViewFaecher.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                // id is the value of the respective _id column
                //<<<< Normally you would have the delete method in the Databasehelper >>>>
                myDb.getWritableDatabase().delete("mytable","_id=?",new String[]{String.valueOf(id)});
                fachSimpleCursorAdapter.swapCursor(myDb.zeigeFaecher()); // Tell the adapter about the new cursor
                return true;
            }
        });
    }
}

CATATAN sebagai _id kolom akan selalu unik metode ini hanya akan menghapus baris tertentu bukan beberapa baris jika nilai yang ditampilkan tidak unik.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. 3 Cara Menemukan Baris yang Mengandung Huruf Besar di SQLite

  2. Bagaimana saya bisa menambahkan kolom baru ke database SQLite setelah aplikasi Android dirilis?

  3. Cara Memeriksa apakah Tabel Ada di SQLite

  4. Cara Mendapatkan Tanggal Kemarin di SQLite

  5. Bagaimana saya bisa membagi SQLiteOpenHelper tunggal yang panjang menjadi beberapa kelas, satu untuk setiap tabel?