首先说说数据源

{
    "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:

这里需要说明两个问题:

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

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

/** * Author: Moos * E-mail: moosphon@gmail.com * Date:  18/4/20. * Desc: 评论与回复列表的适配器 */public class CommentExpandAdapter extends BaseExpandableListAdapter {    private static final String TAG = "CommentExpandAdapter";    private List commentBeanList;    private Context context;    public CommentExpandAdapter(Context context, List 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所在位置。

源码:https://download.csdn.net/download/qq_35224776/10905410

微信关注 “安卓集中营”,获取更多

或者扫码关注

一起共同学习探讨

更多相关文章

  1. 【转】Android大图片裁剪终极解决方案 原理分析
  2. Android(安卓)API Demo研究(3)
  3. Android——QQ登录、分享
  4. 接着归纳Android(安卓)from 《第一行代码》
  5. Android悬浮按钮点击返回顶部FloatingActionButton
  6. Android中启动其他Activity并返回结果
  7. Android开发中的单元测试-初级教程(01)
  8. Retrofit 2.0使用详解,配合OkHttp、Gson,Android最强网络请求框架
  9. 一行代码实现Android右滑返回

随机推荐

  1. Android Training - 运行你的程序
  2. Android res/raw文件;raw与res/assets异
  3. Android 6.0 运行时权限的处理
  4. katalon设置Android(安卓)SDK路径
  5. Android studio 入门笔记
  6. Android OOBE开发
  7. 【Android】动态注册广播接收器
  8. .net平台借助第三方推送服务在推送Androi
  9. React Native Android白屏优化终极方案
  10. Android中发送短信等普通方法