Kortom, u moet een rij voor verwijdering kunnen onderscheiden aan de hand van de gegevens die beschikbaar zijn voor de ListView. Als de waarde opgehaald van de cursor, als de 2e kolom (d.w.z. de String geëxtraheerd met behulp van res.getString(1))
, en de waarde wordt uniek , kunt u deze ophalen en gebruiken voor de verwijdering.
Er zijn echter een paar problemen bij het gebruik van een ListAdapter
zal waarschijnlijk niet voldoende zijn. Er zijn andere adapters, zoals een ArrayAdapter die meer functies biedt en vooral een notifyDatasetChanged
methode (die de bijbehorende ListView zal verversen).
Het is zonde om voor elke iteratie van de cursor een nieuwe adapter te maken. Dus de adapter moet buiten de lus worden gemaakt en slechts één keer.
Ik stel voor dat het verwijderen van een itemklik te gevoelig is voor onbedoeld klikken, terwijl het verwijderen van item LongClick veel minder vatbaar is voor per ongeluk verwijderen.
Als u variabelen verplaatst om klassevariabelen te zijn, hoeft u ze niet als definitief te declareren.
Dus op basis van het bovenstaande zou je kunnen hebben:-
Array Adapter-methode
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));
}
}
}
Samen met het bovenstaande de deletRow
methode is:-
public int deleteRow(String col2) {
SQLiteDatabase db = this.getWritableDatabase();
return db.delete(TB001,COL_TB001_DATA + "=?",new String[]{col2});
}
- waar
- TB001 is een constante String die is ingesteld op de naam van de tabel.
- COL_TB001_DATA is de kolomnaam van de 2e kolom.
WAARSCHUWING De bovenstaande oplossing werkt alleen correct als de 2e kolom unieke gegevens bevat, anders zouden meerdere rijen worden verwijderd.
Er is ook de veronderstelling dat het verwijderen werkt, het zou beter zijn om:-
@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
}
Cursoradaptermethode
Er zijn echter andere adapters die geschikt zijn voor Cursors die de noodzaak van een tussenliggende array zouden kunnen wegnemen. U kunt een CursorAdapter
. gebruiken . Voor een CursorAdapter
een kolomnaam _id
is vereist en deze kolom moet een lange . zijn en ook de rij uniek identificeren. De bedoeling en vandaar de naam is dat een alias van de rowid wordt gebruikt (vandaar ook waarom de CONSTANT BaseColumns._ID
bestaat).
Een alias van de rowid wordt gemaakt door ?? INTEGER PRIMARY KEY
waar ?? is de kolomnaam. Dus idealiter zou de tabel moeten worden gedefinieerd inclusief een kolomdefinitie met _id INTEGER PRIMARY KEY
bijv. CREATE mytable (_id INTEGER PRIMARY KEY, myothercolumn TEXT)
(u kunt INTEGER PRIMARY KEY
volgen met het trefwoord AUTOINCREMENT, maar over het algemeen zou u dit niet doen, omdat het overheadkosten heeft SQLite Autoincrement)
Als uw tabel niet zo'n kolom heeft, kunt u altijd een kolom in de cursor maken bij het opvragen van de gegevens, met behulp van rowid AS _id
bijv. als je SQL gelijk is aan SELECT * FROM mytable
dan kun je SELECT *, rowid AS _id FROM mytable
. gebruiken .
In dit voorbeeld is de standaard SimpleCursorAdapter
zal worden gebruikt, kan de code zijn:-
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;
}
});
}
}
OPMERKING als de _id
kolom zal altijd uniek zijn. Deze methode verwijdert alleen de specifieke rij en niet meerdere rijen als de weergegeven waarden niet uniek zijn.