Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Android之微信朋友圈UI实现--ExpandableListView+GridView

Android之微信朋友圈UI实现--ExpandableListView+GridView

作者头像
cMusketeer
发布于 2018-08-01 02:53:07
发布于 2018-08-01 02:53:07
1.3K00
代码可运行
举报
文章被收录于专栏:Android机器圈Android机器圈
运行总次数:0
代码可运行

PS:我们都知道微信,更是知道朋友圈,很多人在朋友圈里卖起了化妆品,打入广告等为自己做一下推广,里面会附带一写好看的图片,上面有标题,有描述,整体布局每场的美观,那么这是怎么实现的呢,有些人可能会单个使用ListView,也会使用GridView,那么listview嵌套gridview你使用过吗,现在先看一张图,

这张图是不是很熟悉,没错这个就是朋友圈,里面有一个,里面的布局我都画出来了,我不知道微信具体怎么实现的,但是我们会用安卓原生的方法去实现这样的布局,并有实实在在的数据。

思路:

首页这是一个可以滑动的view,但是分为标题(用户名)和内容,并且内容下面还有图片,图片也是不确定的。这里就用ExpandableListView+GridView,如果有人不了解这个ExpandableListView的话,看完这篇基本用法就会了。

步骤:

  1. 总布局的创建,里面只要一个ExpandableListView控件。
  2. ExpandableListView的item布局创建,本布局用最传统的做法分为Group和Child布局。
    1. Group布局只显示一个用户名
    2. Child布局就要为描述内容和GridView(存放图片)。
  3. ExpandableListView适配器创建。
  4. 数据加载。

查看效果图,这个图在上传的时候压缩了就变的模糊了,请谅解。

1: 总布局的创建,里面只要一个ExpandableListView控件。

这里文件非常简单,只有一个控件,当然ExpandableListView也是有很多属性的。这里都没有写,去掉箭头,在Activity中动态添加。这里布局文件我都省去了根布局LinearLayout。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 <ExpandableListView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/id_elv"/>

2:ExpandableListView的item布局创建,本布局用最传统的做法分为Group和Child布局

2.1:这个就比较多了文件,首先来写一下Group的布局,名字你随便起,我这里叫grouplayout.xml

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<ImageView
        android:id="@+id/id_group_img"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:src="@mipmap/ic_launcher"/>
    <TextView
        android:id="@+id/id_group_name"
        android:layout_width="wrap_content"
        android:layout_height="40dp"
        android:gravity="center"
        android:textSize="40px"
        android:layout_marginLeft="10dp"
        android:text="name"/>

2.2:其次是Child的布局,名字也是随便起,我这里叫childlayout.xml

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<TextView
        android:id="@+id/id_dec"
        android:layout_width="wrap_content"
        android:layout_height="40dp"
        android:gravity="center"
        android:textSize="35px"
        android:layout_marginLeft="10dp"
        android:text="describe"/>
    <GridView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:numColumns="3"
        android:id="@+id/id_gv"></GridView>

2.3:还有一个布局文件,那就是GridView的item布局

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<ImageView
        android:id="@+id/id_img"
        android:src="@mipmap/ic_launcher"
        android:layout_width="match_parent"
        android:layout_margin="20dp"
        android:layout_height="100dp" />

3:ExpandableListView适配器创建

适配器的创建才是重点,首先我们对ExpandableListView自定义适配器,然后再在里面嵌套一个GridView的自定义适配器,当然你也可以调用系统的,不过个人觉得自定义有更好的灵活性。在这之前呢,我们需要创建几个bean类,group里有img图片和text文字,child有text文字和img图片数组。因为用户可能会多发几张照片,不光是一个。下面有两个class,稍微看一下就Ok了,不用太在意非要一样。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package mus.cn.shopeffect;
/**
 * Created by cMusketeer on 18/5/23.
 *
 * @author 刘志通
 */

public class GroupBean {
    String groupImg,name;

    public String getGroupImg() {
        return groupImg;
    }

