上篇博客讲到如何获取手机中所有歌曲的信息。本文就把上篇获取到的歌曲按照歌手名字分类。用一个ExpandableListView显示出来。

MainActivity .java

  1.  
    public class MainActivity extends AppCompatActivity {
  2.  
    private static List<MusicLoader.MusicInfo> musicList = new ArrayList<MusicLoader.MusicInfo>();
  3.  
    private ExpandableListView groupLvSongs;
  4.  
     
  5.  
    @Override
  6.  
    protected void onCreate(Bundle savedInstanceState) {
  7.  
    super.onCreate(savedInstanceState);
  8.  
    setContentView(R.layout.activity_main);
  9.  
    initView();
  10.  
    initEvent();
  11.  
    }
  12.  
     
  13.  
    private void initEvent() {
  14.  
    // 这是获取musicList,与本篇博客主题无关,大家只需要知道musicList代表所有歌曲,它的每一项都包含一首歌的所有信息
  15.  
    musicList = MusicLoader.instance(getContentResolver()).getMusicList();
  16.  
    // 设置适配器,给listview提供数据
  17.  
    groupLvSongs.setAdapter(new myExadapter(MainActivity.this, musicList));
  18.  
    }
  19.  
     
  20.  
    private void initView() {
  21.  
    groupLvSongs = (ExpandableListView) findViewById(R.id.groupLvSongs);
  22.  
    }
  23.  
     
  24.  
    /**
  25.  
    * 按歌手分类的listview 对应的Adapter,自定义ExpandableListView的适配器
  26.  
    * getGroupId()getChildId()hasStableIds()isChildSelectable暂时都默认自动生成的,
  27.  
    * 最主要是getGroupView(),getChildView()方法
  28.  
    */
  29.  
    class myExadapter extends BaseExpandableListAdapter {
  30.  
     
  31.  
    //在获取view的时候需要context
  32.  
    private Context context;
  33.  
    //所有歌曲
  34.  
    private List<MusicInfo> musicList = new ArrayList<MusicInfo>();
  35.  
    //记录各个歌手名字
  36.  
    private List<String> groupName = new ArrayList<String>();
  37.  
    //按歌手名字分类后的所有歌曲
  38.  
    private List<List<MusicInfo>> musicGroupBySinger = new ArrayList<List<MusicInfo>>();
  39.  
     
  40.  
    myExadapter(Context context, List<MusicInfo> group) {
  41.  
    this.context = context;
  42.  
    musicList = group;
  43.  
     
  44.  
    sortByArtistName();
  45.  
    }
  46.  
     
  47.  
    // 根据歌手分类最终获得 musicGroupBySinger
  48.  
    private void sortByArtistName() {
  49.  
    // 第一个特殊
  50.  
    groupName.add(musicList.get(0).getArtist());
  51.  
    List<MusicInfo> musicListWithSameSinger = new ArrayList<MusicInfo>();
  52.  
    musicListWithSameSinger.add(musicList.get(0));
  53.  
    musicGroupBySinger.add(musicListWithSameSinger);
  54.  
    for (int i = 1; i < musicList.size(); i++) {
  55.  
    boolean flag = false;
  56.  
    for (int j = 0; j < groupName.size(); j++) {
  57.  
    // if该歌手名字已经存在
  58.  
    if (musicList.get(i).getArtist().equals(groupName.get(j))) {
  59.  
    flag = true;
  60.  
    musicGroupBySinger.get(j).add(musicList.get(i));
  61.  
    break;
  62.  
    }
  63.  
    }
  64.  
    if (!flag) {
  65.  
    groupName.add(musicList.get(i).getArtist());
  66.  
    List<MusicInfo> musicListWithSameSinger2 = new ArrayList<MusicInfo>();
  67.  
    musicListWithSameSinger2.add(musicList.get(i));
  68.  
    musicGroupBySinger.add(musicListWithSameSinger2);
  69.  
    }
  70.  
    }
  71.  
    }
  72.  
     
  73.  
    @Override
  74.  
    public int getGroupCount() {
  75.  
    return musicGroupBySinger.size();
  76.  
    }
  77.  
     
  78.  
    @Override
  79.  
    public int getChildrenCount(int groupPosition) {
  80.  
    return musicGroupBySinger.get(groupPosition).size();
  81.  
    }
  82.  
     
  83.  
    @Override
  84.  
    public Object getGroup(int groupPosition) {
  85.  
    return musicGroupBySinger.get(groupPosition);
  86.  
    }
  87.  
     
  88.  
    @Override
  89.  
    public Object getChild(int groupPosition, int childPosition) {
  90.  
    return musicGroupBySinger.get(groupPosition).get(childPosition);
  91.  
    }
  92.  
     
  93.  
    @Override
  94.  
    public long getGroupId(int groupPosition) {
  95.  
    return 0;
  96.  
    }
  97.  
     
  98.  
    @Override
  99.  
    public long getChildId(int groupPosition, int childPosition) {
  100.  
    return 0;
  101.  
    }
  102.  
     
  103.  
    //true还是false感觉没什么区别
  104.  
    @Override
  105.  
    public boolean hasStableIds() {
  106.  
    return false;
  107.  
    }
  108.  
     
  109.  
    //获取Group的视图
  110.  
    @Override
  111.  
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
  112.  
     
  113.  
    if (convertView == null) {
  114.  
    LayoutInflater inflater = LayoutInflater.from(context);
  115.  
    // R.layout.groups这个参数是group的视图
  116.  
    convertView = inflater.inflate(R.layout.groups, null);
  117.  
    }
  118.  
     
  119.  
    TextView title = (TextView) convertView.findViewById(R.id.tvSinger);
  120.  
    title.setText(groupName.get(groupPosition));// 设置大组成员名称
  121.  
     
  122.  
    return convertView;
  123.  
    }
  124.  
    //获取展开的子视图
  125.  
     
  126.  
    /**
  127.  
    * 在这里我有必要提一下listview加载视图的优化问题
  128.  
    * <p/>
  129.  
    * 一、复用convertView
  130.  
    * 首先讲下ListView的原理:ListView中的每一个Item显示都需要Adapter调用一次getView的方法,这个方法会传入一个convertView的参数,
  131.  
    * 返回的View就是这个Item显示的View。如果当Item的数量足够大,再为每一个Item都创建一个View对象,必将占用很多内存,
  132.  
    * 创建View对象(mInflater.inflate(R.layout.lv_item, null);从xml中生成View,这是属于IO操作)也是耗时操作,所以必将影响性能。
  133.  
    * Android提供了一个叫做Recycler(反复循环器)的构件,就是当ListView的Item从上方滚出屏幕视角之外,对应Item的View会被缓存到Recycler中,
  134.  
    * 相应的会从下方生成一个Item,而此时调用的getView中的convertView参数就是滚出屏幕的Item的View,所以说如果能重用这个convertView,
  135.  
    * 就会大大改善性能。
  136.  
    * 所以getChildView 一开始会有一个判断语句
  137.  
    * if (convertView == null) 如果不为空就直接使用之前那个。
  138.  
    * <p/>
  139.  
    * <p/>
  140.  
    * 二、使用viewHolder类
  141.  
    * 我们都知道在getView方法中的操作是这样的:
  142.  
    * 先从xml中创建view对象(inflate操作,我们采用了重用convertView方法优化),然后在这个view去findViewById,
  143.  
    * 找到每一个子View,如:一个TextView等。这里的findViewById操作是一个树查找过程,也是一个耗时的操作,所以这里也需要优化,
  144.  
    * 就是使用viewHolder,把每一个子View都放在Holder中,当第一次创建convertView对象时,把这些子view找出来。
  145.  
    * 然后用convertView的setTag将viewHolder设置到Tag中,以便系统第二次绘制ListView时从Tag中取出。
  146.  
    * 当第二次重用convertView时,只需从convertView中getTag取出来就可以。
  147.  
    */
  148.  
    @Override
  149.  
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
  150.  
    int position = musicList.indexOf(getChild(groupPosition,
  151.  
    childPosition));
  152.  
    // 优化listView
  153.  
    ViewHolder viewHolder;
  154.  
    if (convertView == null) {
  155.  
    // R.layout.music_item是每一项的视图xml文件
  156.  
    convertView = LayoutInflater.from(MainActivity.this).inflate(
  157.  
    R.layout.music_item, null);
  158.  
     
  159.  
    TextView pTitle = (TextView) convertView
  160.  
    .findViewById(R.id.title);
  161.  
    viewHolder = new ViewHolder(pTitle);
  162.  
    // 用convertView的setTag将viewHolder设置到Tag中,以便系统第二次绘制ListView时从Tag中取出。
  163.  
    convertView.setTag(viewHolder);
  164.  
    } else {
  165.  
    // 当第二次重用convertView时,只需从convertView中getTag取出来就可以。
  166.  
    viewHolder = (ViewHolder) convertView.getTag();
  167.  
    }
  168.  
    viewHolder.title.setText(musicList.get(position).getTitle());
  169.  
    return convertView;
  170.  
    }
  171.  
     
  172.  
    @Override
  173.  
    public boolean isChildSelectable(int groupPosition, int childPosition) {
  174.  
    return false;
  175.  
    }
  176.  
    }
  177.  
     
  178.  
    class ViewHolder {
  179.  
    TextView title;
  180.  
     
  181.  
    public ViewHolder(TextView pTitle) {
  182.  
    title = pTitle;
  183.  
    }
  184.  
    }
  185.  
    }
  186.  
     
  187.  
     

