android学习
2015-06-09 00:00
323 查看
摘要: android学习
ViewHolder
ImageLoader
ViewHolder
package com.zhy.utils; 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.zhy.utils.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); // setTag mConvertView.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) { ViewHolder holder = null; if (convertView == null) { holder = new ViewHolder(context, parent, layoutId, position); } else { holder = (ViewHolder) convertView.getTag(); holder.mPosition = position; } return holder; } 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 drawabl 3ff0 eId * @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; } }
ImageLoader
package com.zhy.utils; 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; private int mThreadCount = 1; private Type mType = Type.LIFO; private LinkedList<Runnable> mTasks; private Thread mPoolThread; private Handler mPoolThreadHander; private Handler mHandler; private volatile Semaphore mSemaphore = new Semaphore(0); private volatile Semaphore mPoolSemaphore; private static ImageLoader mInstance; public enum Type { FIFO, LIFO } 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 thread mPoolThread = new Thread() { @Override public void run() { Looper.prepare(); mPoolThreadHander = new Handler() { @Override public 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) { @Override protected 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; } public void loadImage(final String path, final ImageView imageView) { // set tag imageView.setTag(path); // UI线程 if (mHandler == null) { mHandler = new Handler() { @Override public 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() { @Override public 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(); } }); } } private synchronized void addTask(Runnable runnable) { try { // 请求信号量,防止mPoolThreadHander为null if (mPoolThreadHander == null) mSemaphore.acquire(); } catch (InterruptedException e) { } mTasks.add(runnable); mPoolThreadHander.sendEmptyMessage(0x110); } private synchronized Runnable getTask() { if (mType == Type.FIFO) { return mTasks.removeFirst(); } else if (mType == Type.LIFO) { return mTasks.removeLast(); } return null; } public static ImageLoader getInstance(int threadCount, Type type) { if (mInstance == null) { synchronized (ImageLoader.class) { if (mInstance == null) { mInstance = new ImageLoader(threadCount, type); } } } return mInstance; } 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 width if (width <= 0) width = params.width; // Get layout width parameter if (width <= 0) width = getImageViewFieldValue(imageView, "mMaxWidth"); // Check // maxWidth // parameter if (width <= 0) width = displayMetrics.widthPixels; int height = params.height == LayoutParams.WRAP_CONTENT ? 0 : imageView .getHeight(); // Get actual image height if (height <= 0) height = params.height; // Get layout height parameter if (height <= 0) height = getImageViewFieldValue(imageView, "mMaxHeight"); // Check // maxHeight // parameter if (height <= 0) height = displayMetrics.heightPixels; imageSize.width = width; imageSize.height = height; return imageSize; } private Bitmap getBitmapFromLruCache(String key) { return mLruCache.get(key); } private void addBitmapToLruCache(String key, Bitmap bitmap) { if (getBitmapFromLruCache(key) == null) { if (bitmap != null) mLruCache.put(key, bitmap); } } 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; } 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; } 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; } }
相关文章推荐
- android学习2
- android学习3
- Android 众多的布局属性详解
- android 源码下载
- Android信息处理机制
- Android 点击图片全屏
- Android系统各版本及代号
- android NDk初步学习以及某些小问题的解决方法备忘 二
- Android系统启动过程全解析
- vmbox-android
- Android源代码分析要看这18本书
- Android是如何在不同屏幕上适配图片的 -- 或控件大小
- Android NDK(学习笔记四)—— 在NDK开发中JNI打印Log信息
- android顺序广播
- Android模拟器与局域网通信
- Android入门---下拉刷新上拉加载更多策略的实现
- android 中的 scrollView 控件的默认位置和子控件的焦点冲突
- Android性能优化第三篇--java程序优化
- Android中Anmation运动时的监听方法
- Android学习笔记(九)