为什么BaseAdapter getview将我的数据混合在行中?

时间:2013-06-03 13:22:18

标签: android android-view android-adapter

我正在使用BaseAdapter来自定义我的listview

public View getChildView(int groupPosition, int childPosition,
                boolean isLastChild, View view, ViewGroup parent) {
            if (view == null) {
                LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                view = inflater.inflate(R.layout.products_item, null);
            }

            FileBean file = (FileBean) ((ExtendedList) (Object) categories.get(groupPosition)).getItem(childPosition);

            CheckBox checkBox = (CheckBox) view.findViewById(R.id.fileCheckBox);
            if(checkBox != null){
                if(mCheckBoxListener != null){
                    checkBox.setOnCheckedChangeListener(mCheckBoxListener);
                }
                checkBox.setChecked(file.isChecked());
                Log.d("getcview", String.valueOf(file.isChecked() + " " + file.getName() 
                        + " " + groupPosition + " "  + childPosition));
            }

            setProductDetails(file, view);

            ViewHolder holder = new ViewHolder();
            holder.groupPosition = groupPosition;
            holder.childPosition = childPosition;
            Log.d("exadapter", "Child " + file.getName());

            view.setTag(holder);
            return view;
        }

3 个答案:

答案 0 :(得分:1)

您的问题与滚动列表视图时回收视图的事实有关。您必须在每次复选框的正确值时重置(已选中或未选中)。

您正在执行此操作,但是您的订单错误,每次重置选中/未选中复选框时都会触发OnCheckListener(首先设置侦听器,然后更改复选框值)。

  1. 删除OnCheckListener
  2. 设置复选框值
  3. 再次添加您的听众
  4. 正确的顺序:

    checkBox.setOnCheckedChangeListener(null);
    checkBox.setChecked(file.isChecked());
    checkBox.setOnCheckedChangeListener(mCheckBoxListener)
    

答案 1 :(得分:0)

在baseadapter类中重写这两个方法:

@Override
    public int getViewTypeCount() {

        if (getCount() != 0)
            return getCount();

        return 1;
    }

    @Override
    public int getItemViewType(int position) {

        return position;
    }

看看它是否有效。

答案 2 :(得分:0)

我看到两个问题,

1 - 将你的LayoutInflater移出getView方法,你在那里创造了大量的垃圾。而是创建一个实例变量来存储LayoutInflater,并在适配器的构造函数中创建它。 (这与混合btw无关。)

private LayoutInflater mInflater; //instance variable

public CustomAdapter(Context context, List<Item> items) {
    //some code
    mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

2 - 您正在每次调用getView()时创建ViewHolder实例。 移动此代码:

ViewHolder holder = new ViewHolder();
holder.groupPosition = groupPosition;
holder.childPosition = childPosition;
Log.d("exadapter", "Child " + file.getName());
view.setTag(holder);

在converview的null检查中。您只想在converView为null时(仅在新视图上)创建新的ViewHolder。

public View getChildView(int groupPosition, int childPosition,
            boolean isLastChild, View view, ViewGroup parent) {
    //First, get the Tag from the converView
    ViewHolder mHolder = (ViewHolder) view.getTag();
    //Now check if the holder is null, rather than checking if the convertView is null.
    if (mHolder == null) {
        //init the holder code
        view.setTag(mHolder);  //only set the Tag if it's a new view.
    }

此外,您使用ViewHolder模式的方式有误,您应该使用ViewHolder来存储CheckBox,这样您就不必在每次getView调用时都调用findViewById(R.id.fileCheckBox);

希望有所帮助。