Android 从附加到SQLite的Listview中删除ListItem

Android 从附加到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

[GIF OF ACTIVITY][1]您在问题中提到的解决问题的方法不正确。 用下面的解决方案提到这个问题

问题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);
        }
    }
}
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"