您的位置:首页 > 移动开发 > 微信开发

android 仿微信选择相册中的图片跟图片异步加载

2014-03-20 13:52 411 查看
选择图片文件夹的代码:



public class PickPhotoActivity extends BaseActivity implements OnClickListener{
public static final int PICK_PHOTO = 125;
private ArrayList<ImageData> selectedImageDatas = new ArrayList<ImageData>();
private String[] floderProjection = {
"_id",//图片ID
"_data",//图片uri
"bucket_display_name"//图片所在文件夹名字
};
private ArrayList<String> mFloderList = new ArrayList<String>();
private ListView mFloderListView;
private ImageButton back_btn,finish_btn;
private TextView title_tv,selectedNumber_tv;
private FloderAdapter adapter;
private int canSelectNumber = 9;

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.pick_photo_layout);
canSelectNumber = 9-getIntent().getIntExtra("seletedNumber", 0);
mFloderListView = (ListView)findViewById(R.id.floder_listView);
finish_btn = (ImageButton)findViewById(R.id.title_finish_ImageButton);
back_btn = (ImageButton)findViewById(R.id.back_imageButton);
title_tv =(TextView)findViewById(R.id.activity_title_textView);
title_tv.setText("选择图片");
back_btn.setOnClickListener(this);
finish_btn.setOnClickListener(this);
finish_btn.setVisibility(View.VISIBLE);
selectedNumber_tv = (TextView)findViewById(R.id.select_textView);
selectedNumber_tv.setText("您还可选择"+canSelectNumber+"张图片");

Cursor cursor = getContentResolver().query(Media.EXTERNAL_CONTENT_URI, floderProjection, null, null, null);

if (cursor!=null) {
cursor.moveToFirst();
for (int i = 0; i < cursor.getCount(); i++) {
if (!mFloderList.contains(cursor.getString(2))) {
mFloderList.add(cursor.getString(2));
}
cursor.moveToNext();
}

Log.d("PickPhotoActivity", "here is the floderlist size is===>" + mFloderList.size());
}
adapter =new FloderAdapter();
mFloderListView.setAdapter(adapter);
mFloderListView.setOnItemClickListener(new OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
Intent intent = new Intent(PickPhotoActivity.this, PickPhotoDetialActivity.class);
intent.putExtra("canSelectNumber", canSelectNumber);
intent.putExtra("floderName", mFloderList.get(arg2));
startActivityForResult(intent, PICK_PHOTO);

}
});
}

@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.back_imageButton:
setResult(RESULT_CANCELED);
finish();
break;
case R.id.title_finish_ImageButton:
Intent intent = new Intent(PickPhotoActivity.this,EditTravelActivity.class);
Bundle bundle =new Bundle();
bundle.putSerializable("selectedList", selectedImageDatas);
intent.putExtras(bundle);
setResult(EditTravelActivity.ALBUMS, intent);
finish();
break;
default:
break;
}
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PICK_PHOTO && resultCode == RESULT_OK) {
if (selectedImageDatas.size() != 0) {
selectedImageDatas.clear();
}
selectedImageDatas.addAll((ArrayList<ImageData>) data.getExtras().getSerializable("selectedList"));
}
selectedNumber_tv.setText("您选择了"+selectedImageDatas.size()+"张图片");
super.onActivityResult(requestCode, resultCode, data);
}

class FloderAdapter extends BaseAdapter{

@Override
public int getCount() {
// TODO Auto-generated method stub
return mFloderList.size();
}

@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return mFloderList.get(position);
}

