现在的app都需要图片选择器,网上有很多开源的代码,可有时候要根据需求来修改界面,所以要知道图片选择器的原理,图片选择器的实现原理很简单,只要使用ContentResolver这个类就可以了,使用方法有点像数据库通过query函数进行查询,也用到getColumnIndex这个函数,上代码
既然要获取图片,当然要权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
定义图片类Image.java
public class Image { private String path; private String name; private long time; public Image(String path,String name,long time){ this.path = path; this.name = name; this.time = time; } public Image(){ } public String getPath() { return path; } public void setPath(String path) { this.path = path; } public String getName() { return name; } public void setName(String name) { this.name = name; } public long getTime() { return time; } public void setTime(long time) { this.time = time; } }
定义文件夹类Folder.java
public class Folder { private String name; private List<Image> images; public Folder(String name,List<Image> images){ this.name = name; this.images = images; } public String getName() { return name; } public void setName(String name) { this.name = name; } public List<Image> getImages() { return images; } public void setImages(List<Image> images) { this.images = images; } }
MainActivity.java
public class MainActivity extends AppCompatActivity { private String[] denied; private String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { ArrayList<String> list = new ArrayList<>(); for (int i = 0; i < permissions.length; i++) { if (PermissionChecker.checkSelfPermission(this, permissions[i]) == PackageManager.PERMISSION_DENIED) { list.add(permissions[i]); } } if (list.size() != 0) { denied = new String[list.size()]; for (int i = 0; i < list.size(); i++) { denied[i] = list.get(i); ActivityCompat.requestPermissions(this, denied, 5); } } else { init(); } } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode == 5) { boolean isDenied = false; for (int i = 0; i < denied.length; i++) { String permission = denied[i]; for (int j = 0; j < permissions.length; j++) { if (permissions[j].equals(permission)) { if (grantResults[j] != PackageManager.PERMISSION_GRANTED) { isDenied = true; break; } } } } if (isDenied) { Toast.makeText(this, "请开启权限", Toast.LENGTH_SHORT).show(); } else { init(); } } super.onRequestPermissionsResult(requestCode, permissions, grantResults); } private static final String allImage = "全部图片"; private HashMap<String,Folder> imageFolders = new HashMap<>(); private List<String> folders = new ArrayList<>(); private ImageAdapter imageAdapter; private ListView listView; private Button button; private void init(){ systemImages(); RecyclerView recyclerView = findViewById(R.id.recycler_view); recyclerView.setLayoutManager(new GridLayoutManager(this,4)); imageAdapter = new ImageAdapter(this,imageFolders.get(allImage).getImages()); recyclerView.setAdapter(imageAdapter); listView = findViewById(R.id.list_view); listView.setAdapter(new ListViewAdapter(this)); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { String key = folders.get(i); Folder folder = imageFolders.get(key); button.setText(folder.getName()); imageAdapter.setList(folder.getImages()); imageAdapter.notifyDataSetChanged(); listView.setVisibility(View.INVISIBLE); } }); button = findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { listView.setVisibility(View.VISIBLE); } }); button.setText(allImage); } //获取所有图片 public void systemImages(){ ContentResolver cr = this.getContentResolver(); Cursor cursor = cr.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null, MediaStore.Images.Media.DEFAULT_SORT_ORDER); List<Image> images = new ArrayList<>(); Folder allImageFolder = new Folder(allImage, images); imageFolders.put(allImage,allImageFolder); folders.add(allImage); if (cursor != null) { if (cursor.moveToFirst()) { while (!cursor.isAfterLast()) { String fileName = cursor .getString(cursor .getColumnIndex(MediaStore.Images.Media.DISPLAY_NAME)); String path = cursor.getString(cursor .getColumnIndex(MediaStore.Images.Media.DATA)); Point point = getSize(path); if(isSize(point.x,point.y)){ File file = new File(path); if (accept(file)) { Image image = new Image(path,fileName,file.lastModified()); String key = path.substring(0, path.lastIndexOf(File.separator)); List<Image> list; if (imageFolders.containsKey(key)) { list = imageFolders.get(key).getImages(); } else { list = new ArrayList<>(); Folder folder = new Folder(key.substring(key.lastIndexOf(File.separator) + 1, key.length()), list); imageFolders.put(key, folder); folders.add(key); } list.add(image); images.add(image); } } cursor.moveToNext(); } } if (!cursor.isClosed()) { cursor.close(); } } for (String key : imageFolders.keySet()) { List<Image> list = imageFolders.get(key).getImages(); Collections.sort(list, new FileComparator()); } } //判断是否是图片,没想到好的方法,就用文件名来判断 public boolean accept(File f) { String tmp = f.getName().toLowerCase(); if (tmp.endsWith(".png") || tmp.endsWith(".jpg") || tmp.endsWith(".jpeg") || tmp.endsWith(".gif")) { return true; } return false; } //排序按时间排序 private class FileComparator implements Comparator<Image> { @Override public int compare(Image lhs, Image rhs) { if (lhs.getTime() < rhs.getTime()) { return 1; } else if(lhs.getTime() > rhs.getTime()){ return -1; }else{ return 0; } } } //计算图片大小 private Point getSize(String filePath){ BitmapFactory.Options bmFactoryOptions = new BitmapFactory.Options(); bmFactoryOptions.inJustDecodeBounds = true; BitmapFactory.decodeFile(filePath, bmFactoryOptions); return new Point(bmFactoryOptions.outWidth,bmFactoryOptions.outHeight); } //过滤太小的图片 private boolean isSize(int width,int height){ if(height < 200){ return false; }else if(width < 200){ return false; }else if(width*1.0f / height < 0.5){ return false; }else{ return true; } } //布局 class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.ImageViewHolder>{ private Context context; private List<Image> list; public ImageAdapter(Context context,List<Image> list){ this.context = context; this.list = list; } public void setList(List<Image> list) { this.list = list; } @Override public ImageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { ImageViewHolder holder = new ImageViewHolder(LayoutInflater.from(context).inflate(R.layout.item_image, parent, false)); return holder; } @Override public void onBindViewHolder(ImageViewHolder holder, int position) { Glide.with(context).asBitmap().load(list.get(position).getPath()).thumbnail(0.1f).into(holder.iv); } @Override public int getItemCount() { return list.size(); } class ImageViewHolder extends RecyclerView.ViewHolder { ImageView iv; public ImageViewHolder(View view) { super(view); iv = view.findViewById(R.id.image_view); } } } private class ListViewAdapter extends BaseAdapter { private LayoutInflater inflater = null; private Context context; public ListViewAdapter(Context context) { this.context = context; inflater = LayoutInflater.from(context); } @Override public int getCount() { return folders.size(); } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { final ViewHolder holder; if (convertView == null) { convertView = inflater.inflate(R.layout.item_folder, null); holder = new ViewHolder(); holder.textView = convertView.findViewById(R.id.text_view); holder.imageView = convertView.findViewById(R.id.image_view); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } String key = folders.get(position); Folder folder = imageFolders.get(key); holder.textView.setText(folder.getName()); Glide.with(context).asBitmap().load(folder.getImages().get(0).getPath()).thumbnail(0.1f).into(holder.imageView); return convertView; } private class ViewHolder { TextView textView; ImageView imageView; } } }
systemImages()函数内就是获取图片路径的方法了
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.selectimage.MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <RelativeLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"> <android.support.v7.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent"/> <ListView android:id="@+id/list_view" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#fff" android:visibility="invisible"/> </RelativeLayout> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> </android.support.constraint.ConstraintLayout>
item_image.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <com.example.selectimage.SquareImageView android:id="@+id/image_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:scaleType="centerCrop" /> </RelativeLayout>
item_folder.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <TextView android:id="@+id/text_view" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="3" /> <com.example.selectimage.SquareImageView android:id="@+id/image_view" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:scaleType="centerCrop" /> </LinearLayout>
SquareImageView.java是为了自适应宽度,使图片为正方形
public class SquareImageView extends ImageView { public SquareImageView(Context context) { super(context); } public SquareImageView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if(getMeasuredWidth() != 0){ setMeasuredDimension(getMeasuredWidth(),getMeasuredWidth()); } } }
至于Glide可以去网上找教程,很简单的
这只是个简陋的页面,现在可以根据需求来随便更改了