संक्षेप में, आपको ListView के लिए उपलब्ध डेटा द्वारा हटाने के लिए एक पंक्ति को अलग करने में सक्षम होना चाहिए। यदि मान कर्सर से दूसरे कॉलम के रूप में प्राप्त किया गया है (यानी res.getString(1))
का उपयोग करके निकाला गया स्ट्रिंग , और मान अद्वितीय होने जा रहा है , आप इसे पुनः प्राप्त कर सकते हैं और इसे हटाने के लिए उपयोग कर सकते हैं।
हालांकि, ListAdapter
. का उपयोग करने में कुछ समस्याएं हैं शायद पर्याप्त नहीं होगा। अन्य एडेप्टर भी हैं, जैसे कि ऐरेएडाप्टर जो अधिक सुविधाएँ प्रदान करते हैं और महत्वपूर्ण रूप से एक notifyDatasetChanged
विधि (जो संबंधित ListView को रीफ्रेश करेगी)।
कर्सर के प्रत्येक पुनरावृत्ति के लिए एक नया एडेप्टर बनाना बेकार है। तो एडॉप्टर को लूप के बाहर और सिर्फ एक बार बनाया जाना चाहिए।
मेरा सुझाव है कि आइटम क्लिक पर हटाने से आकस्मिक क्लिक होने की संभावना बहुत अधिक होगी, आइटम लॉन्गक्लिक को हटाने से आकस्मिक विलोपन की संभावना बहुत कम होगी।
यदि आप चर को वर्ग चर के रूप में स्थानांतरित करते हैं, तो आपको उन्हें अंतिम घोषित करने की आवश्यकता नहीं है।
तो उपरोक्त के आधार पर, आप :-
एरे एडेप्टर विधि
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
विधि है :-
public int deleteRow(String col2) {
SQLiteDatabase db = this.getWritableDatabase();
return db.delete(TB001,COL_TB001_DATA + "=?",new String[]{col2});
}
- कहां
- TB001 एक स्थिर स्ट्रिंग है जो तालिका के नाम पर सेट है।
- COL_TB001_DATA दूसरे कॉलम का कॉलम नाम है।
चेतावनी उपरोक्त समाधान केवल तभी सही ढंग से काम करेगा जब दूसरे कॉलम में अद्वितीय डेटा होगा, अन्यथा एकाधिक पंक्तियां हटा दी जाएंगी।
ऐसी भी धारणा है कि हटाना काम करता है, यह बेहतर हो सकता है :-
@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
}
कर्सर एडेप्टर विधि
हालांकि, कर्सर के अनुकूल अन्य एडेप्टर हैं जो एक मध्यवर्ती सरणी की आवश्यकता को दूर कर सकते हैं। आप एक CursorAdapter
. का उपयोग कर सकते हैं . CursorAdapter
. के लिए एक कॉलम नाम _id
आवश्यक है और यह कॉलम लंबा . होना चाहिए और पंक्ति को अनजाने में पहचानें। इरादा और इसलिए नाम यह है कि पंक्तिबद्ध . का एक उपनाम का उपयोग किया जाता है (इसलिए क्यों CONSTANT BaseColumns._ID
मौजूद है)।
पंक्तिबद्ध . का एक उपनाम ?? INTEGER PRIMARY KEY
कहाँ पे ?? स्तंभ का नाम है। तो आदर्श रूप से तालिका को _id INTEGER PRIMARY KEY
के साथ कॉलम परिभाषा सहित परिभाषित किया जाना चाहिए जैसे CREATE mytable (_id INTEGER PRIMARY KEY, myothercolumn TEXT)
(आप INTEGER PRIMARY KEY
follow का अनुसरण कर सकते हैं कीवर्ड AUTOINCREMENT के साथ, हालांकि आम तौर पर आप ऐसा नहीं करेंगे, क्योंकि इसमें SQLite Autoincrement ओवरहेड्स हैं)
यदि आपकी तालिका में ऐसा कोई कॉलम नहीं है तो आप rowid AS _id
का उपयोग करके डेटा को क्वेरी करते समय हमेशा कर्सर में एक कॉलम बना सकते हैं। जैसे यदि आप SQL SELECT * FROM mytable
. के बराबर हैं तो आप उपयोग कर सकते हैं SELECT *, rowid AS _id FROM mytable
।
इस उदाहरण में स्टॉक SimpleCursorAdapter
इस्तेमाल किया जाएगा, कोड हो सकता है :-
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;
}
});
}
}
नोट _id
. के रूप में कॉलम हमेशा अद्वितीय रहेगा यदि प्रदर्शित मान अद्वितीय नहीं हैं तो यह विधि केवल विशिष्ट पंक्तियों को हटा देगी, एकाधिक पंक्तियों को नहीं।