@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = PickPhotoActivity.this.getLayoutInflater();
convertView=inflater.inflate(R.layout.pick_photo_list_item, null);
ImageView floderImage = (ImageView) convertView.findViewById(R.id.floder_image);
TextView floderName = (TextView)convertView.findViewById(R.id.floder_name);
TextView photoNumber = (TextView)convertView .findViewById(R.id.photo_number);
floderName.setText(mFloderList.get(position));
String image_path = null;
int imageCount = 0;
Cursor cursor = getContentResolver().query(Media.EXTERNAL_CONTENT_URI, floderProjection, "bucket_display_name = '" +mFloderList.get(position) + "'", null, null);
if (cursor !=null) {
imageCount =cursor.getCount();
cursor.moveToFirst();
image_path = cursor.getString(1);//图片路径
Log.d("PickPhoto", "the floder photo id is ===> " + image_path);
}
cursor.close();
photoNumber.setText(imageCount+" 张");
floderImage.setImageBitmap(getImageThumbnail(image_path,70,70));
return convertView;
}

}

@SuppressLint("NewApi")
private Bitmap getImageThumbnail(String imagePath, int width, int height) {
Bitmap bitmap = null;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
// 获取这个图片的宽和高,注意此处的bitmap为null
bitmap = BitmapFactory.decodeFile(imagePath, options);
options.inJustDecodeBounds = false; // 设为 false
// 计算缩放比
int h = options.outHeight;
int w = options.outWidth;
int beWidth = w / width;
int beHeight = h / height;
int be = 1;
if (beWidth < beHeight) {
be = beWidth;
} else {
be = beHeight;
}
if (be <= 0) {
be = 1;
}
options.inSampleSize = be;
// 重新读入图片,读取缩放后的bitmap,注意这次要把options.inJustDecodeBounds 设为 false
bitmap = BitmapFactory.decodeFile(imagePath, options);
// 利用ThumbnailUtils来创建缩略图,这里要指定要缩放哪个Bitmap对象
bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,
ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
return bitmap;
}

}


选择图片的代码:



public class PickPhotoDetialActivity extends BaseActivity implements OnClickListener{
private ArrayList<ImageData> selectedImageDatas = new ArrayList<ImageData>();
ArrayList<String> selectedIdList = new ArrayList<String>();
private String[] floderProjection = {
"_id",
"_data",
"bucket_display_name"
};
private ArrayList<String> mPhotoList = new ArrayList<String>();
private GridView mPhotoGridView;
private ImageButton back_btn,finish_btn;
private TextView title_tv,selectedNumber_tv;
private PhotoAdapter adapter;

private BasicImageAsynLoader asynLoader;

public Handler mAsynHandler=new Handler();
private int canSelectNumber = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pick_photo_detial);

canSelectNumber = getIntent().getIntExtra("canSelectNumber", 0);

asynLoader =new BasicImageAsynLoader(mAsynHandler, width);
mPhotoGridView = (GridView) findViewById(R.id.photo_grid);
finish_btn = (ImageButton)findViewById(R.id.title_finish_ImageButton);
back_btn = (ImageButton)findViewById(R.id.back_imageButton);
title_tv =(TextView)findViewById(R.id.activity_title_textView);
title_tv.setText("选择图片");
back_btn.setOnClickListener(this);
finish_btn.setOnClickListener(this);
finish_btn.setVisibility(View.VISIBLE);
selectedNumber_tv = (TextView)findViewById(R.id.select_textView);
selectedNumber_tv.setText("您还可选择"+canSelectNumber+"张图片");

Cursor cursor = getContentResolver().query(Media.EXTERNAL_CONTENT_URI, floderProjection, "bucket_display_name = '" +getIntent().getExtras().getString("floderName") + "'", null, null);
if (cursor !=null) {

cursor.moveToFirst();
for (int i = 0; i < cursor.getCount(); i++) {
mPhotoList.add(cursor.getString(1));
cursor.moveToNext();
}
}
cursor.close();
adapter = new PhotoAdapter();
mPhotoGridView.setAdapter(adapter);

}

@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.back_imageButton:
setResult(RESULT_CANCELED);
finish();
break;
case R.id.title_finish_ImageButton:
for (int i = 0; i < selectedIdList.size(); i++) {
ImageData data = new ImageData();
data.setUrl(selectedIdList.get(i));
selectedImageDatas.add(data);
}
Intent intent = new Intent(PickPhotoDetialActivity.this,PickPhotoActivity.class);
Bundle bundle =new Bundle();
bundle.putSerializable("selectedList", selectedImageDatas);
intent.putExtras(bundle);
setResult(RESULT_OK, intent);
finish();
break;
default:
break;
}
}

