ListView的优化和万能适配器继承于BaseAdapter
在android开发中Listview是一个很重要的组件,它以列表的形式根据数据的长自适应展示具体内容,用户可以自由的定义listview每一列的布局,但当listview有大量的数据需要加载的时候,会占据大量内存,影响性能,这时候就需要按需填充并重新使用view来减少对象的创建。
一、复用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,就会大大改善性能
二,ViewHolder类
避免了就是每次在getVIew的时候,都需要重新的findViewById,重新找到控件,然后进行控件的赋值以及事件相应设置。这样其实在做重复的事情)
三 自定义适配器BaseAdapter
抽取BaseAdapter类里面的方法写一个自定义适配器,因为一个项目中会有多次使用到适配器,其实每次使用,我们主要是写getView方法和传入数据,所以把其他的方法抽取出来写到一个自定义类里面,供多次使用,看看我的代码就知道了.
看看我写的自定义适配器
MyBaseAdapter.java
package com.gaomin.myBaseAdapter;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import java.util.List;
/**
* Created by gaomin on 2016/3/21.
*/
public abstract class MyBaseAdapter extends BaseAdapter{
public List T;
public MyBaseAdapter(List t){
T=t;
}
@Override
public int getCount() {
return T.size();
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public abstract View getView(int position, View convertView, ViewGroup parent);
}
activity_main.xml
每一项的布局
listview_item.xml
最后就是将要实现程序的主要java代码了
package com.gaomin.listViewDemo;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.gaomin.myBaseAdapter.MyBaseAdapter;
import java.util.ArrayList;
import java.util.HashMap;
public class MainActivity extends Activity {
private SongAdapter songAdapter;
private ListView mListView;
private ArrayList songArrayList;
private HashMap songMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mListView =(ListView)findViewById(R.id.mListView);
songArrayList = new ArrayList();
songMap = new HashMap();
songMap.put("image",R.mipmap.lyf);
songMap.put("singer","林心如");
songMap.put("songInfo","一万个舍不得");
songArrayList.add(songMap);
songMap = new HashMap();
songMap.put("image",R.mipmap.lyf);
songMap.put("singer","宋慧乔");
songMap.put("songInfo","太阳的后裔");
songArrayList.add(songMap);
songMap = new HashMap();
songMap.put("image",R.mipmap.lyf);
songMap.put("singer","庄心妍");
songMap.put("songInfo","一直还想着她");
songArrayList.add(songMap);
songMap = new HashMap();
songMap.put("image",R.mipmap.lyf);
songMap.put("singer","林心如");
songMap.put("songInfo","一万个舍不得");
songArrayList.add(songMap);
songMap = new HashMap();
songMap.put("image",R.mipmap.lyf);
songMap.put("singer","宋慧乔");
songMap.put("songInfo","太阳的后裔");
songArrayList.add(songMap);
songMap = new HashMap();
songMap.put("image",R.mipmap.lyf);
songMap.put("singer","庄心妍");
songMap.put("songInfo","一直还想着她");
songArrayList.add(songMap);
songMap = new HashMap();
songMap.put("image",R.mipmap.lyf);
songMap.put("singer","林心如");
songMap.put("songInfo","一万个舍不得");
songArrayList.add(songMap);
songMap = new HashMap();
songMap.put("image",R.mipmap.lyf);
songMap.put("singer","宋慧乔");
songMap.put("songInfo","太阳的后裔");
songArrayList.add(songMap);
songMap = new HashMap();
songMap.put("image",R.mipmap.lyf);
songMap.put("singer","庄心妍");
songMap.put("songInfo","一直还想着她");
songArrayList.add(songMap);
songMap = new HashMap();
songMap.put("image",R.mipmap.lyf);
songMap.put("singer","林心如");
songMap.put("songInfo","一万个舍不得");
songArrayList.add(songMap);
songMap = new HashMap();
songMap.put("image",R.mipmap.lyf);
songMap.put("singer","宋慧乔");
songMap.put("songInfo","太阳的后裔");
songArrayList.add(songMap);
songMap = new HashMap();
songMap.put("image",R.mipmap.lyf);
songMap.put("singer","庄心妍");
songMap.put("songInfo","一直还想着她");
songArrayList.add(songMap);
songMap = new HashMap();
songMap.put("image",R.mipmap.lyf);
songMap.put("singer","林心如");
songMap.put("songInfo","一万个舍不得");
songArrayList.add(songMap);
songMap = new HashMap();
songMap.put("image",R.mipmap.lyf);
songMap.put("singer","宋慧乔");
songMap.put("songInfo","太阳的后裔");
songArrayList.add(songMap);
songMap = new HashMap();
songMap.put("image",R.mipmap.lyf);
songMap.put("singer","庄心妍");
songMap.put("songInfo","一直还想着她");
songArrayList.add(songMap);
if(songAdapter==null){
songAdapter = new SongAdapter(this,songArrayList);
}else {
//刷新适配器,不用每次都new SongAdapter(this,songArrayList)
songAdapter.notifyDataSetChanged();
}
mListView.setAdapter(songAdapter);
}
class SongAdapter extends MyBaseAdapter{
private Context context;
SongAdapter(Context c,ArrayList arrayList){
super(arrayList);
context=c;
}
//重用了convertView,很大程度上的减少了内存的消耗。通过判断convertView是否为null,
// 是的话就需要产生一个视图出来,然后给这个视图数据,最后将这个视图返回给底层,呈献给用户。
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if(convertView==null){
LayoutInflater inflater = LayoutInflater.from(context);
convertView =inflater.inflate(R.layout.listview_item,null);
viewHolder = new ViewHolder();
viewHolder.singerImageView =(ImageView)convertView.findViewById(R.id.singerImageView);
viewHolder.songInfoTextView =(TextView)convertView.findViewById(R.id.songInfoTextView);
viewHolder.singerTextView =(TextView)convertView.findViewById(R.id.singerTextView);
viewHolder.deleteSongBtn =(Button)convertView.findViewById(R.id.deleteSongBtn);
viewHolder.downLoadSongBtn=(Button)convertView.findViewById(R.id.downLoadSongBtn);
convertView.setTag(viewHolder);
viewHolder.deleteSongBtn.setTag(position);
viewHolder.downLoadSongBtn.setTag(position);
}else {
viewHolder =(ViewHolder)convertView.getTag();
}
viewHolder.singerImageView.setImageResource((Integer)
((HashMap)songArrayList.get(position)).get("image"));
viewHolder.singerTextView.setText((String)((HashMap)songArrayList.get(position)).get("singer"));
viewHolder.songInfoTextView.setText((String)((HashMap)songArrayList.get(position)).get("songInfo"));
viewHolder.deleteSongBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int dePosition = (Integer)v.getTag();
songArrayList.remove(dePosition);
songAdapter.notifyDataSetChanged();
}
});
viewHolder.downLoadSongBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int downLoadPosition =(Integer)v.getTag();
String singerStr =(String)((HashMap)songArrayList.get(downLoadPosition)).get("singer");
String songStr =(String)((HashMap)songArrayList.get(downLoadPosition)).get("songInfo");
String toastStr =singerStr+songStr;
Toast.makeText(getApplicationContext(),"你准备下载"+toastStr,Toast.LENGTH_SHORT).show();
}
});
return convertView;
}
}
//避免了就是每次在getVIew的时候,都需要重新的findViewById,
// 重新找到控件,然后进行控件的赋值以及事件相应设置。这样其实在做重复的事情)
class ViewHolder{
ImageView singerImageView;
TextView songInfoTextView;
TextView singerTextView;
Button deleteSongBtn;
Button downLoadSongBtn;
}
}