失控的ListView

时间:2010-08-18 15:13:05

标签: android listview scroll listviewitem listactivity

我遇到了ListActivity的问题。我已经扩展了ArrayAdapter和Overridden getView来填充每行的数据。我将Adapter的ArrayList中的一些数据抛出到TextView中。

我的问题是,当我滚动时,每行的TextView会填充不在ArrayList中相应数据中的文本。我的意思是:说我的列表顶部有一行用一个填充了emptystring的TextView。如果我在列表的底部并看到一行填充了带有“bob”的TextView并且我轻弹以滚动到顶部,则顶部的行现在可能在其TextView中具有“bob”,但是数据位于我的ArrayList的索引不包含“bob”。它包含emptystring(实际上为null)。如果我继续向上和向下滚动,其他行将使用与Adapter的ArrayList中的内容不对应的数据填充(或擦除)。

为了实现这一点,我不需要快速滚动ListView。但是,看起来我滚动得越快,行就越混乱。

这是我的代码。我知道每次调用getView时我都在使用findViewById,但这不是重点。我正在反对convertView;所以应该在每一行抓取正确的TextView,是吗?

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

    // get the View for this list item
    View v = convertView;
    if (v == null) {
        LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(R.layout.layout_mylistlist_item, null);
    }

    // get the next object
    MyListItem myItem = m_items.get(position);

    // set up the list item
    if (myItem != null) {
        TextView txtName = (TextView) v.findViewById(R.id.mylist_name);

        // set text
        if (txtName != null && myItem.getName() != null) {
            txtName.setText(myItem.getName());
        }
    }

   // return the created view
    return v;
}

2 个答案:

答案 0 :(得分:2)

我认为问题是你的if(myItem!= null)检查在底部。

尝试向该块添加else语句,将textview设置为emptystring。

像这样:

// set up the list item 
TextView txtName = (TextView) v.findViewById(R.id.mylist_name); 
if (myItem != null) {  
    // set text 
    if (txtName != null && myItem.getName() != null) { 
        txtName.setText(myItem.getName()); 
    } else
    {
        txtName.setText("");
    }
} 
else
{
    txtName.setText("");
}

转换视图传递给您时,仍然会有旧数据。即使您的数据无效,您也需要故意覆盖它,否则它将保留其旧数据。

答案 1 :(得分:1)

交换此

if (v == null) {
        LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(R.layout.layout_mylistlist_item, null);
    }

用这个

if (v == null) {
        LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(R.layout.layout_mylistlist_item, parent, false);
    }

你必须将“false”传递给inflate(...)方法。

如果您有时间,请查看今年关于Android ListView的I / O会话:http://code.google.com/events/io/2010/sessions/world-of-listview-android.html

值得观看或至少滚动幻灯片。他们也在线。

根据您的反馈,让我提出一种使用ArrayAdapter绑定数据的方法。也许这解决了你的问题。

public class MyTestArrayAdapter extends ArrayAdapter<MyDataModel>{
   private final int resourceId;

   public MyTestArrayAdapter(Context context, int resourceId, List<MyDataModel> myDataModelList) {
      super(context, resourceId, myDataModelList);
      this.resourceId = resourceId;
   }

   @Override
   public View getView(int position, View convertView, ViewGroup parent) {
      if(convertView == null){
         LayoutInflater inflater = (LayoutInflater)getContext().getSystemService....
         convertView = inflater.inflate(resourceId, parent, false);
      }

      MyDataModel modelObj = getItem(position);

      TextView someDataView = convertView.findViewById(....);
      someDataView.setText(modelObj.getDataText());
      ...

      return convertView;
   }

}

我认为您不需要将数据作为ArrayAdapter的成员传递。 (我没有尝试编译也没有运行它,因此可能需要进行一些调整)