本地图片选择器(picasso框架)

来源:互联网 发布:原生js返回顶部火箭 编辑:程序博客网 时间:2024/05/20 20:02

要点:

1.使用picasso框架,只需导入jar包

Picasso.with(mContext).load(R.drawable.picture_unselected).into((ImageView)mHolder.ibt);

2.在子线程里扫描系统图片

3.获得文件修改时间:file.lastModified()//long类型

4.Set无序且不重复!获取set的值

mDirPaths = new HashSet<String>();Iterator<String> i = mDirPaths.iterator();while(i.hasNext()) {i.next();// 值}

5.list1 = list2 (难点)
问题描述:

                // adapter = new ImageAdapter(this,paths);               // mGridView.setAdapter(adapter);              // paths和selectPaths都是list                 paths.clear();           //1.                 paths = selectPaths;     //2.                 for (String p : paths) { //3.                    Log.v("TAG", p);                }                adapter.notifyDataSetChanged(); // 4.         //  步骤3.根据打印结果,可以打印出值//  步骤4.但是adapet通知的时候,显示出来的数据为空(即paths不存在值)//  显然有点矛盾//  我的理解是,adapter适配的是适配堆内存,path一开始指向的就是这个堆//  内存。然后步骤1.paths.clear()将堆内存清空,之后步骤2.让paths//  指向别的堆内存。在步骤4.适配器通知的时候,依然是指向之前的堆内存//  (被清空),所以造成了看起来paths没有数据,然而循环打印paths却能//   打印出值,这一矛盾的现象。//              这里的解决方案是//              2.测试代码~(正确事例)//              paths.clear();//              for (String p : selectPaths) {//                  paths.add(p);//              }//              adapter.notifyDataSetChanged();

6.Viewholder的声明,设置点击监听的时候,如果Viewholder声明为全局变量,那么mHolder.ibt设置背景的时候会设置到别的item上去了。
这里在每次getView()时声明一个Viewholder可以解决。

7.接着6的案例,选中一个item时,滑动屏幕时,别的item也会被选中,这里的解决方案是getView()的时候图片全部设置为没被选中(初始状态),然后再点击监听里设置,如果选择则将图片路径作为tag存储在list里面,然后根据当前item的路径是否在list里面,有的话则设置图片为选择状态。


说明:

1.读取读取所有的本地图片
2.使用picasso加载图片
3.图片按修改时间排序(新修改的图片会在前面)


效果

这里写图片描述


代码

activity

package com.example.testpacasso;import java.io.File;import java.util.ArrayList;import java.util.Collections;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Set;import android.app.Activity;import android.content.ContentResolver;import android.database.Cursor;import android.net.Uri;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.provider.MediaStore;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.GridView;public class MainActivity extends Activity {    private GridView mGridView;    private ImageAdapter adapter;    // 图片路径, 有序    private List<String> paths;    // 扫描到的图片路径, 无序且不重复    private Set<String> mDirPaths ;    private Handler mHandler;    private Button mButton;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mHandler = new Handler(){            @Override            public void handleMessage(Message msg) {                adapter.notifyDataSetChanged();            }        };        initViews();        initDatas();        initEvent();    }    private void initEvent() {        mButton.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                // 获取选择图片的路径                List<String> selectPaths = adapter.getSelectPaths();                // 拿到图片路径之后根据自己的需求做处理                // 。。。。。                //  1.测试代码(显示空白,看起来paths没有值)                //  并且在adapter.notifyDataSetChanged();往下的代码都不会执行!但又没有异常抛出.//              paths.clear();//              paths = selectPaths;//              for (String p : paths) {//                  Log.v("TAG", p);//              }//              adapter.notifyDataSetChanged();                // 2.测试代码~(正确事例)//              paths.clear();//              for (String p : selectPaths) {//                  paths.add(p);//              }//              for (String p : paths) {//                  Log.v("TAG", p);//              }//              adapter.notifyDataSetChanged();            }        });    }    private void initViews() {        mGridView = (GridView) findViewById(R.id.gv);        mButton = (Button) findViewById(R.id.bt);    }    private void initDatas() {        // 获得图片的路径        paths = new ArrayList<String>();        adapter = new ImageAdapter(this,paths);        mGridView.setAdapter(adapter);        // 扫描图片        getImagePath();    }    private void getImagePath() {        // 开启线程查找图片        new Thread(new Runnable() {            @Override            public void run() {                // 1.所有图片的Uri                Uri mImgUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;                // 2.                ContentResolver cr = MainActivity.this.getContentResolver();                // 3.                Cursor cursor = cr.query(mImgUri, null,                        MediaStore.Images.Media.MIME_TYPE + "= ? or "                                + MediaStore.Images.Media.MIME_TYPE + "= ?",                        new String[] { "image/jpeg", "image/png" },                        MediaStore.Images.Media.DATE_MODIFIED);                // 4.                mDirPaths = new HashSet<String>();                while(cursor.moveToNext()) {                    String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));                    mDirPaths.add(path);                }                // 遍历set                Iterator<String> i = mDirPaths.iterator();                // 存储模型数据                List<ImageModel> mList = new ArrayList<ImageModel>();                ImageModel imageModel = null;                File file = null;                String path ;                while (i.hasNext()) {                    imageModel = new ImageModel();                    path = i.next();                    imageModel.setPath(path);                    file = new File(path);                    imageModel.setMotifyTime(file.lastModified());                    mList.add(imageModel);                }                // 按修改时间排序                // 创建时间数组                int length = mList.size();                long [] motify = new long[length];                for (int j = 0;j < length; j++) {                    motify[j] = mList.get(j).getMotifyTime();                }                // 快排排序                quickSort(motify,0,length-1);                // 根据排序,重新排序path(升序排列)                paths.clear();                for (int k = 0; k < length; k++) {                    for (int p = 0; p < mList.size(); p++) {                        if (mList.get(p).getMotifyTime() == motify[k]) {                            paths.add(mList.get(p).getPath()); //移除,避免修改时间相同的实体                            mList.remove(p);                            break;                        }                    }                }                // paths倒序排序                Collections.reverse(paths);                // handle                mHandler.sendEmptyMessage(0);            }        }).start();    }    // 快排1    private static void quickSort(long[] array,int beg,int end){          if(beg >= end || array == null)              return;          int p = partition(array, beg, end);          quickSort(array, beg, p-1);          quickSort(array, p+1, end);      }      // 快排2    private static int partition(long[] array,int beg,int end){          long last = array[end];          int i = beg -1;          for (int j = beg; j <= end-1; j++) {              if(array[j] <= last){                  i++;                  if(i != j){                      array[i] = array[i]^array[j];                      array[j] = array[i]^array[j];                      array[i] = array[i]^array[j];                  }              }          }          if((i+1) != end){              array[i+1] = array[i+1]^array[end];              array[end] = array[i+1]^array[end];              array[i+1] = array[i+1]^array[end];          }          return i+1;      }  }

adapter

package com.example.testpacasso;import java.io.File;import java.util.ArrayList;import java.util.List;import com.squareup.picasso.Picasso;import android.content.Context;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.View.OnClickListener;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageButton;import android.widget.ImageView;import android.widget.RelativeLayout;public class ImageAdapter extends BaseAdapter{    private Context mContext;    private List<String> paths;    private View view;//  private ViewHolder mHolder;  // 如果设置为全局变量,在点击监听部分会有与预期不符合的效果!    // 选中图片列表    private List<String> selectPaths;    public ImageAdapter(Context mContext, List<String> paths) {        this.mContext = mContext;        this.paths = paths;        selectPaths = new ArrayList<String>();    }    @Override    public int getCount() {        return paths.size();    }    @Override    public Object getItem(int position) {        return paths.get(position);    }    @Override    public long getItemId(int position) {        return 0;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        final int pos = position;        final ViewHolder mHolder;        if (convertView == null) {            view = LayoutInflater.from(mContext).inflate(R.layout.item, null); // 设置parent崩溃            mHolder = new ViewHolder();            mHolder.img = (ImageView) view.findViewById(R.id.iv);            mHolder.ibt = (ImageButton) view.findViewById(R.id.ib);            view.setTag(mHolder);        } else {            view = convertView;            mHolder = (ViewHolder) view.getTag();        }        // 加载图片        Picasso.with(mContext).load(new File(paths.get(position))).placeholder(R.drawable.ic_launcher).resize(500, 500)          .centerCrop().into(mHolder.img);        // 重置状态        Picasso.with(mContext).load(R.drawable.picture_unselected).into((ImageView)mHolder.ibt);        // 如果被选择,则改为选中状态        if (selectPaths.contains(paths.get(pos))) {            Picasso.with(mContext).load(R.drawable.pictures_selected).into((ImageView) mHolder.ibt);        }        // 点击图片打钩图片        mHolder.ibt.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                if (!selectPaths.contains(paths.get(pos))) {                    Picasso.with(mContext).load(R.drawable.pictures_selected).placeholder(R.drawable.picture_unselected).into((ImageView)mHolder.ibt);                    selectPaths.add(paths.get(pos));                } else {                    Picasso.with(mContext).load(R.drawable.picture_unselected).into((ImageView)mHolder.ibt);                    selectPaths.remove(paths.get(pos));                }            }        });        return view;    }     class ViewHolder {         ImageView img;         ImageButton ibt;     }      // 得到选中的图片     public List<String> getSelectPaths() {        return selectPaths;     }}

main_xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent" > <LinearLayout      android:layout_width="match_parent"     android:layout_height="40dp"     android:id="@+id/ll"     android:background="#2294D4">     <TextView          android:layout_width="0dp"         android:layout_height="match_parent"         android:layout_weight="8"         android:text="图片选择器"         android:gravity="center|left"         android:paddingLeft="10dp"         android:textColor="#fff"         android:textSize="20dp"/>     <Button          android:layout_width="0dp"         android:layout_height="match_parent"         android:layout_weight="2"         android:textColor="#fff"         android:text="确定"         android:id="@+id/bt"/> </LinearLayout>    <GridView         android:layout_below="@+id/ll"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:numColumns="3"        android:id="@+id/gv"/></RelativeLayout>

item.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"     >    <ImageView        android:id="@+id/iv"        android:layout_width="match_parent"        android:layout_height="100dp"        android:layout_margin="1dp"        android:scaleType="centerCrop"         />    <ImageButton        android:id="@+id/ib"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentRight="true"        android:layout_alignParentTop="true"        android:layout_marginRight="3dp"        android:layout_marginTop="3dp"        android:background="@null"        android:src="@drawable/picture_unselected" /></RelativeLayout>

ImageModel

package com.example.testpacasso;public class ImageModel{    // 路径    private String path;    // 修改时间    private long motifyTime;    public String getPath() {        return path;    }    public void setPath(String path) {        this.path = path;    }    public long getMotifyTime() {        return motifyTime;    }    public void setMotifyTime(long motifyTime) {        this.motifyTime = motifyTime;    }}

权限:

  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>

参考:http://blog.csdn.net/u010542146/article/details/50766471
还有网上的一些例子。


2016/06/01 更新

修改adapter类,添加点击事件,点击图片跳转至图片放大页面,可以左右滑动


ImageAdapter

package com.example.testpacasso;import java.io.File;import java.util.ArrayList;import java.util.List;import com.squareup.picasso.Picasso;import android.content.Context;import android.content.Intent;import android.os.Bundle;import android.view.LayoutInflater;import android.view.View;import android.view.View.OnClickListener;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageButton;import android.widget.ImageView;public class ImageAdapter extends BaseAdapter{    private Context mContext;    private List<String> paths;    private View view;//  private ViewHolder mHolder;  // 如果设置为全局变量,在点击监听部分会有与预期不符合的效果!    // 选中图片列表    private List<String> selectPaths;    public ImageAdapter(Context mContext, List<String> paths) {        this.mContext = mContext;        this.paths = paths;        selectPaths = new ArrayList<String>();    }    @Override    public int getCount() {        return paths.size();    }    @Override    public Object getItem(int position) {        return paths.get(position);    }    @Override    public long getItemId(int position) {        return 0;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        final int pos = position;        final ViewHolder mHolder;        if (convertView == null) {            view = LayoutInflater.from(mContext).inflate(R.layout.item, null); // 设置parent崩溃            mHolder = new ViewHolder();            mHolder.img = (ImageView) view.findViewById(R.id.iv);            mHolder.ibt = (ImageButton) view.findViewById(R.id.ib);            view.setTag(mHolder);        } else {            view = convertView;            mHolder = (ViewHolder) view.getTag();        }        // 加载图片        Picasso.with(mContext).load(new File(paths.get(position))).placeholder(R.drawable.ic_launcher).resize(500, 500)          .centerCrop().into(mHolder.img);        // 重置状态        Picasso.with(mContext).load(R.drawable.picture_unselected).into((ImageView)mHolder.ibt);        // 如果被选择,则改为选中状态        if (selectPaths.contains(paths.get(pos))) {            Picasso.with(mContext).load(R.drawable.pictures_selected).into((ImageView) mHolder.ibt);        }        // 点击图片打钩图片        mHolder.ibt.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                if (!selectPaths.contains(paths.get(pos))) {                    Picasso.with(mContext).load(R.drawable.pictures_selected).placeholder(R.drawable.picture_unselected).into((ImageView)mHolder.ibt);                    selectPaths.add(paths.get(pos));                } else {                    Picasso.with(mContext).load(R.drawable.picture_unselected).into((ImageView)mHolder.ibt);                    selectPaths.remove(paths.get(pos));                }            }        });        // 點擊放大        mHolder.img.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                Intent intent = new Intent(mContext, ImageActivity.class);                Bundle bundle = new Bundle();                ArrayList<String> arrayList = (ArrayList<String>) paths;                bundle.putStringArrayList(ImageActivity.EXTRA_URLS, arrayList);                bundle.putInt(ImageActivity.EXTRA_POSITION,pos);                intent.putExtra(ImageActivity.EXTRA_BUNDLE, bundle);                mContext.startActivity(intent);            }        });        return view;    }     class ViewHolder {         ImageView img;         ImageButton ibt;     }      // 得到选中的图片     public List<String> getSelectPaths() {        return selectPaths;     }}

ImageActivity

package com.example.testpacasso;import java.io.File;import java.util.ArrayList;import com.squareup.picasso.Picasso;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.BitmapFactory.Options;import android.os.AsyncTask;import android.os.Bundle;import android.support.v4.view.PagerAdapter;import android.support.v4.view.ViewPager;import android.support.v4.view.ViewPager.OnPageChangeListener;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;/** *  * @author yj<br> * 要使用这个类,必须传入一个包含图片路径的集合和要显示图片的位置position<br> * 该类可以左右滑动显示图片<br> */public class ImageActivity extends Activity {    private ViewPager mViewPager;    /**     * 当前图片的位置,作为显示的入口     */    private int position;    private PagerAdapter mAdapter;    /**     * 存放要显示图片的路径集合     */    private ArrayList<String> paths;    /**     * 存放ViewPager Item的下标,用户removeView时的判断依据     */    private ArrayList<Integer> arrayList;    /**     *  ViewPager是否在向左滑动     */    private boolean isLeft;    /**     * 临时存放的变量,用于判断ViewPager是向左滑动还是向右滑动     */    private int temp;    /**     * 屏幕的长     */    private int screenWidth;    /**     * 屏幕的寬     */    private int screenHeight;    public static String EXTRA_BUNDLE ="bundle";    public static String EXTRA_URLS ="urls";    public static String EXTRA_POSITION ="position";    @SuppressWarnings("unchecked")    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_image);        init();        initEvent();    }    private void init() {        screenWidth = getWindowManager().getDefaultDisplay().getWidth();        screenHeight = getWindowManager().getDefaultDisplay().getHeight();        arrayList = new ArrayList<Integer>();        // 获取数据,包括图片路径集合和当前图片路径所在的下标        Bundle bundle = getIntent().getBundleExtra(EXTRA_BUNDLE);        if (bundle != null) {            paths = (ArrayList<String>) bundle.get(EXTRA_URLS);            position = bundle.getInt(EXTRA_POSITION);        }        mViewPager = (ViewPager) findViewById(R.id.id_viewpager);        mAdapter = new PagerAdapter() {            @Override            public void destroyItem(ViewGroup container, int position,                    Object object) {                if (isLeft) {                    // 左滑                    container.removeViewAt(findSmallIndex());                    arrayList.remove(findSmallIndex());                } else {                    // 右滑                    container.removeViewAt(findBigIndex());                    arrayList.remove(findBigIndex());                }            }            @Override            public Object instantiateItem(ViewGroup container, int position) {                View view = LayoutInflater.from(ImageActivity.this).inflate(R.layout.image, null);                ImageView imageView = (ImageView) view.findViewById(R.id.iv_image);                String url = paths.get(position);                // 1.使用picasso 效果很好                Picasso.with(ImageActivity.this).load(new File(url)).centerInside().resize(screenWidth, screenHeight).into(imageView);//              // 2.使用异步加载, 效果一般, 不够picasso好//              MyTask myTask = new MyTask(imageView);//              myTask.execute(url, calculateInSampleSize(url)+"");                container.addView(view);                arrayList.add(position);                return view;            }            @Override            public boolean isViewFromObject(View arg0, Object arg1) {                return arg0 == arg1;            }            @Override            public int getCount() {                return paths.size();            }        };        mViewPager.setAdapter(mAdapter);        // 显示当前的图片        // 此刻ViewPager只会加载position前后的内容,即只有3个View        mViewPager.setCurrentItem(position);    }    private void initEvent() {        // 判断是手指像左滑动还是像右滑动                mViewPager.setOnPageChangeListener(new OnPageChangeListener() {                    @Override                    public void onPageSelected(int arg0) {                    }                    @Override                    public void onPageScrolled(int arg0, float arg1, int arg2) {                        // 经过测试发现                        // arg2在向左滑动时,arg2会不断增大,最后变为0,                        // arg2在向右滑动时,arg2会不断减小,最后变为0,                        if (arg2 != 0) {                            temp = arg2;                        } else {                            if (temp > 300) {                                isLeft = true;                            } else {                                isLeft = false;                            }                        }                    }                    @Override                    public void onPageScrollStateChanged(int arg0) {                    }                });    }    /**     * 找到列表最小item所在的小标     * @return     */    protected int findSmallIndex() {        int index = 0;        for (int i = 1; i < arrayList.size(); i++) {            if (arrayList.get(index) > arrayList.get(i)) {                index = i;            }        }        return index;    }    /**     * 找到列表里最大item所在的下标     * @return     */    protected int findBigIndex() {        int index = 0;        for (int i = 1; i < arrayList.size(); i++) {            if (arrayList.get(index) < arrayList.get(i)) {                index = i;            }        }        return index;    }    /**     *  没有使用到, 作为记录      */ //  /**//   * 计算合适的inSampleSize//   * //   * @param url//   * @param width//   * @param height//   * @return//   *///  private int calculateInSampleSize(String url) {//      Options options = new Options();//      options.inJustDecodeBounds = true;//      int inSampleSize = 1;//      BitmapFactory.decodeFile(url, options);//      int bitmapWidth = options.outWidth;//      int bitmapheight = options.outHeight;////      while (bitmapWidth / inSampleSize > screenWidth//              && bitmapheight / inSampleSize > screenHeight) {//          inSampleSize = inSampleSize * 2;//      }//      return inSampleSize;//  }    /**     *  没有使用到, 作为记录      *///      /**//       * 异步,防止卡顿//       * @author yj//       *//       *///      class MyTask extends AsyncTask<String, Void, Bitmap> {//          private ImageView view;//          public MyTask(ImageView view) {//              this.view = view;//          }    ////          @Override//          protected Bitmap doInBackground(String... params) {//              Options options = new Options();//              options.inSampleSize = Integer.parseInt(params[1]);//              Bitmap bitmap = BitmapFactory.decodeFile(params[0], options);//              return bitmap;//          }//          //          @Override//          protected void onPostExecute(Bitmap result) {//              super.onPostExecute(result);//              view.setImageBitmap(result);//          }//          //      }}

activity_image.xml

<RelativeLayout    android:layout_width="match_parent"    android:layout_height="match_parent"     xmlns:android="http://schemas.android.com/apk/res/android"     android:background="#000" >    <android.support.v4.view.ViewPager        android:id="@+id/id_viewpager"        android:layout_height="match_parent"        android:layout_width="match_parent">    </android.support.v4.view.ViewPager></RelativeLayout>

image

<RelativeLayout    android:layout_width="match_parent"    android:layout_height="match_parent"     xmlns:android="http://schemas.android.com/apk/res/android" >    <ImageView         android:layout_width="match_parent"        android:layout_height="match_parent"        android:id="@+id/iv_image"        /></RelativeLayout>
0 0
原创粉丝点击