ListView 总是从 CustomAdaptor 中删除最后一行
Posted
技术标签:
【中文标题】ListView 总是从 CustomAdaptor 中删除最后一行【英文标题】:ListView always deletes last row from CustomAdaptor 【发布时间】:2020-02-05 23:10:09 【问题描述】:我在 AlertDialog 中有一个 ListView,每行包含更多按钮,它会弹出一个带有删除选项的列表。当我单击删除选项时,它会删除最后一项。在 CustomAdaptor 中,我在从 ArrayList 中删除项目后尝试了 notifyDataSetChanged()。在这里,无论项目位置如何,它总是删除最后一个项目。
自定义适配器代码
public class CustomAdapter extends BaseAdapter
Context context;
List<String> lrowItems ;
ArrayList<String> listItems;
String className;
CalHelper calHelper;
Settings settings;
LayoutInflater inflter;
public CustomAdapter(Context applicationContext, ArrayList<String> listItems)
this.context = applicationContext;
this.listItems = listItems;
this.className = context.getClass().getSimpleName();
this.calHelper = new CalHelper(applicationContext);
this.settings = new Settings(applicationContext);
inflter = (LayoutInflater.from(applicationContext));
@Override
public int getCount()
if(listItems != null)
return listItems.size();
else
return 0;
@Override
public Object getItem(int position)
return listItems.get(position);
@Override
public long getItemId(int position)
return position;
//With following overrides Prevent listview item will not mix randomly
//and convertView provided is of the appropriate type.
@Override
public int getViewTypeCount()
if(getCount() > 0) //for no records in returning view
return getCount();
else
return super.getViewTypeCount();
@Override
public int getItemViewType(int position)
return position;
/* private view holder class for holding calculation history*/
private class HistoryViewHolder
TextView more;
TextView expression;
TextView result;
TextView shortNote;
TextView expTime;
/* private view holder class for holding GST calculations history*/
private class GstHistoryViewHolder
TextView amount;
TextView gst;
TextView total;
TextView expTime;
ImageView share;
/* private view holder class */
private class BMIViewHolder
TextView bmiScore;
TextView bmiDate;
TextView bmiWeight;
@Override
public View getView(final int position, View convertView, ViewGroup viewGroup)
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
//final int pos = position;
if(className.equals("MainActivity"))
final HistoryViewHolder holder = new HistoryViewHolder();
final String expString = listItems.get(position);
final String expre = expString.substring(0, expString.indexOf(":"));
final String expreTime = expString.substring(expString.indexOf(":") + 1, expString.length());
final String result = expre.substring(expre.indexOf("=")+1);
String timePattern = calHelper.calHistoryTimePattern(expreTime);
SimpleDateFormat localDateFormat = new SimpleDateFormat(timePattern);
if (convertView == null)
convertView = mInflater.inflate(R.layout.listview_row, null);
holder.more = (TextView) convertView
.findViewById(R.id.more);
holder.expression = (TextView) convertView.findViewById(R.id.expression);
holder.result = (TextView) convertView.findViewById(R.id.result);
holder.shortNote = (TextView) convertView.findViewById(R.id.shortNote);
holder.expTime = (TextView) convertView.findViewById(R.id.expTime);
holder.expression.setText(expre.substring(0, expre.indexOf("=")));
holder.result.setText(result);
String time = localDateFormat.format(new Date(expreTime));
holder.expTime.setText(time);
holder.shortNote.setText(settings.getHistoryNote(context,expString));
convertView.setTag(holder);
final TextView btnMore = (TextView) holder.more;
btnMore.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
showPopup(v, position, expString, expre, expreTime, holder.shortNote);
);
return convertView;
public void showPopup(View v, final int position, final String expString, final String expression, final String expTime, final TextView shortNote)
final PopupMenu popup = new PopupMenu(context, v);
//truncate title with ellipsis for more characters
final String noteTitle = expression.length()>10? expression.substring(0, 10) + "..." : expression;
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.history_menu, popup.getMenu());
//registering popup with OnMenuItemClickListener
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener()
public boolean onMenuItemClick(MenuItem item)
Intent intent = new Intent(context, MainActivity.class);
int itenId = item.getItemId();
switch (itenId)
case R.id.mnuInsertExpression:
//some code here
break;
case R.id.mnuHisNote:
//some code here
break;
case R.id.mnuCopyHisRecord:
calHelper.copyToClipboard(expression);
break;
case R.id.mnuShareHisRecord:
calHelper.shareText(expression);
break;
case R.id.mnuDeleteHisRecord: //This is where I am deleting item
System.out.println("Pos:"+position);
listItems.remove(position);
notifyDataSetChanged();
Collections.reverse(listItems); //sort descending by time again
settings.clearSharedPre(context,expString); //remove note attached to this expression from ShredPref
settings.saveArrayList(context, listItems, "EXP_HISTORY");
intent.putExtra("HISTORY_RECORD_DELETED", true);
Toast.makeText(context,"Record removed from history", Toast.LENGTH_SHORT).show();
context.startActivity(intent);
break;
return true;
);
popup.show();
非常感谢任何帮助。
【问题讨论】:
【参考方案1】:试试这个 getView():
@Override
public View getView(int position, View convertView, ViewGroup viewGroup)
HistoryViewHolder holder;
if(className.equals("MainActivity"))
final String expString = listItems.get(position);
final String expre = expString.substring(0, expString.indexOf(":"));
final String expreTime = expString.substring(expString.indexOf(":") + 1, expString.length());
final String result = expre.substring(expre.indexOf("=")+1);
String timePattern = calHelper.calHistoryTimePattern(expreTime);
SimpleDateFormat localDateFormat = new SimpleDateFormat(timePattern);
if (convertView == null)
LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.listview_row, null);
holder = new HistoryViewHolder();
holder.more = (TextView) convertView.findViewById(R.id.more);
holder.expression = (TextView) convertView.findViewById(R.id.expression);
holder.result = (TextView) convertView.findViewById(R.id.result);
holder.shortNote = (TextView) convertView.findViewById(R.id.shortNote);
holder.expTime = (TextView) convertView.findViewById(R.id.expTime);
holder.more.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
int pos = (int) v.getTag();
showPopup(v, pos, expString, expre, expreTime, holder.shortNote);
);
else
holder = (HistoryViewHolder)convertView.getTag();
holder.expression.setText(expre.substring(0, expre.indexOf("=")));
holder.result.setText(result);
String time = localDateFormat.format(new Date(expreTime));
holder.expTime.setText(time);
holder.shortNote.setText(settings.getHistoryNote(context, expString));
holder.more.setTag(position);
convertView.setTag(holder);
return convertView;
希望有帮助!
【讨论】:
太棒了!!有用。 holder.more.setOnClickListene 给出了语法错误,我用原来的 btnMore.setOnClickListener 替换了它,但其余的都是按照你提到的方式。非常感谢。【参考方案2】:因为您使用的是 getView 参数的位置,所以在您使用它时,它始终是最后一个索引。
相反,您需要将该位置添加到视图中,可能在您的 convertView 中是我通常做的(标签可以是您想要的任何东西),在您创建每个项目视图时在 getView 方法中执行convertView.setTag(position)
,并且然后在 showpopup 中的删除方法中,您可以执行 (int)view.getTag()
以获取要从数据集中删除的位置。
【讨论】:
使用 setTag 和 getTag 无效。我得到了正确的视图位置,但它只删除了最后一项。我在 AlertDalog 中显示 ListView,这会对正常的列表视图/适配器功能产生任何影响。【参考方案3】:您应该使用setTag()
将postion
添加到button
,并在使用getTag()
将showPopup()
传递给position
时获取position
。您可以执行以下操作。
// ....
final TextView btnMore = (TextView) holder.more;
btnMore.setTag(position); // here add the position to the button using setTag().
btnMore.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
// here you can get position your button using v.getTag().
int pos = (int) v.getTag();
showPopup(v, pos, expString, expre, expreTime, holder.shortNote);
);
【讨论】:
这又是在删除最后一项。以上是关于ListView 总是从 CustomAdaptor 中删除最后一行的主要内容,如果未能解决你的问题,请参考以下文章