如何从 android 列表视图中删除多个选定项目并将其从适配器中删除?
How to delete multiple selected item from android listview and remove it from the adapter as well?
所以,我有一个列表视图和一个将数据填充到列表视图中的适配器。
列表项中的每一行都有一个复选框。片段中有一个按钮,允许使用其 ID 从数据库中删除选中的项目。
但是,我希望发生这种情况:
- 用户checks/unchecks他想删除的项目。
- 然后他单击片段上的删除多个项目按钮。
- 项目已从数据库中删除。
- 项目不再显示在列表视图中。即它们被删除了。
我已经完成了上述所有 3 个步骤。但我正在为最后一个而苦苦挣扎。单击图像按钮时,我可以从列表视图中删除单个项目,但问题出在多个项目上。
适配器代码:
public class ReqFoodAdapter extends BaseAdapter implements CompoundButton.OnCheckedChangeListener {
private Activity activity;
private ArrayList<HashMap<String, String>> data;
// the arraylist that holds the data of the checked items
private ArrayList<String> checkedList = new ArrayList<String>();
private static LayoutInflater inflater=null;
Bitmap image,receivedBitmap;
public ReqFoodAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
activity = a;
data=d;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// initializing each item in the arraylist
for(int i = 0; i < data.size(); i++ ){
checkedList.add(i,"0");
}
}
//method to return the arraylist to the fragment
public ArrayList<String> getCheckedList(){
return checkedList;
}
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View vi = convertView;
if(convertView == null)
vi = inflater.inflate(R.layout.list_row_req_food, null);
TextView fid = vi.findViewById(R.id.lv_req_id);
TextView name = vi.findViewById(R.id.item_name);
TextView qty = vi.findViewById(R.id.item_req_qty);
TextView ngoAdd = vi.findViewById(R.id.ngo_address);
TextView resName = vi.findViewById(R.id.ngoName);
ImageView type = vi.findViewById(R.id.type);
ImageView thumb_image = vi.findViewById(R.id.ngo_image);
ImageView btn_req_confirm = vi.findViewById(R.id.btn_req_confirm);
//checkbox in each row
CheckBox checkBox = vi.findViewById(R.id.chkThisRequest);
checkBox.setOnCheckedChangeListener(this);
HashMap<String, String> food = new HashMap<String, String>();
food = data.get(position);
checkBox.setTag(position + "," + food.get(FoodRequests.KEY_ID));
fid.setText(food.get(FoodRequests.KEY_ID));
name.setText(food.get(FoodRequests.KEY_NAME));
qty.setText(food.get(FoodRequests.KEY_REQ_QTY) + " kg");
ngoAdd.setText(food.get(FoodRequests.KEY_NGO_ADD));
resName.setText(food.get(FoodRequests.KEY_NGO_NAME));
if(food.get(FoodRequests.KEY_TYPE).equals("Veg"))
type.setImageResource(R.drawable.veg);
else if(food.get(FoodRequests.KEY_TYPE).equals("Non-Veg"))
type.setImageResource(R.drawable.non_veg);
btn_req_confirm.setTag(position + "," + food.get(FoodRequests.KEY_ID));
btn_req_confirm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String arrayTag[] = ((String) view.getTag()).split(",");
String key = arrayTag[1];
//Update the database using key here
int pos = Integer.parseInt(arrayTag[0]);
data.remove(pos);
ReqFoodAdapter.this.notifyDataSetChanged();
}
});
return vi;
}
// onchecked change of the checkbox, change the checkedList value to the id
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
String arrayTag[] = ((String) compoundButton.getTag()).split(",");
String key = arrayTag[1];
int pos = Integer.parseInt(arrayTag[0]);
if(b) {
checkedList.set(pos, key);
}else{
checkedList.set(pos,"0");
}
}
// method to remove item
public void removeItem(int index){
data.remove(ReqFoodAdapter.this.getItem(index));
}
public void updateListView(){
notifyDataSetChanged();
}
}
* 片段代码*:
public class FoodRequests extends Fragment {
public FoodRequests() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootview = inflater.inflate(R.layout.fragment_food_requests, container, false);
lvReqFood = rootview.findViewById(R.id.list_req_food);
arrListReqFood = new ArrayList<HashMap<String, String>>();
new LoadReqFood().execute();
btnConfirmAll = rootview.findViewById(R.id.btnConfirmAll);
// button confirm multiple reuqests
btnConfirMultiple = rootview.findViewById(R.id.btnConfirmMultiple);
return rootview;
}
private class LoadReqFood extends AsyncTask<String, String, String >{
ProgressDialog loadingRequests;
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
loadingRequests.dismiss();
adapter = new ReqFoodAdapter(getActivity(), arrListReqFood);
lvReqFood.setAdapter(adapter);
btnConfirMultiple.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// get the checked list
ArrayList<String> checkedList = adapter.getCheckedList();
try {
for (int i = 0; i < checkedList.size(); i++){
temp.put(String.valueOf(i + 1), checkedList.get(i));
}
joAllRequests.put("requests",temp.toString());
}catch (JSONException j){
j.printStackTrace();
}
// update the database using each of the id of the list
new UpdateRequest().execute();
}
});
}
}
private class UpdateRequest extends AsyncTask<String, String, String>{
String msg;
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Toast.makeText(getContext(), msg, Toast.LENGTH_SHORT).show();
ArrayList<String> checkedList = adapter.getCheckedList();
for (int i = 0; i < checkedList.size(); i++){
if(!checkedList.get(i).equals("0")) {
String arrayTag[] = checkedList.get(i).split(",");
int pos = Integer.parseInt(arrayTag[0]);
adapter.removeItem(pos);
}
}
adapter.updateListView();
}
}
}
因此,数据已加载,所选项目已更新,但当我希望从列表视图中删除该项目时,它会引发 ArrayIndexOutOfBound 异常。这是因为,当我从数据中删除一个项目时,它的位置会发生变化,而当我传递另一个项目以给定位置删除时,它会引发错误。
如何处理?
或者有更好的方法来解决我的问题吗?
为了避免位置变化的问题,只需将for循环的方向反转即可,所以代码如下:
ArrayList<String> checkedList = adapter.getCheckedList();
for (int i = checkedList.size() - 1; i => 0; i--){
if(!checkedList.get(i).equals("0")) {
String arrayTag[] = checkedList.get(i).split(",");
int pos = Integer.parseInt(arrayTag[0]);
adapter.removeItem(pos);
}
}
adapter.resetCheckedList();
adapter.updateListView();
检查列表也需要在删除项目后重置,因此可以像这样更改 adpater 的构造函数:
public ReqFoodAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
activity = a;
data=d;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
resetCheckedList();
}
public void resetCheckedList(){
checkedList.clear();
// initializing each item in the arraylist
for(int i = 0; i < data.size(); i++ ){
checkedList.add(i,"0");
}
}
希望对您有所帮助!
所以,我有一个列表视图和一个将数据填充到列表视图中的适配器。
列表项中的每一行都有一个复选框。片段中有一个按钮,允许使用其 ID 从数据库中删除选中的项目。
但是,我希望发生这种情况:
- 用户checks/unchecks他想删除的项目。
- 然后他单击片段上的删除多个项目按钮。
- 项目已从数据库中删除。
- 项目不再显示在列表视图中。即它们被删除了。
我已经完成了上述所有 3 个步骤。但我正在为最后一个而苦苦挣扎。单击图像按钮时,我可以从列表视图中删除单个项目,但问题出在多个项目上。
适配器代码:
public class ReqFoodAdapter extends BaseAdapter implements CompoundButton.OnCheckedChangeListener {
private Activity activity;
private ArrayList<HashMap<String, String>> data;
// the arraylist that holds the data of the checked items
private ArrayList<String> checkedList = new ArrayList<String>();
private static LayoutInflater inflater=null;
Bitmap image,receivedBitmap;
public ReqFoodAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
activity = a;
data=d;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// initializing each item in the arraylist
for(int i = 0; i < data.size(); i++ ){
checkedList.add(i,"0");
}
}
//method to return the arraylist to the fragment
public ArrayList<String> getCheckedList(){
return checkedList;
}
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View vi = convertView;
if(convertView == null)
vi = inflater.inflate(R.layout.list_row_req_food, null);
TextView fid = vi.findViewById(R.id.lv_req_id);
TextView name = vi.findViewById(R.id.item_name);
TextView qty = vi.findViewById(R.id.item_req_qty);
TextView ngoAdd = vi.findViewById(R.id.ngo_address);
TextView resName = vi.findViewById(R.id.ngoName);
ImageView type = vi.findViewById(R.id.type);
ImageView thumb_image = vi.findViewById(R.id.ngo_image);
ImageView btn_req_confirm = vi.findViewById(R.id.btn_req_confirm);
//checkbox in each row
CheckBox checkBox = vi.findViewById(R.id.chkThisRequest);
checkBox.setOnCheckedChangeListener(this);
HashMap<String, String> food = new HashMap<String, String>();
food = data.get(position);
checkBox.setTag(position + "," + food.get(FoodRequests.KEY_ID));
fid.setText(food.get(FoodRequests.KEY_ID));
name.setText(food.get(FoodRequests.KEY_NAME));
qty.setText(food.get(FoodRequests.KEY_REQ_QTY) + " kg");
ngoAdd.setText(food.get(FoodRequests.KEY_NGO_ADD));
resName.setText(food.get(FoodRequests.KEY_NGO_NAME));
if(food.get(FoodRequests.KEY_TYPE).equals("Veg"))
type.setImageResource(R.drawable.veg);
else if(food.get(FoodRequests.KEY_TYPE).equals("Non-Veg"))
type.setImageResource(R.drawable.non_veg);
btn_req_confirm.setTag(position + "," + food.get(FoodRequests.KEY_ID));
btn_req_confirm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String arrayTag[] = ((String) view.getTag()).split(",");
String key = arrayTag[1];
//Update the database using key here
int pos = Integer.parseInt(arrayTag[0]);
data.remove(pos);
ReqFoodAdapter.this.notifyDataSetChanged();
}
});
return vi;
}
// onchecked change of the checkbox, change the checkedList value to the id
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
String arrayTag[] = ((String) compoundButton.getTag()).split(",");
String key = arrayTag[1];
int pos = Integer.parseInt(arrayTag[0]);
if(b) {
checkedList.set(pos, key);
}else{
checkedList.set(pos,"0");
}
}
// method to remove item
public void removeItem(int index){
data.remove(ReqFoodAdapter.this.getItem(index));
}
public void updateListView(){
notifyDataSetChanged();
}
}
* 片段代码*:
public class FoodRequests extends Fragment {
public FoodRequests() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootview = inflater.inflate(R.layout.fragment_food_requests, container, false);
lvReqFood = rootview.findViewById(R.id.list_req_food);
arrListReqFood = new ArrayList<HashMap<String, String>>();
new LoadReqFood().execute();
btnConfirmAll = rootview.findViewById(R.id.btnConfirmAll);
// button confirm multiple reuqests
btnConfirMultiple = rootview.findViewById(R.id.btnConfirmMultiple);
return rootview;
}
private class LoadReqFood extends AsyncTask<String, String, String >{
ProgressDialog loadingRequests;
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
loadingRequests.dismiss();
adapter = new ReqFoodAdapter(getActivity(), arrListReqFood);
lvReqFood.setAdapter(adapter);
btnConfirMultiple.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// get the checked list
ArrayList<String> checkedList = adapter.getCheckedList();
try {
for (int i = 0; i < checkedList.size(); i++){
temp.put(String.valueOf(i + 1), checkedList.get(i));
}
joAllRequests.put("requests",temp.toString());
}catch (JSONException j){
j.printStackTrace();
}
// update the database using each of the id of the list
new UpdateRequest().execute();
}
});
}
}
private class UpdateRequest extends AsyncTask<String, String, String>{
String msg;
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Toast.makeText(getContext(), msg, Toast.LENGTH_SHORT).show();
ArrayList<String> checkedList = adapter.getCheckedList();
for (int i = 0; i < checkedList.size(); i++){
if(!checkedList.get(i).equals("0")) {
String arrayTag[] = checkedList.get(i).split(",");
int pos = Integer.parseInt(arrayTag[0]);
adapter.removeItem(pos);
}
}
adapter.updateListView();
}
}
}
因此,数据已加载,所选项目已更新,但当我希望从列表视图中删除该项目时,它会引发 ArrayIndexOutOfBound 异常。这是因为,当我从数据中删除一个项目时,它的位置会发生变化,而当我传递另一个项目以给定位置删除时,它会引发错误。
如何处理?
或者有更好的方法来解决我的问题吗?
为了避免位置变化的问题,只需将for循环的方向反转即可,所以代码如下:
ArrayList<String> checkedList = adapter.getCheckedList();
for (int i = checkedList.size() - 1; i => 0; i--){
if(!checkedList.get(i).equals("0")) {
String arrayTag[] = checkedList.get(i).split(",");
int pos = Integer.parseInt(arrayTag[0]);
adapter.removeItem(pos);
}
}
adapter.resetCheckedList();
adapter.updateListView();
检查列表也需要在删除项目后重置,因此可以像这样更改 adpater 的构造函数:
public ReqFoodAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
activity = a;
data=d;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
resetCheckedList();
}
public void resetCheckedList(){
checkedList.clear();
// initializing each item in the arraylist
for(int i = 0; i < data.size(); i++ ){
checkedList.add(i,"0");
}
}
希望对您有所帮助!