如何获取项目的位置并使用光标删除它



我正在制作webview应用程序,该应用程序包含书签我使用光标SQLite数据库成功地将项目添加到listView中,但我的问题是我无法获得项目的位置并将其删除。我试图用自己的方式来做,但我得到的是我已经删除了列表视图的所有内容。这是我的MainActivity,我做了一个longClickItemListener来删除长点击时的列表视图项目,这是我BookmarkDatabase

主要活动

final Dialog bookmarksScreen = new Dialog(this);
bookmarksScreen.requestWindowFeature(Window.FEATURE_NO_TITLE);
bookmarksScreen.setContentView(R.layout.activity_bookmark);
bookmarksScreen.setCancelable(true);
final ListView listView = bookmarksScreen.findViewById(R.id.bookmark_list);
ImageView bookmarkBack   = bookmarksScreen.findViewById(R.id.close_bookmarks);
ImageView bookmarkDelete = bookmarksScreen.findViewById(R.id.delete_table);
// populate an ArrayList<String> from the database and then view it
final ArrayList<String> theList = new ArrayList<>();
Cursor data = bookmarkDB.getListContents();
// check if there is no data on database
if(data.getCount() == 0){
Log.d("Database Bookmark", "There is no items on item list");
} else {
while(data.moveToNext()) {
// add data into table "COL1" and "COL2"
theList.add(data.getString(1));
ListAdapter listAdapter = new ArrayAdapter<>(this, R.layout.activity_listitem, theList);
listView.setAdapter(listAdapter);
}
}
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String item = parent.getItemAtPosition(position).toString();
webView.loadUrl(item);
bookmarksScreen.dismiss();
}
});
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
final int which_item = position;
// here i want to delete listview item
return true;
}
});
bookmarkBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
bookmarksScreen.dismiss();
}
});
bookmarkDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showConfirmDialog();
bookmarksScreen.dismiss();
}
});
bookmarksScreen.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
bookmarksScreen.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
bookmarksScreen.show();

书签数据库

package com.rixhion.mint.databases;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class BookmarksDatabase extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "bookmarks.db";
public static final String TABLE_NAME = "bookmarks_data";
public static final String COL1 = "ID";
public static final String COL2 = "ITEM1";
public BookmarksDatabase(Context context) {
super(context, DATABASE_NAME, null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
String createTable = "CREATE TABLE " + TABLE_NAME + " (ID INTEGER PRIMARY KEY AUTOINCREMENT, " + " ITEM1 TEXT)";
db.execSQL(createTable);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
public boolean addData(String item1) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL2, item1);
long result = db.insert(TABLE_NAME, null, contentValues);
//if date as inserted incorrectly it will return -1
if (result == -1) {
return false;
} else {
return true;
}
}
public Cursor getListContents(){
SQLiteDatabase db = this.getWritableDatabase();
Cursor data = db.rawQuery("SELECT * FROM " + TABLE_NAME, null);
return data;
}
public Cursor deleteSpecificContents() {
SQLiteDatabase db = this.getWritableDatabase();
// Here i want to get the position of item and delete it
}

}

理想情况下,您应该在视图中可检索的地方使用主键(或者,反之亦然,将已在可检索的位置使用的值用作主键(。由于这里的主键是一个auto_increment字段,因此它与您试图删除的视图之间没有真正可靠的相关性(至少从我在代码中看到的情况来看(。一种方法是为列表使用自定义的Adapter,而不是ArrayAdapter,并使用View.setTag()View.getTag()方法来存储列表中每个项的主键。您可以在这里看到如何做到这一点,以及一些在线自定义适配器教程。

假设您的activity_listitem布局有一个id为text_viewTextView,您可以在其中显示从数据库中提取的文本,并且您已经向其中添加了存储主键的Tag,那么您可以在主活动中执行以下操作:

listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
TextView textView = (TextView) view.findViewById(R.id.text_view);
final Integer which_item = (Integer) textView.getTag();    //Assuming you stored the ID as an Integer
int rowsDeleted = bookmarksDB.deleteSpecificContent(which_item);
if(rowsDeleted == 0){  //should be 1, since we're deleting by Primary Key
//if you would like like, handle if nothing was deleted
}
return true;
}
});

在BookmarksDatabase类中:

public int deleteSpecificContents(int id) {
SQLiteDatabase db = this.getWritableDatabase();
return db.delete(TABLE_NAME, COL1 + "=?", new String[]{Integer.toString(id)});
}

如果您不想使用自定义Adapter,另一种方法是通过使用列表中的位置来确定要删除的项目。您可以通过查询数据库,并在Cursor上迭代,直到它与您的项目在列表上的位置相匹配。

listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
Cursor data = bookmarkDB.getListContents();
int i = 0;
while(data.moveToNext()){
if(i == position){
break;
}
i++;
}
int rowsDeleted = bookmarkDB.deleteSpecificContent(data.getInt(0));
//again, handle if rowsDeleted != 1 if you want
return true;
}
});

您的BookmarkDatabase.deleteSpecificContent()方法与第一种方法完全相同,唯一的区别在于如何确定要删除的项目的id。如果您不想处理deleteSpecificContent()不返回1的情况(除非我在这里遗漏了一些重要内容,否则在您的用例中应该始终返回1(,请随意将其签名更改为void,而不是int

请注意,第二种方法比第一种方法更昂贵,因为它需要额外的数据库查询,并且可能在Cursor上迭代很多。虽然它需要更少的新代码/更改的代码,但可能不建议使用(老实说,我不能肯定。根据数据库的大小,可能适合您的用例,但-完全公开-我对Android的经验不足,无法进行此调用。请自行使用(。

最新更新