热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用ExpandableListView以及如何优化view的显示减少内存占用

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

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

                                                                             MainActivity .java

public class MainActivity extends AppCompatActivity {
private static List musicList = new ArrayList();
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 musicList = new ArrayList();
//记录各个歌手名字
private List groupName = new ArrayList();
//按歌手名字分类后的所有歌曲
private List> musicGroupBySinger = new ArrayList>();

myExadapter(Context context, List group) {
this.cOntext= context;
musicList = group;

sortByArtistName();
}

// 根据歌手分类最终获得 musicGroupBySinger
private void sortByArtistName() {
// 第一个特殊
groupName.add(musicList.get(0).getArtist());
List musicListWithSameSinger = new ArrayList();
musicListWithSameSinger.add(musicList.get(0));
musicGroupBySinger.add(musicListWithSameSinger);
for (int i = 1; i boolean flag = false;
for (int j = 0; 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 musicListWithSameSinger2 = new ArrayList();
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加载视图的优化问题
*


* 一、复用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) 如果不为空就直接使用之前那个。
*


*


* 二、使用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;
}
}
}


 成果展示:

 

 

 



 

 

 

  • 大小: 64.4 KB
  • 查看图片附件

推荐阅读
  • 本文介绍了一款名为TimeSelector的Android日期时间选择器,采用了Material Design风格,可以在Android Studio中通过gradle添加依赖来使用,也可以在Eclipse中下载源码使用。文章详细介绍了TimeSelector的构造方法和参数说明,以及如何使用回调函数来处理选取时间后的操作。同时还提供了示例代码和可选的起始时间和结束时间设置。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 本文详细介绍了Android中的坐标系以及与View相关的方法。首先介绍了Android坐标系和视图坐标系的概念,并通过图示进行了解释。接着提到了View的大小可以超过手机屏幕,并且只有在手机屏幕内才能看到。最后,作者表示将在后续文章中继续探讨与View相关的内容。 ... [详细]
  • 带添加按钮的GridView,item的删除事件
    先上图片效果;gridView无数据时显示添加按钮,有数据时,第一格显示添加按钮,后面显示数据:布局文件:addr_manage.xml<?xmlve ... [详细]
  • 今天就跟大家聊聊有关怎么在Android应用中实现一个换肤功能,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根 ... [详细]
  • SmartRefreshLayout自定义头部刷新和底部加载
    1.添加依赖implementation‘com.scwang.smartrefresh:SmartRefreshLayout:1.0.3’implementation‘com.s ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • android 触屏处理流程,android触摸事件处理流程 ? FOOKWOOD「建议收藏」
    android触屏处理流程,android触摸事件处理流程?FOOKWOOD「建议收藏」最近在工作中,经常需要处理触摸事件,但是有时候会出现一些奇怪的bug,比如有时候会检测不到A ... [详细]
  • 前端开发工程师必读书籍有哪些值得推荐?我们直接进入代码复杂版式设置,如下所示,先写些标签,源码在这个链接里面:https://codepen.io/Shadid ... [详细]
  • 开发笔记:图像识别基于主成分分析算法实现人脸二维码识别
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了图像识别基于主成分分析算法实现人脸二维码识别相关的知识,希望对你有一定的参考价值。 ... [详细]
author-avatar
Jump_jiedB0_666
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有