    public void setGroupImg(String groupImg) {
        this.groupImg = groupImg;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import java.util.List;

/**
 * Created by cMusketeer on 18/5/23.
 *
 * @author 刘志通
 */

public class ChildBean {
    public String childDesc;
    public List<String> childImg;

    public String getChildDesc() {
        return childDesc;
    }

    public void setChildDesc(String childDesc) {
        this.childDesc = childDesc;
    }

    public List<String> getChildImg() {
        return childImg;
    }

    public void setChildImg(List<String> childImg) {
        this.childImg = childImg;
    }
}

创建Adapter,首先我们要继承adapter,这里和以前的就不一样了,我们要继承BaseExpandableListAdapter,当你继承后,系统就会让你重写里面的方法,方法有很多,不用全部,有如下几个就行了(有的小伙伴系统提示的全部继承,还缺一个)。

3.1:方法作用详情(没有先后顺序,古无序号)

首先定义变量(这里listChild为什么list里泛型还是list,我在Activity中解释)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  public Context context;
    public List<GroupBean> listGroup;
    public List<List<ChildBean>> listChild;

组Group(父)的长度

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 @Override
    public int getGroupCount() {
        return listGroup.size();
    }

某个组中child(子)的长度

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 @Override
    public int getChildrenCount(int groupPosition) {
        return listChild.get(groupPosition).size();
    }

拿到父的项

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 @Override
    public Object getGroup(int groupPosition) {
        return listGroup.get(groupPosition);
    }

拿到组(父)中子的项

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 @Override
    public Object getChild(int groupPosition, int childPosition) {
        return listChild.get(groupPosition).get(childPosition);
    }

拿到父、子id

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

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

组和子元素是否持有稳定的ID。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Override
    public boolean hasStableIds() {
        return false;
    }

 返回值:如果当前适配器不包含任何数据则返回True。经常用来决定一个空视图是否应该被显示。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Override
    public boolean isEmpty() {
        return false;
    }
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
子项是否可以选中
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }

3.2:补充:这里还有一些方法,你如果是没有用的话,就不用写。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public abstract void onGroupCollapsed (int groupPosition)
当组收缩状态的时候此方法被调用。
参数: groupPosition 收缩状态的组索引
public abstract void onGroupExpanded(int groupPosition)
当组展开状态的时候此方法被调用。

3.3:下面才是重点,分别是getGroupView和getChildView用来显示视图。具体看注释。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
图片加载库Glide依赖:compile 'com.github.bumptech.glide:glide:3.7.0'
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        ViewHoldeGroup viewHoldeGroup;
        if (convertView == null) {//没有视图时创建
            convertView = LayoutInflater.from(context).inflate(R.layout.grouplayout, null);//添加布局文件
            viewHoldeGroup = new ViewHoldeGroup();//创建holder对象
            viewHoldeGroup.imageView = (ImageView) convertView.findViewById(R.id.id_group_img);//拿到控件
            viewHoldeGroup.textView = (TextView) convertView.findViewById(R.id.id_group_name);
            convertView.setTag(viewHoldeGroup);
        } else {
            viewHoldeGroup = (ViewHoldeGroup) convertView.getTag();
        }//这里我用的Glide框架,用来加载网络图片的。
        Glide.with(context).load(listGroup.get(groupPosition).getGroupImg()).asBitmap().into(viewHoldeGroup.imageView);
        viewHoldeGroup.textView.setText(listGroup.get(groupPosition).getName());
        return convertView;
    }

    class ViewHoldeGroup {
        ImageView imageView;
        TextView textView;
    }

    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        ViewHoldeChild viewHoldeChild;
        GVAdapter gvAdapter;
        if (convertView == null) {
            convertView = LayoutInflater.from(context).inflate(R.layout.childlayout, null);
            viewHoldeChild = new ViewHoldeChild();
            viewHoldeChild.gridView = (GridView) convertView.findViewById(R.id.id_gv);
            viewHoldeChild.textView = (TextView) convertView.findViewById(R.id.id_dec);
            convertView.setTag(viewHoldeChild);
        } else {
            viewHoldeChild = (ViewHoldeChild) convertView.getTag();
        }
        viewHoldeChild.textView.setText(listChild.get(groupPosition).get(childPosition).getChildDesc());
        gvAdapter = new GVAdapter(context, listChild.get(groupPosition).get(childPosition).getChildImg());//适配器
        viewHoldeChild.gridView.setAdapter(gvAdapter);
        return convertView;
    }

    class ViewHoldeChild {
        TextView textView;
        GridView gridView;
    }

