SQLite
 sql >> Baza danych >  >> RDS >> SQLite

Usuwanie elementu z ListView i bazy danych za pomocą OnItemClickListener

Krótko mówiąc, musisz być w stanie odróżnić wiersz do usunięcia na podstawie danych dostępnych dla ListView. Jeśli wartość pobrana z kursora, jako druga kolumna (tj. String wyodrębniony przy użyciu res.getString(1)) , a wartość będzie unikalna , możesz go pobrać i użyć do usunięcia.

Istnieje jednak kilka problemów związanych z używaniem ListAdapter prawdopodobnie nie wystarczy. Istnieją inne adaptery, takie jak ArrayAdapter, które oferują więcej funkcji i, co ważne, notifyDatasetChanged metoda (która odświeży powiązany widok ListView).

Marnotrawstwem jest tworzenie nowego adaptera dla każdej iteracji kursora. Dlatego adapter powinien być utworzony poza pętlą i tylko raz.

Sugeruję, że usunięcie kliknięcia elementu będzie zbyt podatne na przypadkowe kliknięcie, a usunięcie elementu LongClick będzie znacznie mniej podatne na przypadkowe usunięcie.

Jeśli przenosisz zmienne jako zmienne klasowe, nie musisz deklarować ich jako ostatecznych.

Więc w oparciu o powyższe, możesz mieć:-

Metoda adaptera tablicy

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

Wraz z powyższym deletRow metoda to :-

public int deleteRow(String col2) {
    SQLiteDatabase db = this.getWritableDatabase();
    return db.delete(TB001,COL_TB001_DATA + "=?",new String[]{col2});
}
  • gdzie
    • TB001 jest stałym ciągiem, który jest ustawiony na nazwę tabeli.
    • COL_TB001_DATA to nazwa kolumny drugiej kolumny.

OSTRZEŻENIE Powyższe rozwiązanie będzie działać poprawnie tylko wtedy, gdy druga kolumna zawiera unikalne dane, w przeciwnym razie wiele wierszy zostanie usuniętych.

Istnieje również założenie, że usuwanie działa, lepiej byłoby mieć :-

        @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
        }

Metoda adaptera kursora

Istnieją jednak inne adaptery odpowiednie dla Cursors, które mogą wyeliminować potrzebę pośredniej tablicy. Możesz użyć CursorAdapter . Dla Adaptera kursora nazwa kolumny _id jest wymagana, a ta kolumna powinna być długa a także jednoznacznie identyfikować wiersz. Intencją i stąd nazwa jest to, że alias rowidu jest używany (stąd też dlaczego STAŁY BaseColumns._ID istnieje).

Alias ​​rowidu jest tworzony przez zdefiniowanie ?? CAŁKOWITY KLUCZ PODSTAWOWY gdzie ?? to nazwa kolumny. Idealnie więc, tabela powinna być zdefiniowana wraz z definicją kolumny z _id INTEGER PRIMARY KEY np. CREATE mojatabela (_id INTEGER PRIMARY KEY, mojainnakolumna TEXT) (możesz śledzić INTEGER PRIMARY KEY ze słowem kluczowym AUTOINCREMENT, jednak generalnie nie zrobiłbyś tego, ponieważ ma on narzuty na autoinkrementację SQLite)

Jeśli Twoja tabela nie ma takiej kolumny, zawsze możesz utworzyć kolumnę w kursorze podczas zapytania o dane, używając rowid AS _id np. jeśli SQL równa się SELECT * FROM mytable wtedy możesz użyć SELECT *, rowid AS _id FROM mytable .

W tym przykładzie giełdowy SimpleCursorAdapter zostanie użyty, kod może wyglądać tak:-

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

UWAGA jako _id kolumna będzie zawsze unikalna, ta metoda usunie tylko określony wiersz, a nie wiele wierszy, jeśli wyświetlane wartości nie są unikatowe.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Zbuduj książkę kontaktów za pomocą Pythona, PyQt i SQLite

  2. Uzyskaj identyfikator wiersza tabeli SQLite FTS3

  3. Pokój Android + funkcje okna

  4. Jak przenieść pole ForeignCollection do kursora w Ormlite?

  5. Jak zaktualizować istniejące dane za pomocą SQLite