使用列表视图和自定义文本视图适配器滚动会中断排序



我有一个绑定到列表视图的自定义适配器。这部分很好。当我滚动列表视图时,排序被抛弃,因为如果我滚动回开头(即向下滚动后向上滚动),显示的文本视图不是第一个。滚动过程中我必须在适配器中处理一些事情吗?

public class TextViewAdapter extends BaseAdapter 
{
    private Context context;
    public TextViewAdapter(Context c) 
    {
        context = c;
    }
    //---returns the number of images---
    public int getCount() {
        return textViews.size();
    }
    //---returns the ID of an item--- 
    public Object getItem(int position) {
        return position;
    }
    public long getItemId(int position) {
        return position;
    }
    //---returns an TextView---
    public View getView(int position, View convertView, ViewGroup parent) 
    {
        TextView tv;
        Log.d("Position",  Integer.toString(position));
        if (convertView == null) {
            tv = (TextView)textViews.get(position);
        } else {
            tv = (TextView) convertView;
        }            
        return tv;
    }
}

您以错误的方式实现getView方法。如果您使用该convertView则应重置其文本内容,例如

public View getView(int position, View convertView, ViewGroup parent) 
{
    TextView tv;
    Log.d("Position",  Integer.toString(position));
    if (convertView == null) {
        tv = (TextView)textViews.get(position);
    } else {
        tv = (TextView) convertView;
        // HERE, set its content
        tv.setText(textViews.get(position).getText().toString());
    }            
    return tv;
}

ListView将在滚动时为您回收子视图,因此有些子视图不可见,从而变得可重用。这就是为什么每个convertView一开始都是空的,但当ListView向下滚动时,它不会变成空。但是那些不为空convertView仍然保留其原始文本内容,您应该手动重置其内容。

顺便说一句,当应用程序启动时,您不需要添加新的TextView,只需列出String就可以了,例如

/* somewhere else */
List<String> strings = ...
public class TextViewAdapter extends BaseAdapter 
{
    /* ... */
    //---returns the number of images---
    public int getCount() {
        return strings.size();
    }
    /* ... */
    //---returns an TextView---
    public View getView(int position, View convertView, ViewGroup parent) 
    {
        TextView tv;
        Log.d("Position",  Integer.toString(position));
        if (convertView == null) {
            tv = new TextView(context);
            tv.setText(strings.get(position));
        } else {
            tv = (TextView) convertView;
            // HERE, set its content
            tv.setText(strings.get(position));
        }            
        return tv;
    }
}

您将遇到的一个主要问题是,您正在尝试保存对适配器使用的视图的引用:

tv = (TextView)textViews.get(position);

问题是您正在与适配器中的回收商竞争,这将产生不可预测的结果......简而言之,你不能这样做。请观看 Android 开发人员的 World of ListView 以获取更多信息。

简而言之,您应该更改您的方法,以便适配器保留文本视图将显示的字符串列表,而不是文本视图本身。

如果convertView为空,则应重新充气视图,否则您需要重置convertView上的数据。

最新更新