Android 实现优惠卷二级list

首先说说数据源

{
    "data": [{
        "id": 3,
        "tname": "【成人票】小七孔门票1+划船+小吃",
        "desc": "正常门票,划船项目,各种小吃饮料",
        "price": "150.00",
        "marketp": "198.00",
        "couponinfo": [{
            "id": 3,
            "cname": "荔波景区专属--现金优惠券30元",
            "desc": "荔波景区专属--现金优惠券30元",
            "type": 1,
            "price": 30,
            "start": "2018-12-27",
            "end": "2019-01-11",
            "limit": 1,
            "cash": 2,
            "fullprice": null
        }, {
            "id": 4,
            "cname": "元旦优惠来就打折--8折优惠券",
            "desc": "元旦优惠来就打折--8折优惠券",
            "type": 2,
            "price": 8,
            "start": "2018-12-31",
            "end": "2019-01-12",
            "limit": 1,
            "cash": 1,
            "fullprice": null
        }, {
            "id": 5,
            "cname": "黄果树春节活动--满350立减50",
            "desc": "黄果树春节活动--满350立减50",
            "type": 3,
            "price": 50,
            "start": "2019-01-01",
            "end": "2019-02-28",
            "limit": 1,
            "cash": null,
            "fullprice": 300
        }]
    }, {
        "id": 6,
        "tname": "【成人票】小七孔门票+茂兰风景区门票",
        "desc": "【成人票】小七孔门票+茂兰风景区门票",
        "price": "200.00",
        "marketp": "299.00",
        "couponinfo": [{
            "id": 5,
            "cname": "黄果树春节活动--满350立减50",
            "desc": "黄果树春节活动--满350立减50",
            "type": 3,
            "price": 50,
            "start": "2019-01-01",
            "end": "2019-02-28",
            "limit": 1,
            "cash": null,
            "fullprice": 300
        }]
    }],
    "msg": "获取成功",
    "code": 1
}

看到数据源为两个listjson数组

效果为这样

布局中定义

首先,我们需要在xml的布局文件中声明ExpandableListView:

<ExpandableListView
    android:id="@+id/detail_page_lv_comment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:divider="@null"
    android:layout_marginBottom="64dp"
    android:listSelector="@android:color/transparent"
    android:scrollbars="none"/>

这里需要说明两个问题:

  1. ExpandableListView默认为它的item加上了点击效果,由于item里面还包含了childItem,所以,点击后,整个item里面的内容都会有点击效果。我们可以取消其点击特效,避免其影响用户体验,只需要设置如上代码中的listSelector即可。
  2. ExpandableListView具有默认的分割线,可以通过divider属性将其隐藏。

正如使用listView那样,我们需要为ExpandableListView设置一个适配器Adapter,为其绑定数据和视图。ExpandableListView的adapter需要继承自ExpandableListAdapter,具体代码如下:

/**
 * Author: Moos
 * E-mail: [email protected]
 * Date:  18/4/20.
 * Desc: 评论与回复列表的适配器
 */

public class CommentExpandAdapter extends BaseExpandableListAdapter {
    private static final String TAG = "CommentExpandAdapter";
    private List<CommentDetailBean> commentBeanList;
    private Context context;

    public CommentExpandAdapter(Context context, List<CommentDetailBean> commentBeanList)               {
        this.context = context;
        this.commentBeanList = commentBeanList;
    }

    @Override
    public int getGroupCount() {
        return commentBeanList.size();
    }

    @Override
    public int getChildrenCount(int i) {
        if(commentBeanList.get(i).getReplyList() == null){
            return 0;
        }else {
            return commentBeanList.get(i).getReplyList().size()>0 ? commentBeanList.get(i).getReplyList().size():0;
        }

    }

    @Override
    public Object getGroup(int i) {
        return commentBeanList.get(i);
    }

