与 ListView 战斗
Posted
技术标签:
【中文标题】与 ListView 战斗【英文标题】:Fighting with ListView 【发布时间】:2015-09-27 19:46:34 【问题描述】:我的应用程序的一个片段中有一个ListView
,还有一个按钮。
按钮显示一个对话框,显示一些CheckBoxes
供用户选择他/她希望将哪些添加到ListView
。
这行得通,当用户单击checkBox
时,该项目被添加到列表中,但是如果我单击所有checkBoxes
,ListView
中的最后一个项目将获得第一个的文本一。
这是我的适配器:
public class ListaTributosAdapter extends BaseAdapter
private ArrayList<ListaTributosBean> data;
private LayoutInflater inflater=null;
public ListaTributosAdapter(Context c, ArrayList<ListaTributosBean> data)
this.data=data;
inflater=LayoutInflater.from(c);
@Override
public int getCount()
return data.size();
@Override
public Object getItem(int position)
return data.get(position);
@Override
public long getItemId(int position)
return position;
@Override
public View getView(int position, View convertView, ViewGroup parent)
if (convertView == null)
convertView=inflater.inflate(R.layout.celda_listview_tributos, null);
TextView texto=(TextView)convertView.findViewById(R.id.textView4);
texto.setText(data.get(position).getTexto());
return convertView;
ListaTributosBean
是一个只有一个 TextView
和一个 ImageView
的类,此时未使用。
这就是我设置适配器的方式,我有一个 Strings
和一个 ArrayList
数组来存储用户使用
复选框:
private String[] opciones="A", "B", "C", "D", "E";
private ArrayList<ListaTributosBean> datos;
我将适配器设置为 ListView:
adapter=new ListaTributosAdapter(c, datos);
listView.setAdapter(adapter);
我在 ArrayList 中添加了两个强制项:
datos.add(new ListaTributosBean("Mandatory1"));
datos.add(new ListaTributosBean("Mandatory2"));
当用户单击一个按钮时,会显示带有 checkBoxes 的 Dialog:
button.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(getString(R.string.selectcheckboxes));
builder.setMultiChoiceItems(opciones, null, new DialogInterface.OnMultiChoiceClickListener()
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked)
for (int i = 0; i < datos.size(); i++)
if (datos.get(i).getTexto().equals(opciones[which]))
Toast.makeText(c, getString(R.string.contains1) + " " + opciones[which] + " " + getString(R.string.contains2), Toast.LENGTH_LONG).show();
repe = true;
if (repe == true)
repe = false;
else
if (isChecked)
datos.add(new ListaTributosBean(opciones[which]));
);
builder.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener()
@Override
public void onClick(DialogInterface dialog, int which)
adapter.notifyDataSetChanged();
try
dialog.dismiss();
catch (Exception e)
).create().show();
);
如果我点击一个checkBox
,没问题。我点了两个checkBoxes,没问题。
但如果我检查所有五个 checkBoxes,ListView
中的最后一项会得到第一个的文本,尽管我点击它,然后做
String selected = ((ListaTributosBean) parent.getItemAtPosition(position)).getTexto();
它返回正确的值。
ListView
中的其余项目看起来不错,并且在单击时响应正常。
为什么会这样?
谁能帮帮我?
谢谢。
【问题讨论】:
首先你的getView实现是错误的......如果你只使用1个textview然后把它作为标签到convertView......就像TextView txt = null; if (convertView == null) /*old code here (without setText)*/ txt = (TextView)convertView.findViewById(R.id.textView4); convertView.setTag(txt); else txt = (TextView)convertView.getTag(); txt.setText(data.get(position).getTexto());
......如果你正在使用更多的意见使用持有人pattern ...接下来看看ArrayAdapter ...有一个Filter实现
【参考方案1】:
这个错误是因为您没有遵循Adapter
中的ViewHolder
设计模式。现在执行以下操作
添加下面的类作为你的Adapter
的内部类
static class ViewHolder
public TextView texto;
并将适配器的 getView()
方法替换为以下内容
@Override
public View getView(int position, View convertView, ViewGroup parent)
ViewHolder holder;
if (convertView == null)
convertView = inflater.inflate(R.layout.celda_listview_tributos, null);
holder = new ViewHolder();
holder.texto = (TextView) convertView.findViewById(R.id.textView4);
convertView.setTag(holder);
else
holder = (ViewHolder) convertView.getTag();
holder.texto.setText(data.get(position).getTexto());
return convertView;
【讨论】:
它现在工作正常。谢谢!我需要阅读 ViewHolder 模式,我一直在做没有它的适配器。是时候阅读了:)以上是关于与 ListView 战斗的主要内容,如果未能解决你的问题,请参考以下文章