从附加到SQLite的Listview中删除ListItem

时间:2017-01-03 21:23:08

标签: android listview android-sqlite android-arrayadapter

[活动的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>

2 个答案:

答案 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

再次,在查看自定义数组适配器后,可以提供更多帮助。