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 @Override 106 public int getCount() { 107 return data.size(); 108 } 109 110 @SuppressLint("InflateParams") 111 @Override 112 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 @Override 140 protected void onPreExecute() { 141 // 设置加载进度条 142 pd = new ProgressDialog(activity); 143 pd.setProgressStyle(pd.STYLE_HORIZONTAL); 144 pd.setMessage("正在加载。。。"); 145 pd.show(); 146 } 147 148 @Override 149 protected Object doInBackground(Object... params) { 150 151 try { 152 // 回调加载网络的类Loadnetimage 153 Loadnetimage mLoadnetimage = new Loadnetimage(); 154 155 mLoadnetimage.SetLoadnetimageListener(new OnLoadnetimageListener() { 156 157 @SuppressWarnings("unchecked") 158 @Override 159 public void LoadnetimageListener(int count, int total) { 160 publishProgress(count, total); 161 162 } 163 }); 164 // 获取网络图片 165 Bitmap bitmap = mLoadnetimage.loadRawDataFromURL(url); 166 // 每次将图片和对应的地址放入HashMap 167 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 @Override 184 protected void onPostExecute(Object result) { 185 addtop(result); 186 pd.dismiss(); 187 188 } 189 190 // 更新进度条 191 @Override 192 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 @Override 213 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 @Override 224 protected Object doInBackground(Object... params) { 225 // 回调加载网络的类Loadnetimage 226 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 @Override 239 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 // 缓存2KB 48 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 @Override 32 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 @Override 53 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 }
xml文件:
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="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 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="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 <TextView 13 android:id="@+id/text" 14 android:layout_width="match_parent" 15 android:layout_height="match_parent" /> 16 17 </LinearLayout>
运行效果图:
时间: 2024-10-04 11:47:10