直接看代码;
package com.tz.listview;
import java.util.ArrayList;
import java.util.HashMap;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;
/**
* ListView优化,获取网络图片异步加载,分批加载,分页显示,图片缓存等优化方式
* @author Tony
*参考文档 http://blog.csdn.net/u013263323/article/details/46548685
*/
public class ListViewOptimizeActivity extends Activity {
int count = 0;
ListView listView;
private ArrayList data;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
data = intData();
// SimpleAdapter
listView = (ListView) findViewById(R.id.listview);
// final MyAdapter adapter = new MyAdapter();
final SimpleAdapter adapter = new SimpleAdapter(this, data,
R.layout.listitem,
new String[]{"name","num"},
new int[]{R.id.tv_name,R.id.tv_num});
listView.setAdapter(adapter);
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// TODO Auto-generated method stub
//删除操作,刷新。从data移除一条数据
adapter.notifyDataSetChanged();
}
});
// listView.setOnScrollListener(new OnScrollListener{….})
listView.setOnScrollListener(new OnScrollListener() {
public void onScrollStateChanged(AbsListView view, int scrollState) {
// 手指按下移动的状态 : SCROLL_STATE_TOUCH_SCROLL:// 触摸滑动
// 惯性滚动(滑翔(flgin)状态):SCROLL_STATE_FLING: // 滑翔
// 静止状态: SCROLL_STATE_IDLE:// 静止
switch (scrollState) {
case SCROLL_STATE_TOUCH_SCROLL:
break;
case SCROLL_STATE_FLING:
break;
case SCROLL_STATE_IDLE:
if (isLastItemVisible()){
Toast.makeText(ListViewOptimizeActivity.this, "true", Toast.LENGTH_SHORT).show();
}else{
Log.e("111", "111");
}
break;
}
}
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
}
});
}
public ArrayList intData(){
ArrayList<HashMap<String, Object>> list = new ArrayList<HashMap<String,Object>>();
for (int i = 0; i < 10; i++) {
HashMap<String, Object> item = new HashMap<String, Object>();
item.put("image", "");
item.put("name", "潭州"+i);
item.put("num", "公开微信号"+i);
list.add(item);
}
return list;
}
/**
* 判断最后listView中最后一个item是否完全显示出来
* @return
*/
// ctrl +alt +h查看哪些方法调用isLastItemVisible()
protected boolean isLastItemVisible() {
final Adapter adapter = listView.getAdapter();
if (null == adapter || adapter.isEmpty()) {
return true;
}
final int lastItemPosition = adapter.getCount() - 1;
final int lastVisiblePosition = listView.getLastVisiblePosition();
if (lastVisiblePosition >= lastItemPosition - 1) {
final int childIndex = lastVisiblePosition - listView.getFirstVisiblePosition();
final int childCount = listView.getChildCount();
final int index = Math.min(childIndex, childCount - 1);
final View lastVisibleChild = listView.getChildAt(index);
if (lastVisibleChild != null) {
return lastVisibleChild.getBottom() <= listView.getBottom();
}
}
return false;
}
class MyAdapter extends BaseAdapter{
public MyAdapter() {
super();
}
public int getCount() {
return data.size();
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
TextView tvname = null;
TextView tvnum = null;
count ++;
// Log.e("count", "===="+count);
// convertView = View.inflate(ListViewOptimizeActivity.this,R.layout.listitem, null);
// tvname = (TextView) convertView.findViewById(R.id.tv_name);
// tvnum = (TextView) convertView.findViewById(R.id.tv_num);
// 方案1
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = View.inflate(ListViewOptimizeActivity.this,
R.layout.listitem, null);
holder.img = (ImageView) convertView.findViewById(R.id.image);
holder.title = (TextView) convertView.findViewById(R.id.tv_name);
holder.info = (TextView) convertView.findViewById(R.id.tv_num);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
HashMap<String, Object> map = (HashMap<String, Object>) data.get(position);
holder.img.setImageResource(R.drawable.ic_launcher);
holder.title.setText(map.get("name").toString());
holder.info.setText(map.get("num").toString());
// 方案2
// if (null == convertView){
// convertView = View.inflate(ListViewOptimizeActivity.this, R.layout.listitem, null);
// tvname = (TextView) convertView.findViewById(R.id.tv_name);
// tvnum = (TextView) convertView.findViewById(R.id.tv_num);
// }else{
// tvname = (TextView) ((LinearLayout)convertView).getChildAt(1);
// tvnum = (TextView) ((LinearLayout)convertView).getChildAt(2);
// }
//
// HashMap<String, Object> map = (HashMap<String, Object>) data.get(position);
// tvname.setText(map.get("name").toString());
// tvnum.setText(map.get("num").toString());
return convertView;
}
}
//在外面先定义,ViewHolder静态类
static class ViewHolder{
public ImageView img;
public TextView title;
public TextView info;
}
}
package com.tz.listview;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import android.graphics.Bitmap;
import android.util.Log;
public class MemoryCache {
private static final String TAG = "MemoryCache";
// 放入缓存时是个同步操作
// LinkedHashMap构造方法的最后一个参数true代表这个map里的元素将按照最近使用次数由少到多排列,即LRU
// 这样的好处是如果要将缓存中的元素替换,则先遍历出最近最少使用的元素来替换以提高效率
private Map<String, Bitmap> cache = Collections.synchronizedMap(new LinkedHashMap<String, Bitmap>(10, 1.5f,true));
// 缓存中图片所占用的字节,初始0,将通过此变量严格控制缓存所占用的堆内存
private long size = 0;// current allocated size
// 缓存只能占用的最大堆内存
private long limit = 1000000;// max memory in bytes
public MemoryCache() {
// use 25% of available heap size
setLimit(Runtime.getRuntime().maxMemory() / 10);
}
public void setLimit(long new_limit) {
limit = new_limit;
Log.i(TAG, "MemoryCache willuse up to " + limit / 1024. / 1024. + "MB");
}
public Bitmap get(String id) {
try {
if (!cache.containsKey(id)){
return null;
}
return cache.get(id);
} catch (NullPointerException ex){
return null;
}
}
public void put(String id, Bitmap bitmap) {
try {
if (cache.containsKey(id)){
size -=getSizeInBytes(cache.get(id));
}
cache.put(id, bitmap);
size += getSizeInBytes(bitmap);
checkSize();
} catch (Throwable th) {
th.printStackTrace();
}
}
/**
* 严格控制堆内存,如果超过将首先替换最近最少使用的那个图片缓存
*
*/
private void checkSize() {
Log.i(TAG, "cachesize=" + size + " length=" + cache.size());
if (size > limit) {
// 先遍历最近最少使用的元素
Iterator<Entry<String, Bitmap>> iter = cache.entrySet().iterator();
while (iter.hasNext()) {
Entry<String, Bitmap> entry =iter.next();
size -=getSizeInBytes(entry.getValue());
iter.remove();
if (size <= limit)
break;
}
Log.i(TAG, "Clean cache. New size " + cache.size());
}
}
public void clear() {
cache.clear();
}
/**
* 图片占用的内存
* <a href="\"http://www.eoeandroid.com/home.php?mod=space&uid=2768922\""target="\"_blank\"">@Param</a> bitmap
* @return
*/
long getSizeInBytes(Bitmap bitmap) {
if (bitmap == null){
return 0;
}
return bitmap.getRowBytes() *bitmap.getHeight();
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:gravity="center_vertical"
android:padding="5dp">
<ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher" />
<TextView
android:id="@+id/tv_name"
android:layout_width="100dp"
android:layout_marginLeft="5dp"
android:layout_height="wrap_content"
android:text="TextView" />
<TextView
android:id="@+id/tv_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
<ListView
android:id="@+id/listview"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
</ListView>
</LinearLayout>