使用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的显示减少内存占用的更多相关文章
- 优化 UWP 中图片的内存占用
跟图片打交道的 UWP 应用或多或少都会遇到图片带来的性能问题,就算不主要处理图片,做个论坛做个新闻客户端都涉及到大量图片.一个帖子.一篇文章里多半都是些高清大图,这些图片一张即可占用程序 1~2M ...
- spark优化之数据结构(减少内存)
官网是这么说的: The first way to reduce memory consumption is to avoid the Java features that add overhead, ...
- SqlServer性能优化,查看CPU、内存占用大的会话及SQL语句
1,查看CPU占用量最高的会话及SQL语句 select spid,cmd,cpu,physical_io,memusage, (select top 1 [text] from ::fn_get ...
- 优化SQL Server的内存占用之执行缓存
在论坛上常见有朋友抱怨,说SQL Server太吃内存了.这里笔者根据经验简单介绍一下内存相关的调优知识 首先说明一下SQL Server内存占用由哪几部分组成.SQL Server占用的内存主要 ...
- 五个Taurus垃圾回收compactor优化方案,减少系统资源占用
简介 TaurusDB是一种基于MySQL的计算与存储分离架构的云原生数据库,一个集群中包含多个存储几点,每个存储节点包含多块磁盘,每块磁盘对应一个或者多个slicestore的内存逻辑结构来管理. ...
- Android中View绘制优化之三---- 优化View
本文原创, 转载请注明出处:http://blog.csdn.net/qinjuning 译三: 优化视图 关于如何设计自定义View以及响应触摸时间等,请看Android developer : 地 ...
- 仅此一文让你明白ASP.NET MVC 之View的显示(仅此一文系列二)
题外话 一周之前写的<仅此一文让你明白ASP.NET MVC原理>受到了广大学习ASP.NET MVC同学的欢迎,于是下定决心准备把它写成一个系列,以满足更多求知若渴的同学们.蒋金楠老师已 ...
- 仅此一文让你明白ASP.NET MVC 之View的显示
有些人要问题,为什么我要学框架?这里我简单说一下,深入理解一个框架,给你带来最直接的好处: 使用框架时,遇到问题可以快速定位,并知道如何解决: 当框架中有些功能用着不爽时,你可以自由扩展,实现你想要的 ...
- 经验之谈—控制器的view的显示
经验之谈—控制器的view的显示 开发中,我们经常需要将一个控制器的view添加到另一个控制器的view上,这种效果是我们期望看到的,但是里边隐藏着一些细节,不注意的话,可能会达不到我们想到的效果. ...
随机推荐
- Flink(一)Flink的入门简介
一. Flink的引入 这几年大数据的飞速发展,出现了很多热门的开源社区,其中著名的有 Hadoop.Storm,以及后来的 Spark,他们都有着各自专注的应用场景.Spark 掀开了内存计算的先河 ...
- BZOJ4034 [HAOI2015]树上操作 树链剖分
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ4034 题意概括 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三 ...
- BZOJ1068 [SCOI2007]压缩 区间动态规划 字符串
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1068 题目概括 (其实是复制的) 给一个由小写字母组成的字符串,我们可以用一种简单的方法来压缩其中 ...
- git add Untracked files
git add * 将目录里的所有文件提交到暂存区后 git status 查看状态 所有文件都是绿色的表示本地的文件和暂存区的文件是一样的 然后在本地修改一个文件 然后新建一个文件 在使用git ...
- IdentityServer4-前后端分离的授权验证(六)
上两节介绍完Hybrid模式在MVC下的使用,包括验证从数据获取的User和Claim对MVC的身份授权.本节将介绍Implicit模式在JavaScript应用程序中的使用,使用Node.js+Ex ...
- 洛谷.4234.最小差值生成树(LCT)
题目链接 先将边排序,这样就可以按从小到大的顺序维护生成树,枚举到一条未连通的边就连上,已连通则(用当前更大的)替换掉路径上最小的边,这样一定不会更差. 每次构成树时更新答案.答案就是当前边减去生成树 ...
- BZOJ.3510.首都(LCT 启发式合并 树的重心)
题目链接 BZOJ 洛谷 详见这. 求所有点到某个点距离和最短,即求树的重心.考虑如何动态维护. 两棵子树合并后的重心一定在两棵树的重心之间那条链上,所以在合并的时候用启发式合并,每合并一个点检查sz ...
- bzoj 1095 括号序列求两点距离
大致题意: 给一棵树,每个节点最开始都是黑色,有两种操作,1.询问树中相距最远的一对黑点的距离 2.反转一个节点的颜色 一种做法: 建立出树的括号序列,类似这样: [A[B][C]],所以长度为3*n ...
- winform 中 给DataGridView的表头添加CheckBox
在C/S架构中,给DataGridView的表头添加CheckBox控件: 添加类: /// <summary> /// 给DataGridView添加全选 / ...
- 系统wmiprvse.exe占用CPU非常高,求解决
1.wmiprvse.exe是微软Windows操作系统的一部分.用于通过WinMgmt.exe程序处理WMI操作.文件位置有二处: C:\WINDOWS\system32\wbem\wmiprvse ...