@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@SuppressLint({ "NewApi", "ShowToast" })
public class PhotoAdapter extends BaseAdapter {

@Override
public int getCount() {
return mPhotoList.size();
}

@Override
public Object getItem(int position) {
return mPhotoList.get(position);
}

@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}

class ViewHolder {
ImageButton pickBtn;
ImageView imageView;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final int index =position;
final ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
LayoutInflater inflater = PickPhotoDetialActivity.this.getLayoutInflater();
convertView=inflater.inflate(R.layout.pick_photo_grid_item, null);
holder.imageView = (ImageView)convertView.findViewById(R.id.image);
holder.pickBtn = (ImageButton) convertView.findViewById(R.id.pick_btn);
convertView.setTag(holder);
}  else {
holder = (ViewHolder) convertView.getTag();
}

getThumb(holder.imageView,mPhotoList.get(position));

holder.pickBtn.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
if (!selectedIdList.contains(mPhotoList.get(index))) {

if (selectedIdList.size() < canSelectNumber) {
selectedIdList.add(mPhotoList.get(index));
} else {
Toast.makeText(PickPhotoDetialActivity.this, "最多选择"+canSelectNumber+"张图片!", Toast.LENGTH_SHORT).show();
}
} else {
selectedIdList.remove(mPhotoList.get(index));
}
selectedNumber_tv.setText("你已选择了"+ selectedIdList.size()+"张图片!");
notifyDataSetChanged();

}
});

if (selectedIdList.contains(mPhotoList.get(index))) {
holder.pickBtn.setBackgroundResource(R.drawable.pick_photo_pressed);
//holder.pickBtn.setTag(1);

} else {
holder.pickBtn.setBackgroundResource(R.drawable.pick_photo_normal);
}

return convertView;
}

}
private void getThumb(final ImageView itemImage,String strPath) {
itemImage.setTag(strPath);
asynLoader.loadBitmap(itemImage, true, strPath);
}
// @SuppressLint("NewApi")

}


异步加载

import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map.Entry;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.graphics.Bitmap;
import android.os.Handler;
import android.util.Log;
import android.widget.ImageView;

/**
*
* @author hwang
*
*
*     */

