Android之微信朋友圈UI实现--ExpandableListView+GridView
PS:我们都知道微信,更是知道朋友圈,很多人在朋友圈里卖起了化妆品,打入广告等为自己做一下推广,里面会附带一写好看的图片,上面有标题,有描述,整体布局每场的美观,那么这是怎么实现的呢,有些人可能会单个使用ListView,也会使用GridView,那么listview嵌套gridview你使用过吗,现在先看一张图,
这张图是不是很熟悉,没错这个就是朋友圈,里面有一个,里面的布局我都画出来了,我不知道微信具体怎么实现的,但是我们会用安卓原生的方法去实现这样的布局,并有实实在在的数据。
思路:
首页这是一个可以滑动的view,但是分为标题(用户名)和内容,并且内容下面还有图片,图片也是不确定的。这里就用ExpandableListView+GridView,如果有人不了解这个ExpandableListView的话,看完这篇基本用法就会了。
步骤:
- 总布局的创建,里面只要一个ExpandableListView控件。
- ExpandableListView的item布局创建,本布局用最传统的做法分为Group和Child布局。
- Group布局只显示一个用户名
- Child布局就要为描述内容和GridView(存放图片)。
- ExpandableListView适配器创建。
- 数据加载。
查看效果图,这个图在上传的时候压缩了就变的模糊了,请谅解。
1: 总布局的创建,里面只要一个ExpandableListView控件。
这里文件非常简单,只有一个控件,当然ExpandableListView也是有很多属性的。这里都没有写,去掉箭头,在Activity中动态添加。这里布局文件我都省去了根布局LinearLayout。
<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
<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
<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布局
<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了,不用太在意非要一样。
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;
}
}
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中解释)
public Context context;
public List<GroupBean> listGroup;
public List<List<ChildBean>> listChild;
组Group(父)的长度
@Override
public int getGroupCount() {
return listGroup.size();
}
某个组中child(子)的长度
@Override
public int getChildrenCount(int groupPosition) {
return listChild.get(groupPosition).size();
}
拿到父的项
@Override
public Object getGroup(int groupPosition) {
return listGroup.get(groupPosition);
}
拿到组(父)中子的项
@Override
public Object getChild(int groupPosition, int childPosition) {
return listChild.get(groupPosition).get(childPosition);
}
拿到父、子id
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
} @Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
组和子元素是否持有稳定的ID。
@Override
public boolean hasStableIds() {
return false;
}
返回值:如果当前适配器不包含任何数据则返回True。经常用来决定一个空视图是否应该被显示。
@Override
public boolean isEmpty() {
return false;
}
子项是否可以选中
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
3.2:补充:这里还有一些方法,你如果是没有用的话,就不用写。
public abstract void onGroupCollapsed (int groupPosition)
当组收缩状态的时候此方法被调用。
参数: groupPosition 收缩状态的组索引
public abstract void onGroupExpanded(int groupPosition)
当组展开状态的时候此方法被调用。
3.3:下面才是重点,分别是getGroupView和getChildView用来显示视图。具体看注释。
图片加载库Glide依赖:compile 'com.github.bumptech.glide:glide:3.7.0'
@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中最后一步,下面有解释。
//添加组数据
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>>解释,红色的是组,里面的是子,每个组里不一定有几个子(这里画了两个)。
完
Android之微信朋友圈UI实现--ExpandableListView+GridView的更多相关文章
- Android 仿微信朋友圈添加图片
github地址(欢迎下载Demo) https://github.com/zhouxu88/WXCircleAddPic 老习惯,先上图,着急用的朋友,直接带走Demo,先拿来用吧,毕竟老板催的紧, ...
- 试用友盟SDK实现Android分享微信朋友圈
社会化分享是眼下必学且火热的功能.之前有写第三方登录,那仅仅是社会化分享的一部分.今天来玩玩分享微信朋友圈. 为了方便操作,还是依照步骤写. 一,注冊 注冊应用已经在这里具体说明过了,这里就不多提了. ...
- Android 仿微信朋友圈发动态功能(相册图片多选)
代码分享 代码名称: 仿微信朋友圈发动态功能(相册图片多选) 代码描述: 仿微信朋友圈发动态功能(相册图片多选) 代码托管地址: http://www.apkbus.com/android-15276 ...
- Android 仿微信朋友圈发表图片拖拽和删除功能
朋友圈实现原理 我们使用 Android Device Monitor 来分析朋友圈发布图片的界面实现原理.如果需要分析其他应用的界面实现也是采用这种方法哦. 打开 Android Device Mo ...
- Android仿微信朋友圈,全文收起功能,附源码
在众多的社交类软件中,朋友圈是必不可少的,可以与好友.同学等分享自己的日常和有意思的事情,在开发社交类App时,朋友圈发表的内容你不可能让他全部显示,全部显示的话用户体验度会非常不好,这时就要用到全文 ...
- Android 仿微信朋友圈拍小视频上传到服务器
这个接上一个写的实现拍小视频和传到服务器的 界面是这个样子滴. 我也知不知道怎么给图片搞小一点o(╯□╰)o 布局文件是这样的[认真脸] <?xml version="1.0&quo ...
- Android 仿微信朋友圈查看
项目要做一个类似于这样的功能,就做了. 项目下载地址:http://download.csdn.net/detail/u014608640/9917626 一,看下效果: 二.activity类 pu ...
- (转载) listview实现微信朋友圈嵌套
listview实现微信朋友圈嵌套 标签: androidlistview 2016-01-06 00:05 572人阅读 评论(0) 收藏 举报 分类: android(8) 版权声明:本文为博 ...
- Android 高仿微信朋友圈动态, 支持双击手势放大并滑动查看图片。
转载请注明出处:http://blog.csdn.net/sk719887916/article/details/40348873 作者skay: 最近参与了开发一款旅行APP,其中包含实时聊天和动态 ...
随机推荐
- 【转载】解决nginx负载均衡的session共享问题
https://blog.csdn.net/u012081441/article/details/71787164 之前有写过ubuntu环境下搭建nginx环境,今天来谈一下nginx sessio ...
- python做量化交易干货分享
http://www.newsmth.NET/nForum/#!article/Python/128763 最近程序化交易很热,量化也是我很感兴趣的一块. 国内量化交易的平台有几家,我个人比较喜欢用的 ...
- linux下安装apc
wget htdtp://pecl.php.net/get/APC tar zxvf APC-3.1.3p.tgz cd APC-3.1.3p /usr/local/php/bin/phpize ./ ...
- 建站记录:设置apache .htaccess文件给网站添加404错误处理页面
有些空间服务商会在后台设置中,提供这个选项,可以直观地设置404错误指向的页面,这一点很方便,比如我之前用的阿里云虚拟主机就可以在控制台直接设置. 新租用的香港主机后台没有找到选取文件的地方,只是可以 ...
- 如何利用Python网络爬虫抓取微信朋友圈的动态(上)
今天小编给大家分享一下如何利用Python网络爬虫抓取微信朋友圈的动态信息,实际上如果单独的去爬取朋友圈的话,难度会非常大,因为微信没有提供向网易云音乐这样的API接口,所以很容易找不到门.不过不要慌 ...
- 微信小程序入门一
基本的准备工作 -知识储备 --基础:HTML+JS+CSS --进阶:React.Vue -工具安装 --工具由微信官方提供 ---下载地址:https://github.com/zce/weapp ...
- 适合Python的5大练手项目, 你练了么?
在练手项目的选择上,还存在疑问?不知道要从哪种项目先下手? 首先有两点建议: 最好不要写太应用的程序练手,要思考什么更像是知识,老只会写写爬虫是无用的,但是完全不写也不行. 对于练手的程序,要注意简化 ...
- Django入门四之数据库相关
1. 数据库设置 在settings.py中配置数据库 我首先使用的是sqlite3,所以配置如下 2. 数据库的数据结构定义 #blog/models.py #定义了一个表(Student),表里两 ...
- PAT1037:Magic Coupon
1037. Magic Coupon (25) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue The magi ...
- 2017年的golang、python、php、c++、c、java、Nodejs性能对比[续]
2017年的golang.python.php.c++.c.java.Nodejs性能对比[续] 最近忙,这个话题放了几天,今天来个续集. 上篇传送门: 2017年的golang.python.p ...