[活动的GIF] [1] < ---------------观看活动
我一直在尝试从 ListView 中的 SQLite 中删除行上的项目时遇到问题 到目前为止,我已经能够成功删除列表中的第一个项目。每当我点击 ListView 上的删除按钮时。
如果您有任何意见或反馈,请随时放纵我!
以下是相关代码
DBHelper
public class DBHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "ListappDB";
private static final int DB_VERSION = 1;
public static final String DB_TABLE = "List";
public static final String DB_COLUMN = "Item";
public DBHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
String query = String.format("CREATE TABLE %s(ID INTEGER PRIMARY KEY AUTOINCREMENT, %s TEXT NOT NULL)", DB_TABLE, DB_COLUMN);
db.execSQL(query);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
String query = String.format("DELETE TABLE IF EXISTS %s", DB_TABLE);
db.execSQL(query);
onCreate(db);
}
public void insertNewItem(String item){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(DB_COLUMN, item);
db.insertWithOnConflict(DB_TABLE, null, values, SQLiteDatabase.CONFLICT_REPLACE);
db.close();
}
public void deleteItem(String item){
SQLiteDatabase db = this.getWritableDatabase();
db.delete(DB_TABLE, DB_COLUMN + "=?", new String[]{ item });
db.close();
}
public ArrayList<String> getItemList(){
ArrayList<String> itemList = new ArrayList<String>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(DB_TABLE, new String[]{DB_COLUMN},null,null,null,null,null);
while (cursor.moveToNext()){
int index = cursor.getColumnIndex(DB_COLUMN);
itemList.add(cursor.getString(index));
}
cursor.close();
db.close();
return itemList;
}
}
主要活动
public class MainActivity extends AppCompatActivity {
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private DBHelper mDBHelper;
private ArrayAdapter<String> mAdapter;
private ListView mListView;
private Button mButton;
private Button mDeleteButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_ACTION_BAR);
setContentView(R.layout.activity_main);
mDBHelper = new DBHelper(this);
mAuth = FirebaseAuth.getInstance();
mListView = (ListView) findViewById(R.id.list);
mButton = (Button) findViewById(R.id.buttonQR);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ArrayList<String> itemList = mDBHelper.getItemList();
MultiFormatWriter multiFW = new MultiFormatWriter();
try {
BitMatrix bitMatrix = multiFW.encode(String.valueOf(itemList), BarcodeFormat.QR_CODE, 200, 200);
BarcodeEncoder enconder = new BarcodeEncoder();
Bitmap bitmap = enconder.createBitmap(bitMatrix);
Intent intent = new Intent(getApplicationContext(), QR.class);
intent.putExtra("qrcode", bitmap);
startActivity(intent);
} catch (WriterException e) {
e.printStackTrace();
}
}
});
mAuthListener = new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
if (firebaseAuth.getCurrentUser() == null){
goAuthenticate();
}
}
};
loadItemList();
}
private void loadItemList() {
ArrayList<String> itemList = mDBHelper.getItemList();
if (mAdapter==null){
mAdapter = new ArrayAdapter<String>(this, R.layout.row, R.id.item_name, itemList);
mListView.setAdapter(mAdapter);
} else {
mAdapter.clear();
mAdapter.addAll(itemList);
mAdapter.notifyDataSetChanged();
}
}
public void goAuthenticate(){
Intent mLogin = new Intent(MainActivity.this, Authentication.class);
mLogin.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(mLogin);
finish();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater=getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.logout:
mAuth.signOut();
LoginManager.getInstance().logOut();
break;
case R.id.addNewItem:
final EditText itemEditText = new EditText(this);
AlertDialog alertDialog = new AlertDialog.Builder(this)
.setTitle("Add New Item")
.setView(itemEditText)
.setPositiveButton("Add", new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
String item = String.valueOf(itemEditText.getText());
if(item.length() <= 0|| item.equals("")){
Toast.makeText(MainActivity.this, "Item Cant Be Blank",
Toast.LENGTH_LONG).show();
} else {
mDBHelper.insertNewItem(item);
loadItemList();
}
}
})
.setNegativeButton("Cancel", null)
.create();
alertDialog.show();
break;
}
return super.onOptionsItemSelected(item);
}
public void deleteItemH(View view){
TextView itemTextView = (TextView) view.findViewById(R.id.item_name);
String item = String.valueOf(itemTextView.getText());
mDBHelper.deleteItem(item);
loadItemList();
}
@Override
public void onStart() {
super.onStart();
mAuth.addAuthStateListener(mAuthListener);
}
@Override
public void onStop() {
super.onStop();
if (mAuthListener != null){
mAuth.removeAuthStateListener(mAuthListener);
}
}
}
Row.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:id="@+id/item_name"
android:text="Example"
android:textSize="20dp"
android:layout_alignParentStart="true"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnDelete"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:text="DELETE"
android:onClick="deleteItemH"
android:layout_centerVertical="true"/>
活动Main.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="tech.destinum.listapp.MainActivity"
android:layout_centerVertical="true">
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/list"
android:clipChildren="false"
android:layout_weight="1"/>
<RelativeLayout
android:id="@+id/footer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:gravity="center">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/buttonQR"
android:text="Generate"/>
</RelativeLayout>
答案 0 :(得分:0)
您解决问题中提到的问题的方法不正确。 用下面的解决方案提到问题
问题1
您应该使用自定义适配器而不是使用基本的ArrayAdapter。
ItemAdapter.class
public class ItemAdapter extends BaseAdapter {
private final LayoutInflater layoutInflater;
private ArrayList<ItemClass> itemList;
private final DBHelper dbHelper;
public ItemAdapter(Context context, DBHelper dbHelper, ArrayList<ItemClass> itemList) {
this.itemList = itemList;
this.layoutInflater = LayoutInflater.from(context);
this.dbHelper = dbHelper;
}
@Override
public int getCount() {
return itemList != null ? itemList.size() : 0;
}
@Override
public Object getItem(int i) {
return itemList.get(i);
}
@Override
public long getItemId(int i) {
return itemList.get(i)._id;
}
//use this function to assign list of items
public void setItemList(ArrayList<ItemClass> itemList) {
this.itemList.clear();
this.itemList = itemList;
notifyDataSetChanged();
}
@Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
ViewHolder viewHolder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.row, null);
viewHolder = new ViewHolder(convertView);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
final ItemClass itemClass = itemList.get(position);
viewHolder.btn_delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
deleteItemH(itemClass);
}
});
viewHolder.tv_item.setText(itemClass.detail);
return convertView;
}
private void deleteItemH(ItemClass item) {
dbHelper.deleteItemById(item._id);
setItemList(dbHelper.getItemList());
}
private static class ViewHolder {
final Button btn_delete;
final TextView tv_item;
ViewHolder(View view) {
btn_delete = (Button) view.findViewById(R.id.btnDelete);
tv_item = (TextView) view.findViewById(R.id.item_name);
}
}
}
问题2: -
您尝试使用项目列删除行数据 将删除所有具有相同名称的行,因为您没有放置唯一的行 项目列中的约束。
因此,根据您的使用情况,您应该在项目列上设置一个唯一约束,或者通过 _ID列删除该项目。
修改 DBHelper 代码以删除 _ID列的行。
public class DBHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "ListappDB";
private static final int DB_VERSION = 1;
public static final String DB_TABLE = "List";
public static final String DB_COLUMN = "Item";
//added this variable to use it while deleting the record
public static final String DB_COLUMN_ID = "_id";
public DBHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
String query = String.format("CREATE TABLE %s( %s INTEGER PRIMARY KEY AUTOINCREMENT, %s TEXT NOT NULL)", DB_TABLE, DB_COLUMN_ID, DB_COLUMN);
db.execSQL(query);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
String query = String.format("DELETE TABLE IF EXISTS %s", DB_TABLE);
db.execSQL(query);
onCreate(db);
}
public void insertNewItem(String item) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(DB_COLUMN, item);
db.insertWithOnConflict(DB_TABLE, null, values, SQLiteDatabase.CONFLICT_REPLACE);
db.close();
}
public void deleteItem(String item) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(DB_TABLE, DB_COLUMN + "=?", new String[]{item});
db.close();
}
//Function to delete item using ID
public void deleteItemById(long id) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(DB_TABLE, DB_COLUMN_ID + "=?", new String[]{id + ""});
db.close();
}
public ArrayList<ItemClass> getItemList() {
ArrayList<ItemClass> itemList = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(DB_TABLE, new String[]{DB_COLUMN_ID, DB_COLUMN}, null, null, null, null, null);
while (cursor.moveToNext()) {
final String name = cursor.getString(cursor.getColumnIndex(DB_COLUMN));
final long id = cursor.getLong(cursor.getColumnIndex(DB_COLUMN_ID));
itemList.add(new ItemClass(id, name));
}
cursor.close();
db.close();
return itemList;
}
}
修改了 MainActivity.class 以支持上面使用的 ItemAdapter.class
public class MainActivity extends AppCompatActivity {
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private DBHelper mDBHelper;
private ItemAdapter mAdapter;
private ListView mListView;
private Button mButton;
private Button mDeleteButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_ACTION_BAR);
setContentView(R.layout.activity_main);
mDBHelper = new DBHelper(this);
mAuth = FirebaseAuth.getInstance();
mListView = (ListView) findViewById(R.id.list);
mButton = (Button) findViewById(R.id.buttonQR);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ArrayList<String> itemList = mDBHelper.getItemList();
MultiFormatWriter multiFW = new MultiFormatWriter();
try {
BitMatrix bitMatrix = multiFW.encode(String.valueOf(itemList), BarcodeFormat.QR_CODE, 200, 200);
BarcodeEncoder enconder = new BarcodeEncoder();
Bitmap bitmap = enconder.createBitmap(bitMatrix);
Intent intent = new Intent(getApplicationContext(), QR.class);
intent.putExtra("qrcode", bitmap);
startActivity(intent);
} catch (WriterException e) {
e.printStackTrace();
}
}
});
mAuthListener = new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
if (firebaseAuth.getCurrentUser() == null){
goAuthenticate();
}
}
};
loadItemList();
}
//only needed once rest of the time it is getting managed inside the ItemAdapter
private void loadItemList() {
ArrayList<ItemClass> itemList = mDBHelper.getItemList();
mAdapter = new ItemAdapter(MainActivity.this, mDBHelper, itemList);
mListView.setAdapter(mAdapter);
}
public void goAuthenticate(){
Intent mLogin = new Intent(MainActivity.this, Authentication.class);
mLogin.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(mLogin);
finish();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater=getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.logout:
mAuth.signOut();
LoginManager.getInstance().logOut();
break;
case R.id.addNewItem:
final EditText itemEditText = new EditText(this);
AlertDialog alertDialog = new AlertDialog.Builder(this)
.setTitle("Add New Item")
.setView(itemEditText)
.setPositiveButton("Add", new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
String item = String.valueOf(itemEditText.getText());
if(item.length() <= 0|| item.equals("")){
Toast.makeText(MainActivity.this, "Item Cant Be Blank",
Toast.LENGTH_LONG).show();
} else {
mDBHelper.insertNewItem(item);
loadItemList();
}
}
})
.setNegativeButton("Cancel", null)
.create();
alertDialog.show();
break;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onStart() {
super.onStart();
mAuth.addAuthStateListener(mAuthListener);
}
@Override
public void onStop() {
super.onStop();
if (mAuthListener != null){
mAuth.removeAuthStateListener(mAuthListener);
}
}
}
添加了额外的 ItemClass.java ,以支持适配器传递id和item。
public class ItemClass {
public final long _id;
public final String detail;
public ItemClass(long id, String detail) {
_id = id;
this.detail = detail;
}
}
从 row.xml 中删除 android:onClick =“deleteItemH”,因为您无法在点击适配器的项目中使用。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:id="@+id/item_name"
android:text="Example"
android:textSize="20dp"
android:layout_alignParentStart="true"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnDelete"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:text="DELETE"
android:layout_centerVertical="true"/>
使用上述更改,您的删除将正常工作
答案 1 :(得分:0)
首先,请提供自定义数组适配器的完整代码,其中布局会膨胀。
其次, Row.xml 中的以下属性不适合此处。
android:onClick="deleteItemH"
只有当您直接从您的活动(Click here获取更多详细信息)来展开视图时,该功能才有效。您应该在自定义数组适配器中对 btnDelete 使用 setOnClickListener 。
再次,在查看自定义数组适配器后,可以提供更多帮助。