成果展示:

使用ExpandableListView以及如何优化view的显示减少内存占用的更多相关文章

  1. 优化 UWP 中图片的内存占用

    跟图片打交道的 UWP 应用或多或少都会遇到图片带来的性能问题,就算不主要处理图片,做个论坛做个新闻客户端都涉及到大量图片.一个帖子.一篇文章里多半都是些高清大图,这些图片一张即可占用程序 1~2M ...

  2. spark优化之数据结构(减少内存)

    官网是这么说的: The first way to reduce memory consumption is to avoid the Java features that add overhead, ...

  3. SqlServer性能优化,查看CPU、内存占用大的会话及SQL语句

    1,查看CPU占用量最高的会话及SQL语句   select spid,cmd,cpu,physical_io,memusage, (select top 1 [text] from ::fn_get ...

  4. 优化SQL Server的内存占用之执行缓存

    在论坛上常见有朋友抱怨,说SQL Server太吃内存了.这里笔者根据经验简单介绍一下内存相关的调优知识   首先说明一下SQL Server内存占用由哪几部分组成.SQL Server占用的内存主要 ...

  5. 五个Taurus垃圾回收compactor优化方案,减少系统资源占用

    简介 TaurusDB是一种基于MySQL的计算与存储分离架构的云原生数据库,一个集群中包含多个存储几点,每个存储节点包含多块磁盘,每块磁盘对应一个或者多个slicestore的内存逻辑结构来管理. ...

  6. Android中View绘制优化之三---- 优化View

    本文原创, 转载请注明出处:http://blog.csdn.net/qinjuning 译三: 优化视图 关于如何设计自定义View以及响应触摸时间等,请看Android developer : 地 ...

  7. 仅此一文让你明白ASP.NET MVC 之View的显示(仅此一文系列二)

    题外话 一周之前写的<仅此一文让你明白ASP.NET MVC原理>受到了广大学习ASP.NET MVC同学的欢迎,于是下定决心准备把它写成一个系列,以满足更多求知若渴的同学们.蒋金楠老师已 ...

  8. 仅此一文让你明白ASP.NET MVC 之View的显示

    有些人要问题,为什么我要学框架?这里我简单说一下,深入理解一个框架,给你带来最直接的好处: 使用框架时,遇到问题可以快速定位,并知道如何解决: 当框架中有些功能用着不爽时,你可以自由扩展,实现你想要的 ...

  9. 经验之谈—控制器的view的显示

    经验之谈—控制器的view的显示 开发中,我们经常需要将一个控制器的view添加到另一个控制器的view上,这种效果是我们期望看到的,但是里边隐藏着一些细节,不注意的话,可能会达不到我们想到的效果. ...

随机推荐

  1. thinkphp验证码的使用

    thinkphp不仅封装了验证规则 还封装了验证码 文件的位置是ThinkPHP\Library\Think\Verify.class.php 下面简单的说一下如何使用 我们现在控制器里新建一个方法 ...

  2. 2018年商业版idea破解安装介绍

    1. IntelliJ IDEA 2018商业版-安装 首先去官网http://www.jetbrains.com/idea/download/#section=windows下载Ultimate版( ...

  3. [OpenCV-Python] OpenCV 中的图像处理 部分 IV (二)

    部分 IVOpenCV 中的图像处理 OpenCV-Python 中文教程(搬运)目录 16 图像平滑 目标 • 学习使用不同的低通滤波器对图像进行模糊 • 使用自定义的滤波器对图像进行卷积(2D 卷 ...

  4. poj2184 Cow Exhibition【01背包】+【负数处理】+(求两个变量的和最大)

    题目链接:https://vjudge.net/contest/103424#problem/G 题目大意: 给出N头牛,每头牛都有智力值和幽默感,然后,这个题目最奇葩的地方是,它们居然可以是负数!! ...

  5. 005.Docker存储管理

    一 Docker volume形态 因为Docker 采用 AFUS 分层文件系统时,文件系统的改动都是发生在最上面的容器层,在容器的生命周期内,它是持续的,包括容器在被停止后.但是,当容器被删除后, ...

  6. IntelliJ IDEA(九) :插件(转)

    最近项目比较忙,很久没有更新IDEA系列了,今天介绍一下IDEA的一些炫酷的插件,IDEA强大的插件库,不仅能给我们带来一些开发的便捷,还能体现我们的与众不同. 0|11.插件的安装 打开settin ...

  7. python魔法方法-自定义序列

    自定义序列的相关魔法方法允许我们自己创建的类拥有序列的特性,让其使用起来就像 python 的内置序列(dict,tuple,list,string等). 如果要实现这个功能,就要遵循 python ...

  8. BZOJ.2177.曼哈顿最小生成树(Kruskal)

    \(Solution\) 参考 对于每个点,向唯一有可能与它形成MST的8个点连边,由于是双向单边,所以每个点最多连出4条边(证明见blog) 怎么找到一个区域内最近的点? 只考虑y轴右侧45°的区域 ...

  9. Python图形编程探索系列-03-标签组件(Label)

    跳转到自己的博客 tkinter.Label介绍 什么是标签? 通俗的将就相当于word的功能,能够进行显示不可修改的文字.图片或者图文混排. 直观体会一下 图1 背景图构成:内容区(黑色),填充区( ...

  10. Python3科学计算库概况

    Python3科学计算常见库入门 Numpy快速数据处理库 参见我的博客 http://www.cnblogs.com/brightyuxl/p/8981294.html http://www.cnb ...