关于RecycleView 或List View多类型展示,展开和收起的适配

好记性不如烂笔头!

最在在开发中,有个需求,一个列表需要通过折叠收起和展开的样式展示数据,本人在开发中,使用的多类型的形式展示数据

适配器中开始写法:

//正常的Item
private static final int TYPE_NORMAL = 0;
//查看更多的 item类型
private static final int TYPE_SEE_MORE = 1;
//收起类型
private static final int TYPE_HIDE = 2;
//是否是展开状态 false 收起状态  true  展开状态
private boolean mOpen = false;
@Override
public int getCount() {
    if (mDataList.size() == 0) {
        return 0;
    }
    //mDataList.size > 2条 时  需要折叠
    if (mDataList.size() > 2) {
        //若现在是展开状态 条目数量需要+1 "收起"条目
        if (mOpen) {
            return mDataList.size() + 1 ;
        } else {
            //如果是 收起状态的话 条目为 normal 2条 + “展开更多” 条目
            return 3;
        }
    } else {
        return mDataList.size();
    }
}
@Override
public int getItemViewType(int position) {
    //mDataList.size <= 2条 时   不折叠 直接展示
    if (mDataList.size() <= 2) {
        return TYPE_NORMAL;
    }
    //mDataList.size >  2条 时   折叠 和展开
    if (mOpen) {
        //展开 时  最后一个 收起 按钮
        if (position == mDataList.size()) {
            return TYPE_HIDE;
        } else {
            //展开时 除了最后一个 其他都是正常的展示
            return TYPE_NORMAL;
        }
    } else {
        //收起 时 第三个时
        if (position == 2) {
            return TYPE_SEE_MORE;
        } else {
            return TYPE_NORMAL;
        }
    }
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    LogUtil.d("normalViewHolder  ", "count--" + getCount());
    int type = getItemViewType(position);
    LogUtil.d("normalViewHolder  ", "position" + position + "type--" + type);
    switch (type) {
        //展示正常的 Item
        case TYPE_NORMAL:
            NormalViewHolder normalViewHolder = null;
            if (convertView == null) {
                convertView = mContext.getLayoutInflater().inflate(R.layout.item_shop_normal, null);
                normalViewHolder = new NormalViewHolder(convertView);
                convertView.setTag(normalViewHolder);
            } 
                 normalViewHolder = (NormalViewHolder) convertView.getTag(); 
            }
            //加载数据 展示
            try{
                showNormalItem(normalViewHolder, position);
                addClickListen(normalViewHolder, position);
            }catch (Exception e){}

            break;
        //展示 收起按钮
        case TYPE_HIDE:
            convertView = mContext.getLayoutInflater().inflate(R.layout.item_shop_hide, null);
            AppCompatTextView mHideView = convertView.findViewById(R.id.hide);
            mHideView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mOpen = false;
                    notifyDataSetChanged();
                }
            });
            break;
        //展示 展开更多 按钮
        case TYPE_SEE_MORE:
            convertView = mContext.getLayoutInflater().inflate(R.layout.item_shop_see_more, null);
            AppCompatTextView seeMore = convertView.findViewById(R.id.see_more);
            seeMore.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mOpen = true;
                    notifyDataSetChanged();
                }
            });
            break;
        default:
            break;
    }
    return convertView;
}

适配器中主要代码已写完,可是在运行时,一切OK!点击展开的时候,崩了!!!! 为什么?????

经过debug发现,在getView方法中,在position = 2时,normalHolder是空的,为什么?

最终发现: 在第一运行展示的是收起状态,只展示3个Item,前两个是正常的Item,第三个是“展示更多”按钮,Item的状态不一样,故在点击展示更多的时候,在填充position =2 的时候,复用了之前对象池中的item,即是“展示更多”item,原本是需要展示normal类型下的item,所以出现了上述现像。

最终修改:

getVIew中 type为normal下的的代码:

//展示正常的 Item
case TYPE_NORMAL:
    NormalViewHolder normalViewHolder = null;
    if (convertView == null) {
        convertView = mContext.getLayoutInflater().inflate(R.layout.item_shop_normal, null);
        normalViewHolder = new NormalViewHolder(convertView);
        convertView.setTag(normalViewHolder);
    } else {
        if(convertView.getTag() == null){
            convertView = mContext.getLayoutInflater().inflate(R.layout.item_shop_normal, null);
            normalViewHolder = new NormalViewHolder(convertView);
            convertView.setTag(normalViewHolder);
        }else {
            normalViewHolder = (NormalViewHolder) convertView.getTag();
        }
    }

 

增加了判断,判断当前Holder是否为空,或者是是获取的Tag值是否和此Type下的Holder相等。

此处我只判断了是否为空,因为我在其他两种类型下没有使用ViewHolder,即没有设置Tag值。故在取值时时空的。

 

至此,该问题已解决!如有不对,请指出!  谢谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值