zoukankan      html  css  js  c++  java
  • 使用ExpandableListView以及如何优化view的显示减少内存占用

     

    上篇博客讲到如何获取手机中所有歌曲的信息。本文就把上篇获取到的歌曲按照歌手名字分类。用一个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.  
       

     成果展示:



     

  • 相关阅读:
    MATLAB 粒子群优化PSO
    MATLAB 简单图像融合
    MATLAB 拉普拉斯残差金字塔
    MATLAB 随机抽样一致RANSAC
    MATLAB TV模型图像修复
    MATLAB radon变换
    MATLAB 二维直方图
    MATLAB 自适应中值滤波RAMF
    MATLAB 二值图像内外边界跟踪
    MATLAB 各向异性扩散)
  • 原文地址:https://www.cnblogs.com/xgjblog/p/9681776.html
Copyright © 2011-2022 走看看