你的位置:首页 > 操作系统

[操作系统]自己定制ListView,上拉刷新和下拉刷新,加载网络图片,并且添加缓存机制。


 1 package com.lixu.listviewrefresh; 2  3 import java.util.ArrayList; 4 import java.util.HashMap; 5 import java.util.Random; 6  7 import com.lixu.listviewrefresh.Loadnetimage.OnLoadnetimageListener; 8 import com.lixu.listviewrefresh.MyRefreshListview.OnRefreshListener; 9 import android.annotation.SuppressLint; 10 import android.app.Activity; 11 import android.app.ProgressDialog; 12 import android.content.Context; 13 import android.graphics.Bitmap; 14 import android.graphics.BitmapFactory; 15 import android.os.AsyncTask; 16 import android.os.Bundle; 17 import android.util.Log; 18 import android.view.LayoutInflater; 19 import android.view.View; 20 import android.view.ViewGroup; 21 import android.widget.ArrayAdapter; 22 import android.widget.ImageView; 23 import android.widget.ListView; 24 import android.widget.TextView; 25  26 public class MainActivity extends Activity { 27   private static final String KEY_IMAGE = "image_key"; 28   private static final String KEY_TEXT = "text_key"; 29  30   private static final String CACHE_KEY_IMAGE = "cache_image_key"; 31   private static final String CACHE_KEY_TEXT = "cache_text_key"; 32   // 原始数据 33   private ArrayList<HashMap<String, Object>> data; 34   // 缓存队列 35   private ArrayList<HashMap<String, Object>> cache; 36  37   private ArrayAdapter<String> mMyAdapter; 38  39   private MyRefreshListview lv; 40  41   private Activity activity; 42   private Random random = new Random(); 43   // 图片网络地址 44   private String[] image_urls = { "http://img0.bdstatic.com/img/image/shouye/mxh007.jpg", 45       "http://f.hiphotos.baidu.com/image/h%3D360/sign=1c9a50843ec79f3d90e1e2368aa0cdbc/f636afc379310a5566becb8fb24543a982261036.jpg", 46       "http://h.hiphotos.baidu.com/image/h%3D360/sign=04ef437b0b23dd543e73a16ee108b3df/50da81cb39dbb6fd9d9ada390b24ab18962b37ef.jpg", 47       "http://b.hiphotos.baidu.com/image/h%3D360/sign=e91921f7c1fdfc03fa78e5bee43e87a9/8b82b9014a90f60352684b4e3b12b31bb151eddb.jpg", 48       "http://g.hiphotos.baidu.com/image/h%3D360/sign=a2540bdbf21f3a2945c8d3c8a925bce3/fd039245d688d43fa9943bf77f1ed21b0ef43bf1.jpg", 49       "http://p4.so.qhimg.com/bdr/_240_/t01d4c378e7c6bfbe69.jpg", 50       "http://p0.so.qhimg.com/bdr/_240_/t0160872a7d33df5735.jpg", 51       "http://p3.so.qhimg.com/bdr/_240_/t01473a131702c357dd.jpg" }; 52  53   @Override 54   protected void onCreate(Bundle savedInstanceState) { 55     super.onCreate(savedInstanceState); 56     setContentView(R.layout.activity_main); 57  58     activity = this; 59  60     data = new ArrayList<HashMap<String, Object>>(); 61     cache = new ArrayList<HashMap<String, Object>>(); 62     // 添加初始数据 63     for (int i = 0; i < 30; i++) { 64       HashMap<String, Object> map = new HashMap<String, Object>(); 65       map.put(KEY_IMAGE, BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher)); 66       map.put(KEY_TEXT, i); 67       data.add(map); 68     } 69  70     lv = (MyRefreshListview) findViewById(R.id.listview); 71  72     mMyAdapter = new MyAdapter(this, -1); 73  74     lv.setAdapter(mMyAdapter); 75  76     lv.setOnRefreshListener(new OnRefreshListener() { 77  78       @Override 79       public void ontop() { 80         // 随机加入一张图片 81         adddata(image_urls[random.nextInt(8)]); 82  83       } 84  85       @Override 86       public void onbuttom() { 87         // 没有设置缓存机制 88         new MyAsyncTaskBottom(image_urls[random.nextInt(8)]).execute(); 89       } 90     }); 91   } 92  93   private class MyAdapter extends ArrayAdapter<String> { 94     private LayoutInflater flater; 95     private Context context; 96  97     public MyAdapter(Context context, int resource) { 98  99       super(context, resource);100       this.context = context;101       flater = LayoutInflater.from(context);102 103     }104 105     @Override106     public int getCount() {107       return data.size();108     }109 110     @SuppressLint("InflateParams")111     @Override112     public View getView(int position, View convertView, ViewGroup parent) {113 114       if (convertView == null)115         convertView = flater.inflate(R.layout.list, null);116 117       ImageView iv = (ImageView) convertView.findViewById(R.id.image);118 119       iv.setImageBitmap((Bitmap) data.get(position).get(KEY_IMAGE));120 121       TextView tv = (TextView) convertView.findViewById(R.id.text);122 123       tv.setText(position + "原始数据");124 125       return convertView;126     }127 128   }129 130   private class MyAsyncTaskTop extends AsyncTask {131     private ProgressDialog pd;132     @SuppressWarnings("unused")133     private String url;134 135     public MyAsyncTaskTop(String url) {136       this.url = url;137     }138 139     @Override140     protected void onPreExecute() {141       // 设置加载进度条142       pd = new ProgressDialog(activity);143       pd.setProgressStyle(pd.STYLE_HORIZONTAL);144       pd.setMessage("正在加载。。。");145       pd.show();146     }147 148     @Override149     protected Object doInBackground(Object... params) {150 151       try {152         // 回调加载网络的类Loadnetimage153         Loadnetimage mLoadnetimage = new Loadnetimage();154 155         mLoadnetimage.SetLoadnetimageListener(new OnLoadnetimageListener() {156 157           @SuppressWarnings("unchecked")158           @Override159           public void LoadnetimageListener(int count, int total) {160             publishProgress(count, total);161 162           }163         });164         // 获取网络图片165         Bitmap bitmap = mLoadnetimage.loadRawDataFromURL(url);166         // 每次将图片和对应的地址放入HashMap167         HashMap<String, Object> map = new HashMap<String, Object>();168         // 将新加载图片放入缓存169         map.put(CACHE_KEY_IMAGE, bitmap);170         map.put(CACHE_KEY_TEXT, url);171 172         cache.add(map);173 174         return bitmap;175       } catch (Exception e) {176         e.printStackTrace();177       }178 179       return null;180 181     }182 183     @Override184     protected void onPostExecute(Object result) {185       addtop(result);186       pd.dismiss();187 188     }189 190     // 更新进度条191     @Override192     protected void onProgressUpdate(Object... values) {193       int count = (Integer) values[0];194       int total = (Integer) values[1];195 196       pd.setMax(total);197       pd.setProgress(count);198 199     }200 201   }202 203   @SuppressWarnings("unused")204   private class MyAsyncTaskBottom extends AsyncTask {205     private ProgressDialog pd;206     private String url;207 208     public MyAsyncTaskBottom(String url) {209       this.url = url;210     }211 212     @Override213     protected void onPreExecute() {214       // 设置进度条215       pd = new ProgressDialog(activity);216       // 样式217       pd.setProgressStyle(pd.STYLE_HORIZONTAL);218       pd.setMessage("正在加载。。。");219       pd.show();220 221     }222 223     @Override224     protected Object doInBackground(Object... params) {225       // 回调加载网络的类Loadnetimage226       Loadnetimage mLoadnetimage = new Loadnetimage();227       // 获取网络图片228       Bitmap bitmap;229       try {230         bitmap = mLoadnetimage.loadRawDataFromURL(url);231         return bitmap;232       } catch (Exception e) {233         e.printStackTrace();234       }235       return null;236     }237 238     @Override239     protected void onPostExecute(Object result) {240       addbottom(result);241       pd.dismiss();242 243     }244 245   }246 247   private void adddata(String url) {248     // 设置缓存机制249     Log.e("", "开始添加");250 251     for (int i = 0; i < cache.size(); i++) {252 253       HashMap<String, Object> map = cache.get(i);254       // 判断图片地址一样则载入缓存255       if (url.equals(map.get(CACHE_KEY_TEXT))) {256         Bitmap bitmap = (Bitmap) map.get(CACHE_KEY_IMAGE);257         addtop(bitmap);258         Log.e("", "载入缓存");259 260         return;261       }262 263     }264     // 否则从网络新加载265     Log.e("", "最新加载");266     new MyAsyncTaskTop(url).execute();267 268   }269 270   private void addtop(Object result) {271 272     // 新加载图片放入原始数据273     HashMap<String, Object> map = new HashMap<String, Object>();274     map.put(KEY_IMAGE, result);275     map.put(KEY_TEXT, data.size() + 1);276 277     data.add(0, map);278 279     mMyAdapter.notifyDataSetChanged();280   }281 282   private void addbottom(Object result) {283     HashMap<String, Object> map = new HashMap<String, Object>();284     map.put(KEY_IMAGE, result);285     map.put(KEY_TEXT, data.size() + 1);286 287     data.add(map);288 289     mMyAdapter.notifyDataSetChanged();290     // 添加数据后自动滚动到底部291     lv.setSelection(ListView.FOCUS_DOWN);292 293   }294 295 }

 1 package com.lixu.listviewrefresh; 2  3 import java.io.BufferedInputStream; 4 import java.io.ByteArrayOutputStream; 5 import java.io.InputStream; 6 import java.net.HttpURLConnection; 7 import java.net.URL; 8  9 import android.graphics.Bitmap;10 import android.graphics.BitmapFactory;11 12 public class Loadnetimage {13   // 设置回调机制14   15   private OnLoadnetimageListener mOnLoadnetimageListener;16 17   public Loadnetimage() {18 19   }20 21   public interface OnLoadnetimageListener {22     public void LoadnetimageListener(int count, int total);23   }24 25   public void SetLoadnetimageListener(OnLoadnetimageListener l) {26     mOnLoadnetimageListener = l;27   }28   29   30 31   public Bitmap loadRawDataFromURL(String u) throws Exception {32     33     URL url = new URL(u);34     HttpURLConnection conn = (HttpURLConnection) url.openConnection();35     // 设置请求的一些常用的参数36     conn.setReadTimeout(30000);37     conn.setConnectTimeout(30000);38     conn.setDoInput(true);39     conn.connect();40     // 获取图片总数41     int total = conn.getContentLength();42 43     InputStream is = conn.getInputStream();44     BufferedInputStream bis = new BufferedInputStream(is);45 46     ByteArrayOutputStream baos = new ByteArrayOutputStream();47     // 缓存2KB48     final int BUFFER_SIZE = 2 * 1024;49     final int EOF = -1;50 51     int count = 0;52 53     int c;54     byte[] buf = new byte[BUFFER_SIZE];55 56     while (true) {57       c = bis.read(buf);58       if (c == EOF)59         break;60       // 每次累加到现在为止我们下载了多少数据,以便于后面计算已经下载的数据占了总数量的百分比61       count = count + c;62       // 发布最新的数据,更新随后的进度条显示进度使用63       if (mOnLoadnetimageListener != null)64         mOnLoadnetimageListener.LoadnetimageListener(count, total);65       baos.write(buf, 0, c);66     }67 68     conn.disconnect();69     is.close();70 71     byte[] data = baos.toByteArray();72     baos.flush();73 74     Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);75 76     return bitmap;77   }78 79 }

 1 package com.lixu.listviewrefresh; 2  3 import android.content.Context; 4 import android.util.AttributeSet; 5 import android.widget.AbsListView; 6 import android.widget.ListView; 7  8 public class MyRefreshListview extends ListView { 9   private OnRefreshListener mOnRefreshListener;10 11   public MyRefreshListview(Context context, AttributeSet attrs) {12 13     super(context, attrs);14 15   }16 17   public interface OnRefreshListener {18 19     public void ontop();20 21     public void onbuttom();22   }23 24   public void setOnRefreshListener(OnRefreshListener l) {25     this.mOnRefreshListener = l;26 27     this.setOnScrollListener(new OnScrollListener() {28 29       private int firstVisibleItem, visibleItemCount, totalItemCount;30 31       @Override32       public void onScrollStateChanged(AbsListView view, int scrollState) {33         34         // 当滑动停止的时候判断35         if (OnScrollListener.SCROLL_STATE_IDLE == scrollState) {36           // 滑动到顶部时添加37           if (firstVisibleItem == 0) {38 39             mOnRefreshListener.ontop();40 41           }42           // 滑动到底部时添加43           else if ((firstVisibleItem + visibleItemCount) == totalItemCount) {44 45             mOnRefreshListener.onbuttom();46 47           }48         }49 50       }51 52       @Override53       public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {54 55         this.firstVisibleItem = firstVisibleItem;56         this.visibleItemCount = visibleItemCount;57         this.totalItemCount = totalItemCount;58 59       }60     });61 62   }63 }

 1 <RelativeLayout ="http://schemas.android.com/apk/res/android" 2   ="http://schemas.android.com/tools" 3   android:layout_width="match_parent" 4   android:layout_height="match_parent" 5   tools:context="com.lixu.listviewrefresh.MainActivity" > 6  7   <com.lixu.listviewrefresh.MyRefreshListview 8     android:id="@+id/listview" 9     android:layout_width="match_parent"10     android:layout_height="match_parent" />11 12 </RelativeLayout>

 1 <??> 2 <LinearLayout ="http://schemas.android.com/apk/res/android" 3   android:layout_width="match_parent" 4   android:layout_height="match_parent" 5   android:orientation="vertical" > 6  7   <ImageView 8     android:id="@+id/image" 9     android:layout_width="match_parent"10     android:layout_height="match_parent" />11 12   <TextView13     android:id="@+id/text"14     android:layout_width="match_parent"15     android:layout_height="match_parent" />16 17 </LinearLayout>

运行效果图: