ListView滚动问题

时间:2014-07-17 12:05:01

标签: android listview android-listview

这里有很多问题都有相同的标题。我仍然找不到解决方案。这就是我创建一个新原因的原因。 我有一个导航抽屉和ListView。我对此ListView上的项目有两个自定义视图:标题和正常。我通过考虑他们的位置来给出每个项目的视图,但是当我上下滚动时,视图会随机混合。我将变量保存在ViewHolder上。它不可能是一个解决方案。我的适配器如下:

    public class NavDrawerListAdapter extends BaseAdapter {

        private Context context;
        private ArrayList<NavDrawerItem> navDrawerItems;

        public NavDrawerListAdapter(Context context, ArrayList<NavDrawerItem> navDrawerItems) {
            this.context = context;
            this.navDrawerItems = navDrawerItems;
        }

        @Override
        public int getCount() {
            return navDrawerItems.size();
        }

        @Override
        public Object getItem(int position) {
            return navDrawerItems.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        private static class ViewHolder {
            public ImageView icon;
            public TextView title, count;
        }

@Override
    public int getViewTypeCount() {
        return 2;
    }

    @Override
    public int getItemViewType(int position) {
        return position % 2;
    }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View row = convertView;
            ViewHolder holder = new ViewHolder();

            if (row == null) {
                LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
                if (navDrawerItems.get(position).getType().equals("header")) {
                    row = mInflater.inflate(R.layout.drawer_list_item_header, null, false);
                } else {
                    row = mInflater.inflate(R.layout.drawer_list_item, null, false);
                }
            } else {
                holder = (ViewHolder) row.getTag();
            }

            holder.icon = (ImageView) row.findViewById(R.id.icon);
            holder.title = (TextView) row.findViewById(R.id.title);
            holder.count = (TextView) row.findViewById(R.id.counter);

            holder.icon.setImageResource(navDrawerItems.get(position).getIcon());
            holder.title.setText(navDrawerItems.get(position).getTitle());

            if (navDrawerItems.get(position).getCounterVisibility()) {
                holder.count.setText(navDrawerItems.get(position).getCount());
            } else {
                holder.count.setVisibility(View.GONE);
            }

            row.setTag(holder);

            return row;
        }

    }

4 个答案:

答案 0 :(得分:5)

我有同样的问题,当快速滚动时,它将某些项目的值交替给其他项目,就像某些项目的背景颜色随机变化一样。 我通过搜索解决了这个问题,如果在适配器中使用ViewHolder,那么找到确切的解决方案就是在适配器中添加这两种方法

@Override
    public int getViewTypeCount() {
        return getCount();
    }

    @Override
    public int getItemViewType(int position) {
        return position;
    }

答案 1 :(得分:1)

您的ListView's滚动是滞后的,因为

  

每次滚动时都会创建ViewHolder的对象   列表显示。所以,你的ViewHolder是没用的。

试试这段代码

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

        if (convertView == null) {
            LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
            if (navDrawerItems.get(position).getType().equals("header")) {
                convertView = mInflater.inflate(R.layout.drawer_list_item_header, null, false);
                holder = new ViewHolder();
                holder.icon = (ImageView) convertView.findViewById(R.id.icon);
                holder.title = (TextView) convertView.findViewById(R.id.title);
                holder.count = (TextView) convertView.findViewById(R.id.counter);
            } else {
                convertView = mInflater.inflate(R.layout.drawer_list_item, null, false);
                holder = new ViewHolder();
                holder.icon = (ImageView) convertView.findViewById(R.id.icon);
                holder.title = (TextView) convertView.findViewById(R.id.title);
                holder.count = (TextView) convertView.findViewById(R.id.counter);
            }
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }



        holder.icon.setImageResource(navDrawerItems.get(position).getIcon());
        holder.title.setText(navDrawerItems.get(position).getTitle());

        if (navDrawerItems.get(position).getCounterVisibility()) {
            holder.count.setText(navDrawerItems.get(position).getCount());
        } else {
            holder.count.setVisibility(View.GONE);
        }

        return convertView;
    }

答案 2 :(得分:0)

如果您在适配器中覆盖getViewTypeCount()getItemViewType(),它们就不会混合。

一旦这样做,您可以保证所提供的convertView属于合适的类型。

My ListView has two types of views. How to manage?

答案 3 :(得分:0)

我同意kaushik的回答,但convertView需要保留viewHolder而不是position,我已做出更改,请参阅代码..

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

    if (convertView == null) {
        holder = new ViewHolder();
        LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        if (navDrawerItems.get(position).getType().equals("header")) {
            convertView = mInflater.inflate(R.layout.drawer_list_item_header, null, false);
        } else {
            convertView = mInflater.inflate(R.layout.drawer_list_item, null, false);
        }
        holder.icon = (ImageView) convertView.findViewById(R.id.icon);
        holder.title = (TextView) convertView.findViewById(R.id.title);
        holder.count = (TextView) convertView.findViewById(R.id.counter);

        convertView.setTag(holder);  //as holder will be loaded at second iteration
    } else {
        holder = (ViewHolder) convertView.getTag();
    }
    holder.icon.setImageResource(navDrawerItems.get(position).getIcon());
    holder.title.setText(navDrawerItems.get(position).getTitle());

    if (navDrawerItems.get(position).getCounterVisibility()) {
        holder.count.setText(navDrawerItems.get(position).getCount());
    } else {
        holder.count.setVisibility(View.GONE);
    }

    return convertView;
}

希望它有所帮助!...