ListView回收问题

时间:2013-10-24 20:46:42

标签: android listview android-listview convertview

我在使用ListView和我的自定义适配器时出现问题,因此在点击某个项目时会获得错误的位置。

基本上,当单击项目时,适配器中项目的名称将被发送到不同的活动,并且在滚动之前它可以正常工作。但是,任何仅在滚动时显示的项目都不会发送正确的位置;它似乎在滚动之前为视图中的项目发送了相应的位置(这对于视图回收是有意义的。)

这个ListView可能没有很多项目,所以如果可以禁用视图回收它应该不是一个大问题,但是我宁愿解决问题所以我可以滚动并获取发送的正确位置。

我是一个非常新的Android开发人员,这是我制作的第一个应用程序,所以我从在线教程中获得了这个自定义适配器,所以如果看起来有点奇怪就道歉。

public View getView(final int position, View convertView, ViewGroup parent) {

    ViewHolder holder = null;
    Log.v("ConvertView", String.valueOf(position));

    if (convertView == null) {
        LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = vi.inflate(R.layout.country_info, null);

        holder = new ViewHolder();
        holder.item = ((TextView)convertView.findViewById(R.id.infoBox));
        convertView.setTag(holder);

                holder.item.setOnClickListener(new View.OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        Country country = countryList.get(position);                        
                        String s = (String)(country.getName());
                        Intent i = new Intent(SecondScreenActivity.this, ThirdScreenActivity.class);
                        i.putExtra("position", s);
                        startActivity(i);
                    }
                });

            } else {
                holder = (ViewHolder) convertView.getTag();
            }

            Country country = countryList.get(position);
            holder.item.setText(country.getName());
            holder.favourite.setChecked(country.isSelected());
            holder.favourite.setTag(country);

            return convertView;

        }

注意:此代码可能缺失/在此处有一些额外的括号,因为此方法还会检查项目是否已选中/取消选中复选框,并且我删除了该代码以便更轻松地解决此问题。

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

适配器中的视图正在重复用于列表中的不同项目,因此它们不够可靠,无法完成您要执行的操作。尝试在您正在使用的活动中的listView上设置监听器。

    listView.setOnItemClickListener(new OnItemClickListener()
    {
        public void onItemClick(AdapterView<?> parent, View view, int position, long id)
        {
                  Country country = (Country) listView.getAdapter().getItem(position);                        
                    String s = (String)(country.getName());
                    Intent i = new Intent(SecondScreenActivity.this, ThirdScreenActivity.class);
                    i.putExtra("position", s);
                    startActivity(i);
        }
    });

答案 1 :(得分:0)

我的两分钱是因为当convertView为null时你只设置OnClickListener它只会记住所述视图的初始绑定 final int position ,只有当它最初是从布局创建时,不是在它被回收之后。

尝试在 if {} 块之外设置它,以便它绑定视图的当前位置,无论它是否被回收。

if (convertView == null) {
    LayoutInflater vi = (LayoutInflater)
                        getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    convertView = vi.inflate(R.layout.country_info, null);

    holder = new ViewHolder();
    holder.item = ((TextView)convertView.findViewById(R.id.infoBox));
    convertView.setTag(holder);
} else {
    holder = (ViewHolder) convertView.getTag();
}
holder.item.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View v) {
        Country country = countryList.get(position);                        
        String s = (String)(country.getName());
        Intent i = new Intent(SecondScreenActivity.this, 
                              ThirdScreenActivity.class);
        i.putExtra("position", s);
        startActivity(i);
    }
});

这个,差不多。