您的位置:首页 > 其它

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

2016-05-17 14:12 375 查看

要点:

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"/>


参考:/article/10877492.html

还有网上的一些例子。

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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: