1

我遇到了 ListActivity 的问题。我扩展了 ArrayAdapter 和 Overridden getView 来填充每一行的数据。我将适配器的 ArrayList 中的一些数据放入 TextView。

我的问题是,当我滚动时,每行的 TextView 都会填充不在 ArrayList 中相应数据中的文本。我的意思是:假设我的列表顶部有一排 TextView 填充了空字符串。如果我在列表的底部并看到一行 TextView 填充了“bob”并且我轻拂以滚动到顶部,则顶部的行现在可能在其 TextView 中有“bob”,但数据位于我的 ArrayList 的索引不包含“bob”。它包含空字符串(实际上为空)。如果我继续上下滚动,其他行将填充(或擦除)与适配器的 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;
}
4

2 回答 2

2

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

尝试向该块添加一个 else 语句,将 textview 设置为空字符串。

像这样:

// 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("");
}

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

于 2010-08-18T18:41:31.390 回答
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 的成员传递。(我没有尝试编译或运行它,所以它可能需要一些调整)

于 2010-08-18T15:16:58.330 回答