好记性不如烂笔头!
最在在开发中,有个需求,一个列表需要通过折叠收起和展开的样式展示数据,本人在开发中,使用的多类型的形式展示数据
适配器中开始写法:
//正常的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值。故在取值时时空的。
至此,该问题已解决!如有不对,请指出! 谢谢!