Android 从附加到SQLite的Listview中删除ListItem
[GIF OF ACTIVITY][1]您在问题中提到的解决问题的方法不正确。 用下面的解决方案提到这个问题 问题1 您应该使用自定义适配器,而不是使用基本的ArrayAdapter ItemAdapter.classAndroid 从附加到SQLite的Listview中删除ListItem,android,listview,android-sqlite,android-arrayadapter,Android,Listview,Android Sqlite,Android Arrayadapter,[GIF OF ACTIVITY][1]您在问题中提到的解决问题的方法不正确。 用下面的解决方案提到这个问题 问题1 您应该使用自定义适配器,而不是使用基本的ArrayAdapter ItemAdapter.class public class ItemAdapter extends BaseAdapter { private final LayoutInflater layoutInflater; private ArrayList<ItemClass> ite
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);
}
}
}
从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"/>
使用上述更改,您的删除操作将正常运行首先,请提供布局正在膨胀的自定义阵列适配器的完整代码 其次,Row.xml中的以下属性不适合这里
android:onClick="deleteItemH"
只有当您直接从活动中扩大视图时,这才有效(有关更多详细信息)。您应该在自定义阵列适配器中为btnDelete使用setOnClickListener
同样,在查看自定义阵列适配器后,可以提供更多帮助。deleteItemH(视图)View Get received是您要删除的行吗?这就是我试图解决的问题,到目前为止,当单击“删除”按钮时,会反复删除列表中的第一个项目。请发布整个活动代码,以便我可以方便地查看您调用deleteItemH方法的位置?更改公共静态最终字符串DB_COLUMN=“item”;至DB_列=“_Id”。我在我的上这样做了,一切都可以开箱即用。通过您的修复,我得到了:NullPointerException:尝试在空对象引用上调用虚拟方法“java.lang.CharSequence android.widget.TextView.getText()。感谢您的帮助!请分享完整的活动代码,这样我就可以在我身边调试它了。希望这个解决方案能对你有所帮助。如果有任何问题,请返回thx。嗨!很抱歉延迟回复。我已经实现了我们的解决方案,但出现了以下错误:java.lang.RuntimeException:无法启动活动组件信息{tech.destinum.listapp/tech.destinum.listapp.MainActivity}:android.database.sqlite.SQLiteException:没有这样的列:_id(代码1):,编译时:SELECT Item,_id FROM list您只需清除应用程序的缓存并重新安装即可。在您的实现中,您将其命名为ID而不是_ID。谢谢。
<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>
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);
}
}
}
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;
}
}
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);
}
}
}
public class ItemClass {
public final long _id;
public final String detail;
public ItemClass(long id, String detail) {
_id = id;
this.detail = detail;
}
}
<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"/>
android:onClick="deleteItemH"