使用ExpandableListView以及如何优化view的显示减少内存占用
上篇博客讲到如何获取手机中所有歌曲的信息。本文就把上篇获取到的歌曲按照歌手名字分类。用一个ExpandableListView显示出来。
MainActivity .java
- public class MainActivity extends AppCompatActivity {
- private static List<MusicLoader.MusicInfo> musicList = new ArrayList<MusicLoader.MusicInfo>();
- private ExpandableListView groupLvSongs;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- initView();
- initEvent();
- }
- private void initEvent() {
- // 这是获取musicList,与本篇博客主题无关,大家只需要知道musicList代表所有歌曲,它的每一项都包含一首歌的所有信息
- musicList = MusicLoader.instance(getContentResolver()).getMusicList();
- // 设置适配器,给listview提供数据
- groupLvSongs.setAdapter(new myExadapter(MainActivity.this, musicList));
- }
- private void initView() {
- groupLvSongs = (ExpandableListView) findViewById(R.id.groupLvSongs);
- }
- /**
- * 按歌手分类的listview 对应的Adapter,自定义ExpandableListView的适配器
- * getGroupId()getChildId()hasStableIds()isChildSelectable暂时都默认自动生成的,
- * 最主要是getGroupView(),getChildView()方法
- */
- class myExadapter extends BaseExpandableListAdapter {
- //在获取view的时候需要context
- private Context context;
- //所有歌曲
- private List<MusicInfo> musicList = new ArrayList<MusicInfo>();
- //记录各个歌手名字
- private List<String> groupName = new ArrayList<String>();
- //按歌手名字分类后的所有歌曲
- private List<List<MusicInfo>> musicGroupBySinger = new ArrayList<List<MusicInfo>>();
- myExadapter(Context context, List<MusicInfo> group) {
- this.context = context;
- musicList = group;
- sortByArtistName();
- }
- // 根据歌手分类最终获得 musicGroupBySinger
- private void sortByArtistName() {
- // 第一个特殊
- groupName.add(musicList.get(0).getArtist());
- List<MusicInfo> musicListWithSameSinger = new ArrayList<MusicInfo>();
- musicListWithSameSinger.add(musicList.get(0));
- musicGroupBySinger.add(musicListWithSameSinger);
- for (int i = 1; i < musicList.size(); i++) {
- boolean flag = false;
- for (int j = 0; j < groupName.size(); j++) {
- // if该歌手名字已经存在
- if (musicList.get(i).getArtist().equals(groupName.get(j))) {
- flag = true;
- musicGroupBySinger.get(j).add(musicList.get(i));
- break;
- }
- }
- if (!flag) {
- groupName.add(musicList.get(i).getArtist());
- List<MusicInfo> musicListWithSameSinger2 = new ArrayList<MusicInfo>();
- musicListWithSameSinger2.add(musicList.get(i));
- musicGroupBySinger.add(musicListWithSameSinger2);
- }
- }
- }
- @Override
- public int getGroupCount() {
- return musicGroupBySinger.size();
- }
- @Override
- public int getChildrenCount(int groupPosition) {
- return musicGroupBySinger.get(groupPosition).size();
- }
- @Override
- public Object getGroup(int groupPosition) {
- return musicGroupBySinger.get(groupPosition);
- }
- @Override
- public Object getChild(int groupPosition, int childPosition) {
- return musicGroupBySinger.get(groupPosition).get(childPosition);
- }
- @Override
- public long getGroupId(int groupPosition) {
- return 0;
- }
- @Override
- public long getChildId(int groupPosition, int childPosition) {
- return 0;
- }
- //true还是false感觉没什么区别
- @Override
- public boolean hasStableIds() {
- return false;
- }
- //获取Group的视图
- @Override
- public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
- if (convertView == null) {
- LayoutInflater inflater = LayoutInflater.from(context);
- // R.layout.groups这个参数是group的视图
- convertView = inflater.inflate(R.layout.groups, null);
- }
- TextView title = (TextView) convertView.findViewById(R.id.tvSinger);
- title.setText(groupName.get(groupPosition));// 设置大组成员名称
- return convertView;
- }
- //获取展开的子视图
- /**
- * 在这里我有必要提一下listview加载视图的优化问题
- * <p/>
- * 一、复用convertView
- * 首先讲下ListView的原理:ListView中的每一个Item显示都需要Adapter调用一次getView的方法,这个方法会传入一个convertView的参数,
- * 返回的View就是这个Item显示的View。如果当Item的数量足够大,再为每一个Item都创建一个View对象,必将占用很多内存,
- * 创建View对象(mInflater.inflate(R.layout.lv_item, null);从xml中生成View,这是属于IO操作)也是耗时操作,所以必将影响性能。
- * Android提供了一个叫做Recycler(反复循环器)的构件,就是当ListView的Item从上方滚出屏幕视角之外,对应Item的View会被缓存到Recycler中,
- * 相应的会从下方生成一个Item,而此时调用的getView中的convertView参数就是滚出屏幕的Item的View,所以说如果能重用这个convertView,
- * 就会大大改善性能。
- * 所以getChildView 一开始会有一个判断语句
- * if (convertView == null) 如果不为空就直接使用之前那个。
- * <p/>
- * <p/>
- * 二、使用viewHolder类
- * 我们都知道在getView方法中的操作是这样的:
- * 先从xml中创建view对象(inflate操作,我们采用了重用convertView方法优化),然后在这个view去findViewById,
- * 找到每一个子View,如:一个TextView等。这里的findViewById操作是一个树查找过程,也是一个耗时的操作,所以这里也需要优化,
- * 就是使用viewHolder,把每一个子View都放在Holder中,当第一次创建convertView对象时,把这些子view找出来。
- * 然后用convertView的setTag将viewHolder设置到Tag中,以便系统第二次绘制ListView时从Tag中取出。
- * 当第二次重用convertView时,只需从convertView中getTag取出来就可以。
- */
- @Override
- public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
- int position = musicList.indexOf(getChild(groupPosition,
- childPosition));
- // 优化listView
- ViewHolder viewHolder;
- if (convertView == null) {
- // R.layout.music_item是每一项的视图xml文件
- convertView = LayoutInflater.from(MainActivity.this).inflate(
- R.layout.music_item, null);
- TextView pTitle = (TextView) convertView
- .findViewById(R.id.title);
- viewHolder = new ViewHolder(pTitle);
- // 用convertView的setTag将viewHolder设置到Tag中,以便系统第二次绘制ListView时从Tag中取出。
- convertView.setTag(viewHolder);
- } else {
- // 当第二次重用convertView时,只需从convertView中getTag取出来就可以。
- viewHolder = (ViewHolder) convertView.getTag();
- }
- viewHolder.title.setText(musicList.get(position).getTitle());
- return convertView;
- }
- @Override
- public boolean isChildSelectable(int groupPosition, int childPosition) {
- return false;
- }
- }
- class ViewHolder {
- TextView title;
- public ViewHolder(TextView pTitle) {
- title = pTitle;
- }
- }
- }
成果展示:
使用ExpandableListView以及如何优化view的显示减少内存占用相关推荐
- 怎么优化GO语言服务的内存占用
内存优化: 1.小对象合并成结构体一次分配,减少内存分配次数 2. 缓存区内容一次分配足够大小空间,并适当复用 3.slice和map采make创建时,预估大小指定容量 4.长调用栈避免申请较多的临时 ...
- UE 手游在 iOS 平台运行时内存占用太高?试试这样着手优化
性能优化,对游戏开发来说是一个需要不断钻研的课题,性能越好,游戏才会运行的更加顺畅,玩家的体验感才会更好.腾讯游戏学院专家.游戏客户端开发 Leonn,将和大家分享 UE 手游在 iOS 平台上的内存 ...
- redis占用内存过低_使用多种数据结构优化Redis 内存占用
背景 广告平台 adx 在处理曝光/点击上报时,使用 redis 的 setnx 命令去重,其逻辑如下 构造一个形如 s:track:%d:%s:%s 的 key,参数分别是上报类型(曝光 or 点击 ...
- 优化SQL Server的内存占用之执行缓存
优化SQL Server的内存占用之执行缓存篇 优化SQL Server的内存占用之执行缓存 在论坛上常见有朋友抱怨,说SQL Server太吃内存了.这里笔者根据经验简单介绍一下内存相关的调优知识. ...
- 【华为云技术分享】五个Taurus垃圾回收compactor优化方案,减少系统资源占用
TaurusDB是一种基于MySQL的计算与存储分离架构的云原生数据库,一个集群中包含多个存储几点,每个存储节点包含多块磁盘,每块磁盘对应一个或者多个slicestore的内存逻辑结构来管理. 在ta ...
- arcgis前端(3)----->基础篇--自定义地图优化/隐藏or显示子图层
arcgis前端(3)----->基础篇–自定义地图优化/隐藏or显示子图层 文章目录 arcgis前端(3)----->基础篇--自定义地图优化/隐藏or显示子图层 前言 实现效果展示 ...
- 在小程序中将多个view居中显示
我们在这里要实现的效果是这样的,在小程序中将多个view居中显示 先看一下效果图 如下图效果所示:我们需要将 "延长收货","查看物流","提醒发货& ...
- view中显示部分区域
在android中有时候要求只显示view的部分区域,这个时候就需要对当前的view进行剪裁的操作.在android中剪裁当前的view的有两种方法:一种是直接截取view,第二种是通过Outline ...
- android 在指定位置添加布局,Android 如何动态添加 View 并显示在指定位置。
引子 最近,在做产品的需求的时候,遇到 PM 要求在某个按钮上添加一个新手引导动画,引导用户去点击.作为 RD,我哗啦啦的就写好相关逻辑了.自测完成后,提测,PM Review 效果. 看完后,PM ...
最新文章
- js实现页面跳转的几种方式
- Socket编程原理概述
- top中的res只增不减_tensorflow中张量排序与accuracy计算
- 程序员高效学习的六原则
- SpringMVC中请求路径参数使用正则表达式
- 网页设计中常用的Web安全字体
- 记录各大吃播饭店地址
- 如何对计算机进行磁盘整理,如何对Windows 7进行磁盘碎片整理?
- 漫谈TCP新算法Elastic-TCP
- 搜狗输入法——自定义短语设置
- AtCoder Beginner Contest 214(补题)
- feign调用简单实例
- 离散数学考前复习:(三)计数
- 【javaweb简单教程】1.搭建Web环境、初识JSP
- 系统自带功能之视频压缩
- SVM支持向量机sklearn-wine红酒数据集代码V1
- win10 设定计划任务时提示所指定的账户名称无效,如何解决?
- 星际争霸1终于可以在win10上运行了
- J2SE和J2EE的比较
- 《蹭课神器》Alpha版使用说明
热门文章
- Variable和Tensor合并后,PyTorch的代码要怎么改?
- 面试热点Redis分布式锁,再细说一次
- 实现数据“一键脱敏”,Sharding Sphere帮你搞定
- 美团二面:Redis与MySQL双写一致性如何保证?
- 强烈不建议你用 a.equals(b) 判断对象相等!
- 阿里一面:如何保障消息100%投递成功、消息幂等性?
- 只知道用它打印了Hello World,除此之外你了解多少呢?
- 那些年,我们见过的 Java 服务端乱象
- Openresty最佳案例 | 第5篇:http和C_json模块
- Python数据处理入门教程!