    @Override
    public Object getChild(int i, int i1) {
        return commentBeanList.get(i).getReplyList().get(i1);
    }

    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return getCombinedChildId(groupPosition, childPosition);
    }

    @Override
    public boolean hasStableIds() {
        return true;
    }
    boolean isLike = false;

    @Override
    public View getGroupView(final int groupPosition, boolean isExpand, View convertView, ViewGroup viewGroup) {
        final GroupHolder groupHolder;

        if(convertView == null){
            convertView = LayoutInflater.from(context).inflate(R.layout.comment_item_layout, viewGroup, false);
            groupHolder = new GroupHolder(convertView);
            convertView.setTag(groupHolder);
        }else {
            groupHolder = (GroupHolder) convertView.getTag();
        }
        Glide.with(context).load(R.drawable.user_other)
                .diskCacheStrategy(DiskCacheStrategy.RESULT)
                .error(R.mipmap.ic_launcher)
                .centerCrop()
                .into(groupHolder.logo);
        groupHolder.tv_name.setText(commentBeanList.get(groupPosition).getNickName());
        groupHolder.tv_time.setText(commentBeanList.get(groupPosition).getCreateDate());
        groupHolder.tv_content.setText(commentBeanList.get(groupPosition).getContent());
        groupHolder.iv_like.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(isLike){
                    isLike = false;
                    groupHolder.iv_like.setColorFilter(Color.parseColor("#aaaaaa"));
                }else {
                    isLike = true;
                    groupHolder.iv_like.setColorFilter(Color.parseColor("#FF5C5C"));
                }
            }
        });

        return convertView;
    }

    @Override
    public View getChildView(final int groupPosition, int childPosition, boolean b, View convertView, ViewGroup viewGroup) {
        final ChildHolder childHolder;
        if(convertView == null){
            convertView = LayoutInflater.from(context).inflate(R.layout.comment_reply_item_layout,viewGroup, false);
            childHolder = new ChildHolder(convertView);
            convertView.setTag(childHolder);
        }
        else {
            childHolder = (ChildHolder) convertView.getTag();
        }

        String replyUser = commentBeanList.get(groupPosition).getReplyList().get(childPosition).getNickName();
        if(!TextUtils.isEmpty(replyUser)){
            childHolder.tv_name.setText(replyUser + ":");
        }

        childHolder.tv_content.setText(commentBeanList.get(groupPosition).getReplyList().get(childPosition).getContent());

        return convertView;
    }

    @Override
    public boolean isChildSelectable(int i, int i1) {
        return true;
    }

    private class GroupHolder{
        private CircleImageView logo;
        private TextView tv_name, tv_content, tv_time;
        private ImageView iv_like;
        public GroupHolder(View view) {
            logo =  view.findViewById(R.id.comment_item_logo);
            tv_content = view.findViewById(R.id.comment_item_content);
            tv_name = view.findViewById(R.id.comment_item_userName);
            tv_time = view.findViewById(R.id.comment_item_time);
            iv_like = view.findViewById(R.id.comment_item_like);
        }
    }

    private class ChildHolder{
        private TextView tv_name, tv_content;
        public ChildHolder(View view) {
            tv_name = (TextView) view.findViewById(R.id.reply_item_user);
            tv_content = (TextView) view.findViewById(R.id.reply_item_content);
        }
    }

}
  • getGroupCount,返回group分组的数量,在当前需求中指代评论的数量。
  • getChildrenCount,返回所在group中child的数量,这里指代当前评论对应的回复数目。
  • getGroup,返回group的实际数据,这里指的是当前评论数据。
  • getChild,返回group中某个child的实际数据,这里指的是当前评论的某个回复数据。
  • getGroupId,返回分组的id,一般将当前group的位置传给它。
  • getChildId,返回分组中某个child的id,一般也将child当前位置传给它,不过为了避免重复,可以使用getCombinedChildId(groupPosition, childPosition);来获取id并返回。
  • hasStableIds,表示分组和子选项是否持有稳定的id,这里返回true即可。
  • isChildSelectable,表示分组中的child是否可以选中,这里返回true。
  • getGroupView,即返回group的视图,一般在这里进行一些数据和视图绑定的工作,一般为了复用和高效,可以自定义ViewHolder,用法与listview一样,这里就不多说了。
  • getChildView,返回分组中child子项的视图,比较容易理解,第一个参数是当前group所在的位置,第二个参数是当前child所在位置。

源码

猜你喜欢

转载自blog.csdn.net/qq_35224776/article/details/86131438