使用ExpandableListView以及如何优化view的显示减少内存占用
2016-11-18 20:35
573 查看
上篇博客讲到如何获取手机中所有歌曲的信息。本文就把上篇获取到的歌曲按照歌手名字分类。用一个ExpandableListView显示出来。
MainActivity .java
成果展示:
大小: 64.4 KB
查看图片附件
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; } } }
成果展示:
大小: 64.4 KB
查看图片附件
相关文章推荐
- 使用ExpandableListView以及如何优化view的显示减少内存占用
- 如何优化Apache,减少内存使用
- 如何管理app的进程与内存分配,以及在Android开发应用的时候如何主动的减少内存的使用
- 如何减少网页的内存使用与CPU占用
- [编程]如何减少.Net应用程序启动时占用的内存 [2007-04-02 更新]
- XP 可关闭的服务 优化系统内存 减少内存占用...
- matlab 优化内存使用以及优化代码运行速度
- 如何提高《个人助手》的运行速度,减少内存占用!
- nios中优化代码和减少程序占用内存空间的设置方法
- 【十五分钟Talkshow】如何理解并优化.NET应用程序对内存的使用
- MyEclipse8.5 性能优化,如何减小内存使用
- iphone 使用popViewController如何避免内存泄露
- 如何优化 Exchange Server 2003 中的内存使用
- ReportView如何使用构造SQL语句带参数的存储过程创建报表以及为rdlc传递参数
- Android深入浅出系列之实例应用—简单的手指拖动图片,图片滑来滑去显示应用Gallery和BaseAdapter以及ImageView的使用
- 如何减少网页的内存与CPU占用
- 减少windows7内存占用的优化方案 (内存占用才285兆 比XP还省)
- cisco交换机如何查看CPU和内存使用情况,以及如何查看接口数据量
- Android手机开发:ImageView使用和从内存读取图片显示
- 一个可以显示图片(包括GIF动画)的ATL控件,以及在RichEdit中如何使用此控件插入图片