public final class BasicImageAsynLoader {
private LoaderThread thread;// 加载图片并发消息通知更新界面的线程
private HashMap<String, SoftReference<Bitmap>> imageCache;// 图片对象缓存,key:图片的url
private boolean isphoto;
// private ExecutorService executorService = Executors.newFixedThreadPool(5);//这个线程池最好在引用该类的地方new新的,在引用的Activity关闭时关闭该线程池。
private Handler handler;// 界面Activity的Handler对象  e
private int width;

public BasicImageAsynLoader(Handler handler,int width) {
imageCache = new HashMap<String, SoftReference<Bitmap>>();
this.handler = handler;
this.width = width;
}

/**
* 加载图片前显示到指定的ImageView中,图片的url保存在视图对象的Tag中
*
* @param imageView
*            要显示图片的视图
* @param defaultBitmap
*            加载需要显示的提示正在加载的默认图片对象
*/
public void loadBitmap(final ImageView imageView, Boolean isPhoto,final String url,ExecutorService executorService) {
// 图片所对应的url,这个值在加载图片过程中很可能会被改变
// String url = (String) imageView.getTag();
Log.d("PVthumb","the url is===>"+url);
if (imageCache.containsKey(url)) {// 判断缓存中是否有
SoftReference<Bitmap> softReference = imageCache.get(url);
Bitmap bitmap = softReference.get();
if (bitmap != null) {// 如果图片对象不为空,则可挂接更新视图,并返回
imageView.setImageBitmap(bitmap);
return;
} else {// 如果为空,需要将其从缓存中删除(其bitmap对象已被回收释放,需要重新加载)
Log.e("TAG", "cache bitmap is null");
imageCache.remove(url);
}
}
isphoto=isPhoto;
//线程池加载
executorService.execute(new Runnable() {

@Override
public void run() {
final Bitmap bitmap;
if (isphoto) {
Log.d("Pvthumb","the url is====>>>"+url);
bitmap = CommonUtil.getImageThumbnail(url,null, width/4-1, width/4-1);// 此方法应该是从网络或sd卡中加载
Log.d("hwang","thebitmap is ==>"+bitmap);
}else {
bitmap =null;
}
// 将加载的图片放入缓存map中
imageCache.put(url, new SoftReference<Bitmap>(bitmap));
if (url == imageView.getTag()) {// 再次判断视图有没有复用
handler.post(new Runnable() {// 通过消息机制在主线程中更新UI
public void run() {
imageView.setImageBitmap(bitmap);
}
});
}
}

});
/*这个是单线程异步加载适合低端机型
// imageView.setImageBitmap(defaultBitmap);// 先显示一个提示正在加载的图片
if (thread == null) {// 加载线程不存在,线程还未启动,需要新建线程并启动
thread = new LoaderThread(imageView, url);
thread.start();
} else {// 如果存在,就调用线程对象去加载
thread.load(imageView, url);
} */
}

/**
* 释放缓存中所有的Bitmap对象,并将缓存清空
064      */
public void releaseBitmapCache() {
if (imageCache != null) {
for (Entry<String, SoftReference<Bitmap>> entry : imageCache.entrySet()) {
Bitmap bitmap = entry.getValue().get();
if (bitmap != null) {
bitmap.recycle();// 释放bitmap对象
}
}
imageCache.clear();
}
}

/**
* 加载图片并显示的线程
*/

public class LoaderThread extends Thread {
LinkedHashMap<String, ImageView> mTaskMap;// 需要加载图片并显示的图片视图对象任务链
private boolean mIsWait;// 标识是线程是否处于等待状态

public LoaderThread(ImageView imageView, String url) {
mTaskMap = new LinkedHashMap<String, ImageView>();
mTaskMap.put(url, imageView);
}

/**
* 处理某个视图的更新显示
*
* @param imageView
*/
public void load(ImageView imageView, String url) {
mTaskMap.remove(imageView);// 任务链中可能有,得先删除
mTaskMap.put(url, imageView);// 将其添加到任务中
if (mIsWait) {// 如果线程此时处于等待得唤醒线程去处理任务队列中待处理的任务
synchronized (this) {// 调用对象的notify()时必须同步
this.notify();
}
}
}

@Override
public void run() {
while (mTaskMap.size() > 0) {// 当队列中有数据时线程就要一直运行,一旦进入就要保证其不会跳出循环
mIsWait = false;
final String url  = mTaskMap.keySet().iterator().next();

final ImageView imageView = mTaskMap.remove(url);
if (imageView.getTag() == url) {// 判断视图有没有复用(一旦ImageView被复用,其tag值就会修改变)
final Bitmap bitmap;
if (isphoto) {
Log.d("Pvthumb","the url is====>>>"+url);
bitmap = CommonUtil.getImageThumbnail(url,null, width/4-1, width/4-1);// 此方法应该是从网络或sd卡中加载
Log.d("hwang","thebitmap is ==>"+bitmap);
}else {
bitmap =null;
}
// 将加载的图片放入缓存map中
imageCache.put(url, new SoftReference<Bitmap>(bitmap));
if (url == imageView.getTag()) {// 再次判断视图有没有复用
handler.post(new Runnable() {// 通过消息机制在主线程中更新UI
public void run() {
imageView.setImageBitmap(bitmap);
}
});
}
}
if (mTaskMap.isEmpty()) {// 当任务队列中没有待处理的任务时,线程进入等待状态
try {
mIsWait = true;// 标识线程的状态,必须在wait()方法之前
synchronized (this) {

this.wait();// 保用线程进入等待状态,直到有新的任务被加入时通知唤醒

}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: