Android listView 之万能Adapter

来源:互联网 发布:dnf校园网打团网络冲突 编辑:程序博客网 时间:2024/05/19 20:39

参考 http://blog.csdn.net/lmj623565791/article/details/38902805

上面的大神已经讲得很清楚了,这里小菜只是对它调用方式稍微做了修改,无需再new多个实体类,可直接读取远程(本地)数据,其实大致跟大神的原帖还是一样的。

下面直接贴代码了:

package com.cruze.commonadapter;import java.util.ArrayList;import java.util.List;import org.json.JSONException;import org.json.JSONObject;import com.example.zhy_baseadapterhelper.R;import android.app.Activity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.ListView;import android.widget.Toast;public class MainActivity extends Activity{private ListView mListView;private List<JSONObject> mDatas = new ArrayList<JSONObject>();// private CommonAdapter<JSONObject> mAdapter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initDatas();initListView();// mListView.setAdapter( new CommonAdapter<Bean>(// getApplicationContext(), mDatas, R.layout.item_list)// {// @Override// public void convert(ViewHolder helper, Bean item)// {// helper.setText(R.id.tv_title, item.getTitle());// helper.setText(R.id.tv_describe, item.getDesc());// helper.setText(R.id.tv_phone, item.getPhone());// helper.setText(R.id.tv_time, item.getTime());//// helper.getView(R.id.tv_title).setTag(item.getTitle());// helper.getView(R.id.tv_title).setOnClickListener(MainActivity.this);// }//// });}private void initListView() {mListView = (ListView) findViewById(R.id.id_lv_main);mListView.setAdapter(new CommonAdapter<JSONObject>(getApplicationContext(), mDatas, R.layout.item_list) {@Overridepublic void convert(ViewHolder helper, JSONObject item) {Log.e("refreshView", "item");try {helper.setText(R.id.tv_title, item.getString("title"));helper.setText(R.id.tv_describe, item.getString("context"));helper.setText(R.id.tv_phone, item.getString("phone"));helper.setText(R.id.tv_time, item.getString("time"));helper.getView(R.id.tv_title).setTag(item.getString("title"));helper.getView(R.id.tv_title).setOnClickListener(new MyListener(item.getInt("id")));} catch (JSONException e) {}}});}private void initDatas() {for (int i = 0; i < 5; i++) {JSONObject json = new JSONObject();try {json.put("id", i + 1);json.put("title", "美女" + i);json.put("context", "在食堂二楼女" + i);json.put("phone", "美女" + i);json.put("time", "2015" + i);} catch (JSONException e) {}mDatas.add(json);}// Bean bean = null;// bean = new Bean("美女一只", "周三早上捡到妹子一只,在食堂二楼", "10086", "20130240122");// mDatas.add(bean);// bean = new Bean("美女一捆", "周三早上捡到妹子一捆,在食堂三楼", "10086", "20130240122");// mDatas.add(bean);// bean = new Bean("比卡丘一个", "周三早上捡到比卡丘一个,在食堂一楼", "10086",// "20130240122");// mDatas.add(bean);// bean = new Bean("汉子一火车", "周三早上捡到xxxxxxxxxx,在xxx",// "10086","20130240122");// mDatas.add(bean);}class MyListener implements OnClickListener {private int id;public MyListener(int id) {this.id = id;}@Overridepublic void onClick(View v) {if (v.getTag().toString().equals("美女0")) {Toast.makeText(MainActivity.this, "lalal", 500).show();return;}Toast.makeText(MainActivity.this, id + "", 500).show();}}}
以上代码注释部分为原帖内容
package com.cruze.commonadapter;import java.util.List;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;public abstract class CommonAdapter<T> extends BaseAdapter{protected LayoutInflater mInflater;protected Context mContext;protected List<T> mDatas;protected final int mItemLayoutId;public CommonAdapter(Context context, List<T> mDatas, int itemLayoutId){this.mContext = context;this.mInflater = LayoutInflater.from(mContext);this.mDatas = mDatas;this.mItemLayoutId = itemLayoutId;}@Overridepublic int getCount(){return mDatas.size();}@Overridepublic T getItem(int position){return mDatas.get(position);}@Overridepublic long getItemId(int position){return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent){final ViewHolder viewHolder = getViewHolder(position, convertView,parent);convert(viewHolder, getItem(position));return viewHolder.getConvertView();}public abstract void convert(ViewHolder helper, T item);private ViewHolder getViewHolder(int position, View convertView,ViewGroup parent){return ViewHolder.get(mContext, convertView, parent, mItemLayoutId,position);}}

package com.cruze.commonadapter;import java.lang.reflect.Field;import java.util.LinkedList;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Semaphore;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.support.v4.util.LruCache;import android.util.DisplayMetrics;import android.util.Log;import android.view.ViewGroup.LayoutParams;import android.widget.ImageView;public class ImageLoader{/** * 图片缓存的核心类 */private LruCache<String, Bitmap> mLruCache;/** * 线程池 */private ExecutorService mThreadPool;/** * 线程池的线程数量,默认为1 */private int mThreadCount = 1;/** * 队列的调度方式 */private Type mType = Type.LIFO;/** * 任务队列 */private LinkedList<Runnable> mTasks;/** * 轮询的线程 */private Thread mPoolThread;private Handler mPoolThreadHander;/** * 运行在UI线程的handler,用于给ImageView设置图片 */private Handler mHandler;/** * 引入一个值为1的信号量,防止mPoolThreadHander未初始化完成 */private volatile Semaphore mSemaphore = new Semaphore(1);/** * 引入一个值为1的信号量,由于线程池内部也有一个阻塞线程,防止加入任务的速度过快,使LIFO效果不明显 */private volatile Semaphore mPoolSemaphore;private static ImageLoader mInstance;/** * 队列的调度方式 *  * @author zhy *  */public enum Type{FIFO, LIFO}/** * 单例获得该实例对象 *  * @return */public static ImageLoader getInstance(){if (mInstance == null){synchronized (ImageLoader.class){if (mInstance == null){mInstance = new ImageLoader(1, Type.LIFO);}}}return mInstance;}private ImageLoader(int threadCount, Type type){init(threadCount, type);}private void init(int threadCount, Type type){// loop threadmPoolThread = new Thread(){@Overridepublic void run(){try{// 请求一个信号量mSemaphore.acquire();} catch (InterruptedException e){}Looper.prepare();mPoolThreadHander = new Handler(){@Overridepublic void handleMessage(Message msg){mThreadPool.execute(getTask());try{mPoolSemaphore.acquire();} catch (InterruptedException e){}}};// 释放一个信号量mSemaphore.release();Looper.loop();}};mPoolThread.start();// 获取应用程序最大可用内存int maxMemory = (int) Runtime.getRuntime().maxMemory();int cacheSize = maxMemory / 8;mLruCache = new LruCache<String, Bitmap>(cacheSize){@Overrideprotected int sizeOf(String key, Bitmap value){return value.getRowBytes() * value.getHeight();};};mThreadPool = Executors.newFixedThreadPool(threadCount);mPoolSemaphore = new Semaphore(threadCount);mTasks = new LinkedList<Runnable>();mType = type == null ? Type.LIFO : type;}/** * 加载图片 *  * @param path * @param imageView */public void loadImage(final String path, final ImageView imageView){// set tagimageView.setTag(path);// UI线程if (mHandler == null){mHandler = new Handler(){@Overridepublic void handleMessage(Message msg){ImgBeanHolder holder = (ImgBeanHolder) msg.obj;ImageView imageView = holder.imageView;Bitmap bm = holder.bitmap;String path = holder.path;if (imageView.getTag().toString().equals(path)){imageView.setImageBitmap(bm);}}};}Bitmap bm = getBitmapFromLruCache(path);if (bm != null){ImgBeanHolder holder = new ImgBeanHolder();holder.bitmap = bm;holder.imageView = imageView;holder.path = path;Message message = Message.obtain();message.obj = holder;mHandler.sendMessage(message);} else{addTask(new Runnable(){@Overridepublic void run(){ImageSize imageSize = getImageViewWidth(imageView);int reqWidth = imageSize.width;int reqHeight = imageSize.height;Bitmap bm = decodeSampledBitmapFromResource(path, reqWidth,reqHeight);addBitmapToLruCache(path, bm);ImgBeanHolder holder = new ImgBeanHolder();holder.bitmap = getBitmapFromLruCache(path);holder.imageView = imageView;holder.path = path;Message message = Message.obtain();message.obj = holder;// Log.e("TAG", "mHandler.sendMessage(message);");mHandler.sendMessage(message);mPoolSemaphore.release();}});}}/** * 添加一个任务 *  * @param runnable */private synchronized void addTask(Runnable runnable){try{// 请求信号量,防止mPoolThreadHander为nullif (mPoolThreadHander == null)mSemaphore.acquire();} catch (InterruptedException e){}mTasks.add(runnable);mPoolThreadHander.sendEmptyMessage(0x110);}/** * 取出一个任务 *  * @return */private synchronized Runnable getTask(){if (mType == Type.FIFO){return mTasks.removeFirst();} else if (mType == Type.LIFO){return mTasks.removeLast();}return null;}/** * 单例获得该实例对象 *  * @return */public static ImageLoader getInstance(int threadCount, Type type){if (mInstance == null){synchronized (ImageLoader.class){if (mInstance == null){mInstance = new ImageLoader(threadCount, type);}}}return mInstance;}/** * 根据ImageView获得适当的压缩的宽和高 *  * @param imageView * @return */private ImageSize getImageViewWidth(ImageView imageView){ImageSize imageSize = new ImageSize();final DisplayMetrics displayMetrics = imageView.getContext().getResources().getDisplayMetrics();final LayoutParams params = imageView.getLayoutParams();int width = params.width == LayoutParams.WRAP_CONTENT ? 0 : imageView.getWidth(); // Get actual image widthif (width <= 0)width = params.width; // Get layout width parameterif (width <= 0)width = getImageViewFieldValue(imageView, "mMaxWidth"); // Check// maxWidth// parameterif (width <= 0)width = displayMetrics.widthPixels;int height = params.height == LayoutParams.WRAP_CONTENT ? 0 : imageView.getHeight(); // Get actual image heightif (height <= 0)height = params.height; // Get layout height parameterif (height <= 0)height = getImageViewFieldValue(imageView, "mMaxHeight"); // Check// maxHeight// parameterif (height <= 0)height = displayMetrics.heightPixels;imageSize.width = width;imageSize.height = height;return imageSize;}/** * 从LruCache中获取一张图片,如果不存在就返回null。 */private Bitmap getBitmapFromLruCache(String key){return mLruCache.get(key);}/** * 往LruCache中添加一张图片 *  * @param key * @param bitmap */private void addBitmapToLruCache(String key, Bitmap bitmap){if (getBitmapFromLruCache(key) == null){if (bitmap != null)mLruCache.put(key, bitmap);}}/** * 计算inSampleSize,用于压缩图片 *  * @param options * @param reqWidth * @param reqHeight * @return */private int calculateInSampleSize(BitmapFactory.Options options,int reqWidth, int reqHeight){// 源图片的宽度int width = options.outWidth;int height = options.outHeight;int inSampleSize = 1;if (width > reqWidth && height > reqHeight){// 计算出实际宽度和目标宽度的比率int widthRatio = Math.round((float) width / (float) reqWidth);int heightRatio = Math.round((float) width / (float) reqWidth);inSampleSize = Math.max(widthRatio, heightRatio);}return inSampleSize;}/** * 根据计算的inSampleSize,得到压缩后图片 *  * @param pathName * @param reqWidth * @param reqHeight * @return */private Bitmap decodeSampledBitmapFromResource(String pathName,int reqWidth, int reqHeight){// 第一次解析将inJustDecodeBounds设置为true,来获取图片大小final BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeFile(pathName, options);// 调用上面定义的方法计算inSampleSize值options.inSampleSize = calculateInSampleSize(options, reqWidth,reqHeight);// 使用获取到的inSampleSize值再次解析图片options.inJustDecodeBounds = false;Bitmap bitmap = BitmapFactory.decodeFile(pathName, options);return bitmap;}private class ImgBeanHolder{Bitmap bitmap;ImageView imageView;String path;}private class ImageSize{int width;int height;}/** * 反射获得ImageView设置的最大宽度和高度 *  * @param object * @param fieldName * @return */private static int getImageViewFieldValue(Object object, String fieldName){int value = 0;try{Field field = ImageView.class.getDeclaredField(fieldName);field.setAccessible(true);int fieldValue = (Integer) field.get(object);if (fieldValue > 0 && fieldValue < Integer.MAX_VALUE){value = fieldValue;Log.e("TAG", value + "");}} catch (Exception e){}return value;}}


package com.cruze.commonadapter;import android.content.Context;import android.graphics.Bitmap;import android.util.SparseArray;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.TextView;import com.cruze.commonadapter.ImageLoader.Type;public class ViewHolder{private final SparseArray<View> mViews;private int mPosition;private View mConvertView;private ViewHolder(Context context, ViewGroup parent, int layoutId,int position){this.mPosition = position;this.mViews = new SparseArray<View>();mConvertView = LayoutInflater.from(context).inflate(layoutId, parent,false);// setTagmConvertView.setTag(this);}/** * 拿到一个ViewHolder对象 *  * @param context * @param convertView * @param parent * @param layoutId * @param position * @return */public static ViewHolder get(Context context, View convertView,ViewGroup parent, int layoutId, int position){if (convertView == null){return new ViewHolder(context, parent, layoutId, position);}return (ViewHolder) convertView.getTag();}public View getConvertView(){return mConvertView;}/** * 通过控件的Id获取对于的控件,如果没有则加入views *  * @param viewId * @return */public <T extends View> T getView(int viewId){View view = mViews.get(viewId);if (view == null){view = mConvertView.findViewById(viewId);mViews.put(viewId, view);}return (T) view;}/** * 为TextView设置字符串 *  * @param viewId * @param text * @return */public ViewHolder setText(int viewId, String text){TextView view = getView(viewId);view.setText(text);return this;}/** * 为ImageView设置图片 *  * @param viewId * @param drawableId * @return */public ViewHolder setImageResource(int viewId, int drawableId){ImageView view = getView(viewId);view.setImageResource(drawableId);return this;}/** * 为ImageView设置图片 *  * @param viewId * @param drawableId * @return */public ViewHolder setImageBitmap(int viewId, Bitmap bm){ImageView view = getView(viewId);view.setImageBitmap(bm);return this;}/** * 为ImageView设置图片 *  * @param viewId * @param drawableId * @return */public ViewHolder setImageByUrl(int viewId, String url){ImageLoader.getInstance(3, Type.LIFO).loadImage(url,(ImageView) getView(viewId));return this;}public int getPosition(){return mPosition;}}
本博客因为制作稍微修改,就算做转载吧,开篇已注明出处,各位同学可以去看看原帖

之后楼主会补上自己一直用的封装的adapter和封装的listview(带有下拉刷新功能的哦),很期待吧,下篇博文见!!!




0 0
原创粉丝点击