为什么getView返回错误convertView对象上SeparatedListAdapter? [英] Why does getView return wrong convertView objects on SeparatedListAdapter?

查看:184
本文介绍了为什么getView返回错误convertView对象上SeparatedListAdapter?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我适应了SeparatedListAdapter从杰夫·夏基我的需求,得到了这样的事情:

I adapted the SeparatedListAdapter from Jeff Sharkey to my needs and got something like this:

public class SeparatedListAdapter<T> extends BaseAdapter {

    @SuppressWarnings("unused")
    private final String LOG_TAG = getClass().getSimpleName();

    public final static int TYPE_SECTION_HEADER = 0;

    public final Map<T, Adapter> sectionAdapters;
    public final ArrayAdapter<T> headerAdapter;

    public SeparatedListAdapter(ArrayAdapter<T> headerAdapter) {
        super();
        this.sectionAdapters = new LinkedHashMap<T,Adapter>();
        this.headerAdapter = headerAdapter;
    }

    public void addSection(T section, Adapter adapter) {
        this.headerAdapter.add(section);
        this.sectionAdapters.put(section, adapter);
    }

    public void clearSections() {
        this.headerAdapter.clear();
        this.sectionAdapters.clear();
    }

    @Override
    public int getCount() {
        // total together all sections, plus one for each section header
        int total = 0;
        for(Adapter adapter : this.sectionAdapters.values())
            total += adapter.getCount() + 1;
        return total;
    }

    @Override
    public int getViewTypeCount() {
        //count headers, then total all sections
        int total = this.headerAdapter.getViewTypeCount();
        for(Adapter adapter : this.sectionAdapters.values())
            total += adapter.getViewTypeCount();
        return total;
    }

    @Override
    public int getItemViewType(int position) {
        int type = 1;
        for(Object section : this.sectionAdapters.keySet()) {
            Adapter adapter = sectionAdapters.get(section);
            int size = adapter.getCount() + 1;

            // check if position inside this section 
            if(position == 0) return TYPE_SECTION_HEADER;
            if(position < size) return type + adapter.getItemViewType(position - 1);

            // otherwise jump into next section
            position -= size;
            type += adapter.getViewTypeCount();

        }
        return -1;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        int sectionnum = 0;
        for(Object section : this.sectionAdapters.keySet()) {
            Adapter adapter = sectionAdapters.get(section);
            int size = adapter.getCount() + 1;

            // check if position inside this section 
            if(position == 0) 
                return headerAdapter.getView(sectionnum, convertView, parent);
            if(position < size) 
                return adapter.getView(position - 1, convertView, parent);

            // otherwise jump into next section
            position -= size;
            sectionnum++;
        }
        return null;
    }

    @Override
    public boolean areAllItemsEnabled() {
        return false;
    }

    @Override
    public boolean isEnabled(int position) {
        return (getItemViewType(position) != TYPE_SECTION_HEADER);
    }
}

我遇到的问题是,该API馈送从错误适配器onvertView对象getView(),导致的问题。我想我正确实施getViewTypeCount()和getItemViewType(),并检查与调试。还有什么能去哪里呢?

The problem I encountered is that the API feeds onvertView objects from the wrong adapter to getView(), leading to problems. I think I correctly implemented getViewTypeCount() and getItemViewType() and checked that with the debugger. What else could go wrong?

下面是我的适配器之一:

Here is one of my adapters:

public static class MeetingAdapter extends ArrayAdapter<Meeting> {
    static class ViewHolder {
        TextView title;
    }
    private LayoutInflater inflater;

    public MeetingAdapter(Activity context, List<Meeting> meetings) {
        super(context, 0, meetings);
        this.inflater = LayoutInflater.from(context);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Meeting meeting = getItem(position);

        View rowView = convertView;
        ViewHolder holder;

        // instanceof should not be necessary!!! normally convertView should be of the right type!
        if (rowView == null || !(rowView.getTag() instanceof ViewHolder)) {
            rowView = inflater.inflate(R.layout.list_item, null);
            holder = new ViewHolder();
            holder.title = (TextView)rowView; // tmp - layout contains only a textview for the moment
            rowView.setTag(holder);
        } else {
            holder = (ViewHolder)rowView.getTag();
        }
        holder.title.setText(meeting.getTrack());
        return rowView;
    }
}

帮助吗?越来越疯狂了这一点。

Help please? Getting crazy over this.

推荐答案

我跟踪这个问题是列表视图的RecybleBin对象。它存储基于其报告的类型从getItemViewType可能convertViews,但其内容永远不会更新您更改的数据集(这样的位置)之后,那么当你的适配器是否曾经被认为是一种X的看法基于其位置,但现在正好是一个类型为Y。 一个解决办法是手动检查getView还判定是否不仅convertView为空,但羯羊它是正确的类型(这真是尴尬,有时...如果你使用的视图持有人模式,你可以检查标签的相应viewholder类相匹配)

I traced the problem to be the listviews's RecybleBin object. It stores the possible convertViews based on their reported types from getItemViewType, however its contents are never updated after you change the dataset (thus positions), then when your adapter gets what used to be a type "X" view based on its position, but now it happens to be a type "Y". A solution is to manually check on getView wether not only the convertView is null, but wether it is of the correct type (that's really awkward sometimes... If you use the view holder pattern you could check if the tag matches your corresponding viewholder class)

这篇关于为什么getView返回错误convertView对象上SeparatedListAdapter?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