到这里呢我们可以看到Gridview的适配器,写在了ExpandableListView适配器的里面,数据还是一样的传递。GridView的适配器我就不写了,太简单,写上代码量就大了。

4:数据加载

4.1:Activity中最后一步,下面有解释。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 //添加组数据
        List<GroupBean> listGroup = new ArrayList<>();
        GroupBean groupBean;
        for (int i = 0; i < 10; i++) {
            groupBean = new GroupBean();
            groupBean.setGroupImg("https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1116338067,147640299&fm=27&gp=0.jpg");
            groupBean.setName("测试");
            listGroup.add(groupBean);
        }
        //添加组中子的数据,这里我解释一下list嵌套list,比如说一共是10个组,每个组里有一个子项目,每个子项目中又有2个图片
        List<List<ChildBean>> listChild = new ArrayList<>();
        List<ChildBean> list;//子的数据
        List<String> liImg;//子中图片的数据
        ChildBean childBean;
        for (int i = 0; i < 10; i++) {
            list = new ArrayList<>();
            for (int j = 0; j < 1; j++) {
                childBean = new ChildBean();
                liImg = new ArrayList<>();
                for (int k = 0; k < 2; k++) {//图片加载
                    liImg.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1527344951394&di=6dc7f379165a02c45e8df43106dbb153&imgtype=0&src=http%3A%2F%2Fimg.sc115.com%2Fuploads%2Fsc%2Fjpgs%2F1407%2Fapic4833_sc115.com.jpg");
                }
                childBean.setChildImg(liImg);
                childBean.setChildDesc("我是一个描述,我在图片的上面");
                list.add(childBean);//添加到子中
            }
            listChild.add(list);
        }

        ExpandableAdapter expandableAdapter = new ExpandableAdapter(this, listGroup, listChild);
        lv.setAdapter(expandableAdapter);
        //默认展开
        if (expandableAdapter != null) {
            for (int i = 0; i < listGroup.size(); i++) {
                lv.expandGroup(i);
            }
        }
        //去除箭头
        lv.setGroupIndicator(null);

List<List<ChildBean>>解释,红色的是组,里面的是子,每个组里不一定有几个子(这里画了两个)。

 完

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-05-27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
android expandablelistview横向,expandableListView 总结[通俗易懂]
expandableListView groupIndicator 图片默认是在左边,而且比较难看,而我要的是实现groupIndicator 在右边自定义图片,
全栈程序员站长
2022/07/05
4890
android expandablelistview横向,expandableListView 总结[通俗易懂]
ExpandableListView实例
demo中有三个group item和多个child item,group item包括一个指示器,一个标题和一个按钮。child item包括一个图片,一个标题和一个按钮。先来实现布局文件 1 activity_main.xml
全栈程序员站长
2022/09/07
1.4K0
可折叠列表ExpandableListView多级选择
上一期学习了AutoCompleteTextView和MultiAutoCompleteTextView,你已经掌握了吗?本期开始学习ExpandableListView的使用。 一、认识ExpandableListView ExpandableListView 是 ListView 的子类,它在普通ListView的基础上进行了扩展,它把应用中的列表项分为几组,每组里又可包含多个列表项。 ExpandableListView的用法与普通 ListView的用法非常相似,只是 Exp
分享达人秀
2018/02/05
2.6K0
可折叠列表ExpandableListView多级选择
ExpandableListView简单应用及listview模拟ExpandableListView
  首先我们还是来看一些案例,还是拿搜狐新闻客户端,因为我天天上下班没事爱看这个东东,上班又没时间看新闻,上下班路途之余浏览下新闻打发时间嘛. 看这个效果挺棒吧,其实实现起来也不难,我简单说明下.
