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


选择图片文件夹的代码:



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





评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值