android学习

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 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;
 }
}

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学习)