xiangzhihong
2018/01/30
1.3K0
ExpandableListView简单应用及listview模拟ExpandableListView
工具栏,底部导航栏,可扩展列表视图
这个概念,所接触的很多开发软件或工具,都会碰到。在手机开发的时候,可以进行导航、显示相应的标题等,使开发者不至于在应用程序中迷路。5.0使用Actionbar来实现,很多公司都会对该类进行定制,使用起来更加灵活。5.0之后使用Toolbar来取代之前的Actionbar,这个更加强大。
张哥编程
2024/12/19
1690
站在巨人的肩膀上---重新自定义 android- ExpandableListView 收缩类,实现列表的可收缩扩展
林冠宏-指尖下的幽灵
2018/01/03
1.7K0
站在巨人的肩膀上---重新自定义 android- ExpandableListView 收缩类,实现列表的可收缩扩展
A022-列表容器之ExpandableListView
概述 本节课介绍Android中可实现二级可展开收缩列表的ExpandableListView容器,笔者感觉它非常难用并且难理解,很多时候我们可能需要对控件进行扩展和定制,然而它不太方便扩展,它使用难
巫山老妖
2018/07/20
9440
android 伸缩控件ExpandableListView 展开失败的可能原因。
本文介绍了ExpandableListView在Android中的使用,以及遇到的问题和解决方案。作者通过实例详细讲解了ExpandableListView的使用方法和注意事项,对于ExpandableListView的使用具有一定的指导意义。
林冠宏-指尖下的幽灵
2018/01/03
9200
android 伸缩控件ExpandableListView  展开失败的可能原因。
重走Android路之挑几个基本控件玩玩(上卷)
Android为我们提供了很多UI样式,但是在实际开发中,我们往往会根据UI图去为我们选择的绝大部分的控件进行渲染,从而达到产品更加的美观。
贺biubiu
2019/06/11
6680
Android开发笔记(一百)折叠式列表
经常看朋友圈的动态,有的动态内容较多就只展示前面一段,如果用户想看完整的再点击展开,这样整个页面的动态列表比较均衡,不会出现个别动态占用大片屏幕的情况。同样,查看博客的文章列表也类似,只展示文章开头几行内容,有需要再点击加载全篇文章。 动态列表直接使用ListView,动态内容就得自己写个控件了,自定义控件的难点在于如何把握动态下拉和收起的动画。这里我们要先预习TextView的相关函数,下面是本文用到的方法说明: getHeight : 获取TextView的显示高度。 setHeight : 设置TextView的显示高度。 getLineHeight : 获取每行文本的高度。 getLineCount : 获取所有文本的行数。 如果一开始每条动态默认显示四行,那么默认显示高度是getLineHeight*4,使用setHeight方法即可设置动态的初始显示高度。点击展开动态全文时,就得显示所有行的文本,整个文本的高度是getLineHeight*getLineCount。现在有了每条动态的初始高度,以及动态全文的完整高度,再加个拉伸动画就差不多了。拉伸动画的主要工作是随着时间的推移,给TextView设置渐增或渐减的高度,这要重写Animation的applyTransformation方法。 下面是点击监听器的显示动画代码示例:
aqi00
2019/01/18
2.3K0
Android仿淘宝购物车,玩转电商购物车
前言 其实做一个电商购物车,还真不是一个轻松的活。但是只要掌握思路,一步一步来做,就会发现也就这样。废物不多说,直接上效果图 完整代码,github链接,希望能给个星,谢谢 效果图 GIF1.gif
用户2032165
2018/06/05
2.9K0
【Android从零单排系列二十二】《Android视图控件——GridView》
小伙伴们,在上文中我们介绍了Android视图组件ExpandableListView,本文我们继续盘点,介绍一下视图控件的GridView。
再见孙悟空_
2023/07/17
6430
ExpandableListView实现商品列表折叠
简介 在日常的开发中,有可能会遇到需要一些可以展开的列表,比如QQ的好友列表,电商的购物车折叠显示。Android也给我们提供ExpandableListView类,完美实现这样类似的需求, 极大的方
xiangzhihong
2018/01/26
1.6K0
Android实现商城购物车功能
最近公司项目做商城模块,需要实现购物车功能,主要实现了单选、全选,金额合计,商品删除,商品数量加减等能,先看看效果图:
SoullessCoder
2019/08/07
4.6K0
Android实现商城购物车功能
相关推荐
android expandablelistview横向,expandableListView 总结[通俗易懂]
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档