我的列表视图上的删除按钮无法正常工作
Posted
技术标签:
【中文标题】我的列表视图上的删除按钮无法正常工作【英文标题】:Delete button on my listview is not working as it is supposed to 【发布时间】:2021-07-08 05:33:02 【问题描述】:所以我想在列表的每个项目上都有一个删除按钮,这样当按下该按钮时,我希望完全删除该特定列表项。但是,当我尝试这样做时,它不起作用。此外,如果我两次单击删除图标,应用程序就会崩溃。 这是我的列表适配器的代码:
package com.example.taskmasterv3;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.ArrayList;
public class SubtaskAdapter extends ArrayAdapter<subtask>
private final Context context;
private ArrayList<subtask> values;
public SubtaskAdapter(Context context, ArrayList<subtask> list)
//since your are using custom view,pass zero and inflate the custom view by overriding getview
super(context, 0 , list);
this.context = context;
this.values = list;
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent)
//check if its null, if so inflate it, else simply reuse it
if (convertView == null)
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.subtask_item, parent, false);
//use convertView to refer the childviews to populate it with data
TextView tvSubtaskName = convertView.findViewById(R.id.tvSubtaskName);
ImageView ivPri = convertView.findViewById(R.id.ivPri);
ImageView ivTime = convertView.findViewById(R.id.ivTime);
ImageView ivDelete = convertView.findViewById(R.id.ivDelete);
tvSubtaskName.setText(values.get(position).getSubtaskName());
if (values.get(position).isPriHigh())
ivPri.setImageResource(R.drawable.priority_high);
else if (values.get(position).isPriMed())
ivPri.setImageResource(R.drawable.priority_med);
else if (values.get(position).isPriLow())
ivPri.setImageResource(R.drawable.priority_low);
if (values.get(position).isTimeMore())
ivTime.setImageResource(R.drawable.time_symbol_more);
else if (values.get(position).isTimeMed())
ivTime.setImageResource(R.drawable.time_symbol_med);
else if (values.get(position).isTimeLess())
ivTime.setImageResource(R.drawable.time_symbol_less);
// Delete button for subtasks (NOT WORKING)
ivDelete.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
values.remove(position);
notifyDataSetChanged();
);
//return the view you inflated
return convertView;
//to keep adding the new subtasks try the following
public void addANewSubTask(subtask newSubTask)
ArrayList<subtask> newvalues = new ArrayList<>(this.values);
newvalues.add(newSubTask);
this.values = newvalues;
notifyDataSetChanged();
【问题讨论】:
removeAt 对你有用吗? 我没有看到任何这样的选项。我看到的是 remove、removeAll、removeIf。我正在使用安卓工作室... 【参考方案1】:将values.remove(position);
更改为values.remove(values.get(position));
【讨论】:
是的,现在似乎已修复,但我现在面临的问题是删除按钮会自动删除列表的最后一项,而不是我想要删除的特定项目。有什么解决办法吗?【参考方案2】:由于继续创建 OnClickListener 并使用 findViewById() 解析视图 ID,以这种方式使用 ListView 非常糟糕并且内存很重。 侵入性较小的解决方案是使用缓存所有 View ID 和 ClickListener 的 ViewHolder:
public class SubtaskAdapter extends ArrayAdapter<subtask>
private final LayoutInflater mLayoutInflater;
public SubtaskAdapter(@NonNull final Context context, @NonNull final List<subtask> values)
super(context, R.layout.subtask_item, values);
this.mLayoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
private static class ViewHolder
private int mPosition = -1;
private final TextView tvSubtaskName;
private final ImageView ivPri;
private final ImageView ivTime;
private final ImageView ivDelete;
private final View.OnClickListener mOnClickListener;
private ViewHolder(@NonNull final ArrayAdapter<subtask> arrayAdapter, @NonNull final View convertView)
this.tvSubtaskName = convertView.findViewById(R.id.tvSubtaskName);
this.ivPri = convertView.findViewById(R.id.ivPri);
this.ivTime = convertView.findViewById(R.id.ivTime);
this.ivDelete = convertView.findViewById(R.id.ivDelete);
this.mOnClickListener = new View.OnClickListener()
@Override
public void onClick(final View v)
arrayAdapter.remove(arrayAdapter.getItem(ViewHolder.this.mPosition));
arrayAdapter.notifyDataSetChanged();
;
this.ivDelete.setOnClickListener(this.mOnClickListener);
private void setPosition(final int position) this.mPosition = position;
@Override
public View getView(final int position, @Nullable View convertView, @NonNull final ViewGroup parent)
final View cParentView = super.getView(position, convertView, parent);
if (cParentView != null) return cParentView;
ViewHolder holder;
if (convertView == null)
convertView = this.mLayoutInflater.inflate(R.layout.subtask_item, parent, false);
holder = new ViewHolder(this, convertView);
convertView.setTag(holder);
else
holder = (ViewHolder)convertView.getTag();
holder.setPosition(position);
final subtask cCurrentSubtask = getItem(position);
holder.tvSubtaskName.setText(cCurrentSubtask.getSubtaskName());
if (cCurrentSubtask.isPriHigh())
holder.ivPri.setImageResource(R.drawable.priority_high);
else if (cCurrentSubtask.isPriMed())
holder.ivPri.setImageResource(R.drawable.priority_med);
else if (cCurrentSubtask.isPriLow())
holder.ivPri.setImageResource(R.drawable.priority_low);
if (cCurrentSubtask.isTimeMore())
holder.ivTime.setImageResource(R.drawable.time_symbol_more);
else if (cCurrentSubtask.isTimeMed())
holder.ivTime.setImageResource(R.drawable.time_symbol_med);
else if (cCurrentSubtask.isTimeLess())
holder.ivTime.setImageResource(R.drawable.time_symbol_less);
return convertView;
您不需要使用内部“值”来保存所有项目,您可以使用“ArrayAdapter.add()”和其他类似方法(remove()、getItem()、getCount() 等)在您创建 ArrayAdapter 并传递初始 Items Array/List 之后。
编辑:要将项目添加到 ArrayAdapter,您需要保存 ArrayAdapter 实例,然后调用其“add()”方法。
public class MainActivity extends Activity
...
@Nullable
private SubtaskAdapter mSubtaskAdapter = null;
@Override
protected void onCreate(@Nullable final Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSubtaskAdapter = new SubtaskAdapter(this, subtask_items);
private boolean addSubtaskToList(@Nullable final subtask newSubtask)
if ((mSubtaskAdapter == null) || (newSubtask == null)) return false;
mSubtaskAdapter.add(newSubtask);
return true;
【讨论】:
感谢您的建议。但是我在当前代码中实现这一点时遇到了麻烦。我还是编程新手。你能帮我一下吗 另外,删除功能仍然不适合我 我在答案中添加了最终评论。您不需要 ArrayAdapter 中的“值”,但您可以通过传递初始 Array/List 来创建 ArrayAdapter,然后使用它自己的 add()、addAll()、remove()、getCount()、getItem() 等... 方法(ArrayAdapter 本身使用内部 ArrayList以上是关于我的列表视图上的删除按钮无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章
应用于字幕表视图单元格的 UITableViewAutomaticDimension 无法正常工作