Resumindo, você precisa ser capaz de distinguir uma linha para exclusão pelos dados disponíveis para o ListView. Se o valor recuperado do cursor, como a 2ª coluna (ou seja, a String extraída usando
res.getString(1))
, e o valor será único , você pode recuperá-lo e usá-lo para a exclusão. No entanto, existem alguns problemas, usando um
ListAdapter
provavelmente não será suficiente. Existem outros adaptadores, como um ArrayAdapter que oferece mais recursos e, principalmente, um notifyDatasetChanged
método (que irá atualizar o ListView associado). É um desperdício criar um novo adaptador para cada iteração do cursor. Portanto, o adaptador deve ser criado fora do loop e apenas uma vez.
Eu sugiro que a exclusão no clique do item será muito propensa a cliques acidentais, a exclusão no item LongClick seria muito menos propensa à exclusão acidental.
Se você mover variáveis para serem variáveis de classe, não precisará declará-las como finais.
Então, com base no acima, você poderia ter:-
Método do adaptador de matriz
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));
}
}
}
Junto com o acima, o
deletRow
método é:- public int deleteRow(String col2) {
SQLiteDatabase db = this.getWritableDatabase();
return db.delete(TB001,COL_TB001_DATA + "=?",new String[]{col2});
}
- onde
- TB001 é uma String constante que é definida para o nome da tabela.
- COL_TB001_DATA é o nome da coluna da 2ª coluna.
AVISO A solução acima só funcionará corretamente se a 2ª coluna contiver dados exclusivos, caso contrário, várias linhas serão excluídas.
Há também a suposição de que a exclusão funciona, poderia ser melhor ter:-
@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
}
Método do adaptador de cursor
No entanto, existem outros adaptadores adequados para Cursores que podem dispensar a necessidade de um Array intermediário. Você pode utilizar um
CursorAdapter
. Para um CursorAdapter
um nome de coluna _id
é obrigatório e esta coluna deve ser longa e também identificar de forma estranha a linha. A intenção e, portanto, o nome é que um alias do rowid é usado (daí também porque o CONSTANT BaseColumns._ID
existe). Um alias do rowid é criado definindo
?? INTEGER PRIMARY KEY
Onde ?? é o nome da coluna. Então, idealmente, a tabela deve ser definida incluindo uma definição de coluna com _id INTEGER PRIMARY KEY
por exemplo. CREATE mytable (_id INTEGER PRIMARY KEY, myothercolumn TEXT)
(você pode seguir INTEGER PRIMARY KEY
com a palavra-chave AUTOINCREMENT, no entanto, geralmente você não faria isso, pois tem overheads SQLite Autoincrement) Se sua tabela não tiver essa coluna, você sempre poderá criar uma coluna no cursor ao consultar os dados, usando
rowid AS _id
por exemplo. se você SQL equivale a SELECT * FROM mytable
então você pode usar SELECT *, rowid AS _id FROM mytable
. Neste exemplo, o estoque
SimpleCursorAdapter
será usado, o código pode ser:- 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;
}
});
}
}
OBSERVAÇÃO como o
_id
coluna será sempre exclusiva, este método excluirá apenas a linha específica, não várias linhas, se os valores exibidos não forem exclusivos.