版权声明:本文为HaiyuKing原创文章,转载请注明出处!

前言

本Demo使用的是PhotoPicker 0.9.12版本,里面集成的glide版本号是4.1.1。这里就不进行特殊的个性化处理了(比如新增NewImagePagerDialogFragment.java用于对话框样式预览图片、新增NewPhotoPickerFragment.java用于单独作为自定义DialogFragment的其中一个Fragment和其他Fragment共存),而是记录下使用步骤(当然了,github上讲解的很清楚了,大家可以直接参考《donglua/PhotoPicker》)。

不过,本文对PhotoPicker进行了简单的修改,对UI进行了部分修改。【所以本Demo最后使用的是方式2——通过引入PhotoPicker这个module的方式】

效果图

  

代码分析

引入PhotoPicker有两种方式【二选一】

1、通过Gradle方式,在APP的build.gradle中引用【见导入步骤】

2、下载整个压缩包,然后导入PhotoPicker的module,然后修改图片资源

2.1、下载压缩包

2.2、导入PhotoPicker的Module

提示下面的错误:

2.3、解决Plugin with id 'com.novoda.bintray-release' not found.问题

在项目的build.gradle文件中添加以下代码

  1. // Top-level build file where you can add configuration options common to all sub-projects/modules.
  2.  
  3. buildscript {
  4.  
  5. repositories {
  6. google()
  7. jcenter()
  8. }
  9. dependencies {
  10. classpath 'com.android.tools.build:gradle:3.0.1'
  11. //解决PhotoPicker的Plugin with id 'com.novoda.bintray-release' not found.
  12. classpath 'com.novoda:bintray-release:0.5.0'
  13. // NOTE: Do not place your application dependencies here; they belong
  14. // in the individual module build.gradle files
  15. }
  16. }
  17.  
  18. allprojects {
  19. repositories {
  20. google()
  21. jcenter()
  22. }
  23. }
  24.  
  25. task clean(type: Delete) {
  26. delete rootProject.buildDir
  27. }

2.4、修改图片资源(比如__picker_ic_photo_black_48dp.png、__picker_checkbox_marked.png、__picker_checkbox_n.png)

注意:需要修改所有drawable-xxxx目录下的图片

原始的图片资源:

修改后的图片资源:

2.5、添加图片资源【__picker_transparent_bg.png、down_arrow.png、up_arrow.png】

添加到drawable-xxhdpi目录下

2.6、修改drawable目录下的__picker_photo_bg.xml和__picker_checkbox_bg.xml【主要用于替换图片列表项的底部背景图】

原代码1:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <selector xmlns:android="http://schemas.android.com/apk/res/android">
  3.  
  4. <item android:state_selected="true">
  5. <shape>
  6. <stroke android:color="@color/__picker_item_photo_border_selected"
  7. android:width="1dip"/>
  8. </shape>
  9. </item>
  10.  
  11. <item>
  12. <shape>
  13. <stroke android:color="@color/__picker_item_photo_border_n"
  14. android:width="1dip"/>
  15. </shape>
  16. </item>
  17.  
  18. </selector>

__picker_photo_bg.xml

修改后的代码:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <selector xmlns:android="http://schemas.android.com/apk/res/android">
  3. <item android:state_selected="true">
  4. <shape android:shape="rectangle">
  5. <stroke android:width="2dip"
  6. android:color="@color/__picker_item_photo_border_selected"/>
  7. <solid android:color="@color/__picker_selected_bg"/>
  8. <solid></solid>
  9. </shape>
  10. </item>
  11.  
  12. <item android:drawable="@drawable/__picker_transparent_bg">
  13. <shape android:shape="rectangle">
  14. <stroke android:width="2dip"
  15. android:color="@color/__picker_item_photo_border_n"/>
  16. <!--<solid android:color="#00000000"/>-->
  17. </shape>
  18. </item>
  19. </selector>

原代码2:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <selector xmlns:android="http://schemas.android.com/apk/res/android">
  3.  
  4. <item android:state_selected="true">
  5. <layer-list>
  6. <item>
  7. <shape>
  8. <corners android:radius="2dip"/>
  9. <padding android:top="-2dip"
  10. android:left="-2dip"
  11. android:bottom="-2dip"
  12. android:right="-2dip"/>
  13. <stroke android:width="1dip"
  14. android:color="@android:color/white"/>
  15. </shape>
  16. </item>
  17. <item android:drawable="@drawable/__picker_checkbox_marked"/>
  18. </layer-list>
  19. </item>
  20.  
  21. <item>
  22. <layer-list>
  23. <item>
  24. <shape>
  25. <corners android:radius="2dip"/>
  26. <padding android:top="-2dip"
  27. android:left="-2dip"
  28. android:bottom="-2dip"
  29. android:right="-2dip"/>
  30. <stroke android:width="1dip"
  31. android:color="@android:color/white"/>
  32. </shape>
  33. </item>
  34. <item android:drawable="@drawable/__picker_checkbox_n"/>
  35. </layer-list>
  36. </item>
  37.  
  38. </selector>

__picker_checkbox_bg.xml

修改后的

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <selector xmlns:android="http://schemas.android.com/apk/res/android">
  3.  
  4. <item android:state_selected="true">
  5. <layer-list>
  6. <!--<item>
  7. <shape>
  8. <corners android:radius="10dip"/>
  9. <padding android:top="-2dip"
  10. android:left="-2dip"
  11. android:bottom="-2dip"
  12. android:right="-2dip"/>
  13. <stroke android:width="1dip"
  14. android:color="@android:color/white"/>
  15. <solid android:color="@android:color/white"></solid>
  16. </shape>
  17. </item>-->
  18. <item android:drawable="@drawable/__picker_checkbox_marked"/>
  19. </layer-list>
  20. </item>
  21.  
  22. <item>
  23. <layer-list>
  24. <!--<item>
  25. <shape>
  26. <corners android:radius="10dip"/>
  27. <padding android:top="-2dip"
  28. android:left="-2dip"
  29. android:bottom="-2dip"
  30. android:right="-2dip"/>
  31. <stroke android:width="1dip"
  32. android:color="@android:color/white"/>
  33. <solid android:color="@android:color/white"></solid>
  34. </shape>
  35. </item>-->
  36. <item android:drawable="@drawable/__picker_checkbox_n"/>
  37. </layer-list>
  38. </item>
  39.  
  40. </selector>

2.7、修改__picker_fragment_photo_picker.xml文件【主要用于添加图片目录的上下箭头图标】

原代码

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. >
  7.  
  8. <android.support.v7.widget.RecyclerView
  9. android:id="@+id/rv_photos"
  10. android:layout_width="match_parent"
  11. android:gravity="center"
  12. android:layout_weight="1"
  13. android:layout_height="0dip"
  14. />
  15.  
  16. <LinearLayout
  17. android:layout_width="match_parent"
  18. android:layout_height="wrap_content"
  19. android:background="?attr/colorPrimary"
  20. >
  21. <Button
  22. android:id="@+id/button"
  23. android:text="@string/__picker_all_image"
  24. android:layout_width="wrap_content"
  25. android:gravity="center"
  26. android:layout_height="wrap_content"
  27. style="@style/Widget.AppCompat.ActionButton"
  28. />
  29.  
  30. </LinearLayout>
  31.  
  32. </LinearLayout>

__picker_fragment_photo_picker.xml

修改后的代码

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. >
  7.  
  8. <android.support.v7.widget.RecyclerView
  9. android:id="@+id/rv_photos"
  10. android:layout_width="match_parent"
  11. android:gravity="center"
  12. android:layout_weight="1"
  13. android:layout_height="0dip"
  14. />
  15.  
  16. <View
  17. android:layout_width="match_parent"
  18. android:layout_height="1dp"
  19. android:background="#e9e9e9"/>
  20.  
  21. <LinearLayout
  22. android:layout_width="match_parent"
  23. android:layout_height="wrap_content"
  24. android:background="?attr/colorPrimary"
  25. >
  26. <!--<Button
  27. android:id="@+id/button"
  28. android:text="@string/__picker_all_image"
  29. android:layout_width="wrap_content"
  30. android:gravity="center"
  31. android:layout_height="wrap_content"
  32. style="@style/Widget.AppCompat.ActionButton"
  33. />-->
  34.  
  35. <TextView
  36. android:id="@+id/button"
  37. android:layout_width="0.0dp"
  38. android:layout_weight="1"
  39. android:layout_height="match_parent"
  40. android:text="@string/__picker_all_image"
  41. android:textColor="@color/__picker_text_120"
  42. android:textSize="16sp"
  43. android:drawableRight="@drawable/up_arrow"
  44. android:drawablePadding="8dp"
  45. android:paddingLeft="10dp"
  46. android:paddingRight="10dp"
  47. android:gravity="center_vertical"
  48. style="@style/Widget.AppCompat.ActionButton"
  49. />
  50. <!-- 现在用不到,只是占位用 -->
  51. <ImageView
  52. android:layout_width="0.0dp"
  53. android:layout_weight="1"
  54. android:layout_height="match_parent"
  55. android:src="@drawable/__picker_camera"
  56. android:layout_gravity="center_vertical"
  57. android:paddingLeft="15dp"
  58. android:paddingRight="15dp"
  59. android:visibility="invisible"/>
  60.  
  61. </LinearLayout>
  62.  
  63. </LinearLayout>

2.8、修改PhotoPickerFragment.java文件【主要是实现上下箭头的更换功能】

搜索why,查看改动的代码:

  1. package me.iwf.photopicker.fragment;
  2.  
  3. import android.content.ActivityNotFoundException;
  4. import android.content.Intent;
  5. import android.content.pm.PackageManager;
  6. import android.graphics.drawable.Drawable;
  7. import android.os.Bundle;
  8. import android.support.annotation.NonNull;
  9. import android.support.v4.app.Fragment;
  10. import android.support.v4.app.FragmentActivity;
  11. import android.support.v4.content.ContextCompat;
  12. import android.support.v7.widget.DefaultItemAnimator;
  13. import android.support.v7.widget.ListPopupWindow;
  14. import android.support.v7.widget.OrientationHelper;
  15. import android.support.v7.widget.RecyclerView;
  16. import android.support.v7.widget.StaggeredGridLayoutManager;
  17. import android.util.Log;
  18. import android.view.Gravity;
  19. import android.view.LayoutInflater;
  20. import android.view.View;
  21. import android.view.View.OnClickListener;
  22. import android.view.ViewGroup;
  23. import android.widget.AdapterView;
  24. import android.widget.PopupWindow;
  25. import android.widget.TextView;
  26.  
  27. import com.bumptech.glide.Glide;
  28. import com.bumptech.glide.RequestManager;
  29.  
  30. import java.io.IOException;
  31. import java.util.ArrayList;
  32. import java.util.List;
  33.  
  34. import me.iwf.photopicker.PhotoPickerActivity;
  35. import me.iwf.photopicker.R;
  36. import me.iwf.photopicker.adapter.PhotoGridAdapter;
  37. import me.iwf.photopicker.adapter.PopupDirectoryListAdapter;
  38. import me.iwf.photopicker.entity.Photo;
  39. import me.iwf.photopicker.entity.PhotoDirectory;
  40. import me.iwf.photopicker.event.OnPhotoClickListener;
  41. import me.iwf.photopicker.utils.AndroidLifecycleUtils;
  42. import me.iwf.photopicker.utils.ImageCaptureManager;
  43. import me.iwf.photopicker.utils.MediaStoreHelper;
  44. import me.iwf.photopicker.utils.PermissionsConstant;
  45. import me.iwf.photopicker.utils.PermissionsUtils;
  46.  
  47. import static android.app.Activity.RESULT_OK;
  48. import static me.iwf.photopicker.PhotoPicker.DEFAULT_COLUMN_NUMBER;
  49. import static me.iwf.photopicker.PhotoPicker.EXTRA_PREVIEW_ENABLED;
  50. import static me.iwf.photopicker.PhotoPicker.EXTRA_SHOW_GIF;
  51. import static me.iwf.photopicker.utils.MediaStoreHelper.INDEX_ALL_PHOTOS;
  52.  
  53. /**
  54. * Created by donglua on 15/5/31.
  55. */
  56. public class PhotoPickerFragment extends Fragment {
  57.  
  58. private ImageCaptureManager captureManager;
  59. private PhotoGridAdapter photoGridAdapter;
  60.  
  61. private PopupDirectoryListAdapter listAdapter;
  62. //所有photos的路径
  63. private List<PhotoDirectory> directories;
  64. //传入的已选照片
  65. private ArrayList<String> originalPhotos;
  66.  
  67. private int SCROLL_THRESHOLD = 30;
  68. int column;
  69. //目录弹出框的一次最多显示的目录数目
  70. public static int COUNT_MAX = 4;
  71. private final static String EXTRA_CAMERA = "camera";
  72. private final static String EXTRA_COLUMN = "column";
  73. private final static String EXTRA_COUNT = "count";
  74. private final static String EXTRA_GIF = "gif";
  75. private final static String EXTRA_ORIGIN = "origin";
  76. private ListPopupWindow listPopupWindow;
  77. private RequestManager mGlideRequestManager;
  78.  
  79. public static PhotoPickerFragment newInstance(boolean showCamera, boolean showGif,
  80. boolean previewEnable, int column, int maxCount, ArrayList<String> originalPhotos) {
  81. Bundle args = new Bundle();
  82. args.putBoolean(EXTRA_CAMERA, showCamera);
  83. args.putBoolean(EXTRA_GIF, showGif);
  84. args.putBoolean(EXTRA_PREVIEW_ENABLED, previewEnable);
  85. args.putInt(EXTRA_COLUMN, column);
  86. args.putInt(EXTRA_COUNT, maxCount);
  87. args.putStringArrayList(EXTRA_ORIGIN, originalPhotos);
  88. PhotoPickerFragment fragment = new PhotoPickerFragment();
  89. fragment.setArguments(args);
  90. return fragment;
  91. }
  92.  
  93. @Override public void onCreate(Bundle savedInstanceState) {
  94. super.onCreate(savedInstanceState);
  95.  
  96. setRetainInstance(true);
  97.  
  98. mGlideRequestManager = Glide.with(this);
  99.  
  100. directories = new ArrayList<>();
  101. originalPhotos = getArguments().getStringArrayList(EXTRA_ORIGIN);
  102.  
  103. column = getArguments().getInt(EXTRA_COLUMN, DEFAULT_COLUMN_NUMBER);
  104. boolean showCamera = getArguments().getBoolean(EXTRA_CAMERA, true);
  105. boolean previewEnable = getArguments().getBoolean(EXTRA_PREVIEW_ENABLED, true);
  106.  
  107. photoGridAdapter = new PhotoGridAdapter(getActivity(), mGlideRequestManager, directories, originalPhotos, column);
  108. photoGridAdapter.setShowCamera(showCamera);
  109. photoGridAdapter.setPreviewEnable(previewEnable);
  110.  
  111. listAdapter = new PopupDirectoryListAdapter(mGlideRequestManager, directories);
  112.  
  113. Bundle mediaStoreArgs = new Bundle();
  114.  
  115. boolean showGif = getArguments().getBoolean(EXTRA_GIF);
  116. mediaStoreArgs.putBoolean(EXTRA_SHOW_GIF, showGif);
  117. MediaStoreHelper.getPhotoDirs(getActivity(), mediaStoreArgs,
  118. new MediaStoreHelper.PhotosResultCallback() {
  119. @Override public void onResultCallback(List<PhotoDirectory> dirs) {
  120. directories.clear();
  121. directories.addAll(dirs);
  122. photoGridAdapter.notifyDataSetChanged();
  123. listAdapter.notifyDataSetChanged();
  124. adjustHeight();
  125. }
  126. });
  127.  
  128. captureManager = new ImageCaptureManager(getActivity());
  129. }
  130.  
  131. @Override
  132. public void onResume() {
  133. super.onResume();
  134. if(getActivity() instanceof PhotoPickerActivity){
  135. PhotoPickerActivity photoPickerActivity = (PhotoPickerActivity) getActivity();
  136. photoPickerActivity.updateTitleDoneItem();
  137. }
  138. }
  139.  
  140. @Override public View onCreateView(LayoutInflater inflater, ViewGroup container,
  141. Bundle savedInstanceState) {
  142.  
  143. final View rootView = inflater.inflate(R.layout.__picker_fragment_photo_picker, container, false);
  144.  
  145. RecyclerView recyclerView = (RecyclerView) rootView.findViewById(R.id.rv_photos);
  146. StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(column, OrientationHelper.VERTICAL);
  147. layoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS);
  148. recyclerView.setLayoutManager(layoutManager);
  149. recyclerView.setAdapter(photoGridAdapter);
  150. recyclerView.setItemAnimator(new DefaultItemAnimator());
  151.  
  152. //final Button btSwitchDirectory = (Button) rootView.findViewById(R.id.button);
  153. final TextView btSwitchDirectory = (TextView) rootView.findViewById(R.id.button);//why
  154.  
  155. listPopupWindow = new ListPopupWindow(getActivity());
  156. listPopupWindow.setWidth(ListPopupWindow.MATCH_PARENT);
  157. listPopupWindow.setAnchorView(btSwitchDirectory);
  158. listPopupWindow.setAdapter(listAdapter);
  159. listPopupWindow.setModal(true);
  160. listPopupWindow.setDropDownGravity(Gravity.BOTTOM);
  161.  
  162. listPopupWindow.setOnItemClickListener(new AdapterView.OnItemClickListener() {
  163. @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
  164. listPopupWindow.dismiss();
  165.  
  166. PhotoDirectory directory = directories.get(position);
  167.  
  168. btSwitchDirectory.setText(directory.getName());
  169.  
  170. photoGridAdapter.setCurrentDirectoryIndex(position);
  171. photoGridAdapter.notifyDataSetChanged();
  172. }
  173. });
  174.  
  175. //添加popwindow隐藏的监听--why
  176. listPopupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
  177. @Override
  178. public void onDismiss() {
  179. //监听popwindow隐藏的时候的操作
  180. Drawable drawableUp = ContextCompat.getDrawable(getActivity(),R.drawable.up_arrow);
  181. drawableUp.setBounds(0, 0, drawableUp.getMinimumWidth(), drawableUp.getMinimumHeight());
  182. btSwitchDirectory.setCompoundDrawables(null,null,drawableUp,null);
  183. }
  184. });
  185.  
  186. photoGridAdapter.setOnPhotoClickListener(new OnPhotoClickListener() {
  187. @Override public void onClick(View v, int position, boolean showCamera) {
  188. final int index = showCamera ? position - 1 : position;
  189.  
  190. List<String> photos = photoGridAdapter.getCurrentPhotoPaths();
  191.  
  192. ImagePagerFragment imagePagerFragment =
  193. ImagePagerFragment.newInstance(photos, index);
  194.  
  195. ((PhotoPickerActivity) getActivity()).addImagePagerFragment(imagePagerFragment);
  196. }
  197. });
  198.  
  199. photoGridAdapter.setOnCameraClickListener(new OnClickListener() {
  200. @Override public void onClick(View view) {
  201. if (!PermissionsUtils.checkCameraPermission(PhotoPickerFragment.this)) return;
  202. if (!PermissionsUtils.checkWriteStoragePermission(PhotoPickerFragment.this)) return;
  203. openCamera();
  204. }
  205. });
  206.  
  207. btSwitchDirectory.setOnClickListener(new OnClickListener() {
  208. @Override public void onClick(View v) {
  209.  
  210. if (listPopupWindow.isShowing()) {
  211. listPopupWindow.dismiss();
  212. } else if (!getActivity().isFinishing()) {
  213. adjustHeight();
  214. //why
  215. Drawable drawableDown = ContextCompat.getDrawable(getActivity(),R.drawable.down_arrow);
  216. drawableDown.setBounds(0, 0, drawableDown.getMinimumWidth(), drawableDown.getMinimumHeight());
  217. btSwitchDirectory.setCompoundDrawables(null,null,drawableDown,null);
  218. listPopupWindow.show();
  219. }
  220. }
  221. });
  222.  
  223. recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
  224. @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
  225. super.onScrolled(recyclerView, dx, dy);
  226. // Log.d(">>> Picker >>>", "dy = " + dy);
  227. if (Math.abs(dy) > SCROLL_THRESHOLD) {
  228. mGlideRequestManager.pauseRequests();
  229. } else {
  230. resumeRequestsIfNotDestroyed();
  231. }
  232. }
  233. @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
  234. if (newState == RecyclerView.SCROLL_STATE_IDLE) {
  235. resumeRequestsIfNotDestroyed();
  236. }
  237. }
  238. });
  239.  
  240. return rootView;
  241. }
  242.  
  243. private void openCamera() {
  244. try {
  245. Intent intent = captureManager.dispatchTakePictureIntent();
  246. startActivityForResult(intent, ImageCaptureManager.REQUEST_TAKE_PHOTO);
  247. } catch (IOException e) {
  248. e.printStackTrace();
  249. } catch (ActivityNotFoundException e) {
  250. Log.e("PhotoPickerFragment", "No Activity Found to handle Intent", e);
  251. }
  252. }
  253.  
  254. @Override public void onActivityResult(int requestCode, int resultCode, Intent data) {
  255. if (requestCode == ImageCaptureManager.REQUEST_TAKE_PHOTO && resultCode == RESULT_OK) {
  256.  
  257. if (captureManager == null) {
  258. FragmentActivity activity = getActivity();
  259. captureManager = new ImageCaptureManager(activity);
  260. }
  261.  
  262. captureManager.galleryAddPic();
  263. if (directories.size() > 0) {
  264. String path = captureManager.getCurrentPhotoPath();
  265. PhotoDirectory directory = directories.get(INDEX_ALL_PHOTOS);
  266. directory.getPhotos().add(INDEX_ALL_PHOTOS, new Photo(path.hashCode(), path));
  267. directory.setCoverPath(path);
  268. photoGridAdapter.notifyDataSetChanged();
  269. }
  270. }
  271. }
  272.  
  273. @Override
  274. public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
  275. if (grantResults.length > 0
  276. && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
  277. switch (requestCode) {
  278. case PermissionsConstant.REQUEST_CAMERA:
  279. case PermissionsConstant.REQUEST_EXTERNAL_WRITE:
  280. if (PermissionsUtils.checkWriteStoragePermission(this) &&
  281. PermissionsUtils.checkCameraPermission(this)) {
  282. openCamera();
  283. }
  284. break;
  285. }
  286. }
  287. }
  288.  
  289. public PhotoGridAdapter getPhotoGridAdapter() {
  290. return photoGridAdapter;
  291. }
  292.  
  293. @Override public void onSaveInstanceState(Bundle outState) {
  294. captureManager.onSaveInstanceState(outState);
  295. super.onSaveInstanceState(outState);
  296. }
  297.  
  298. @Override public void onViewStateRestored(Bundle savedInstanceState) {
  299. captureManager.onRestoreInstanceState(savedInstanceState);
  300. super.onViewStateRestored(savedInstanceState);
  301. }
  302.  
  303. public ArrayList<String> getSelectedPhotoPaths() {
  304. return photoGridAdapter.getSelectedPhotoPaths();
  305. }
  306.  
  307. public void adjustHeight() {
  308. if (listAdapter == null) return;
  309. int count = listAdapter.getCount();
  310. count = count < COUNT_MAX ? count : COUNT_MAX;
  311. if (listPopupWindow != null) {
  312. listPopupWindow.setHeight(count * getResources().getDimensionPixelOffset(R.dimen.__picker_item_directory_height));
  313. }
  314. }
  315.  
  316. @Override public void onDestroy() {
  317. super.onDestroy();
  318.  
  319. if (directories == null) {
  320. return;
  321. }
  322.  
  323. for (PhotoDirectory directory : directories) {
  324. directory.getPhotoPaths().clear();
  325. directory.getPhotos().clear();
  326. directory.setPhotos(null);
  327. }
  328. directories.clear();
  329. directories = null;
  330. }
  331.  
  332. private void resumeRequestsIfNotDestroyed() {
  333. if (!AndroidLifecycleUtils.canLoadImage(this)) {
  334. return;
  335. }
  336.  
  337. mGlideRequestManager.resumeRequests();
  338. }
  339. }

PhotoPickerFragment.java

2.9、修改__picker_item_photo.xml,设置图片列表项的内边距值

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <me.iwf.photopicker.widget.SquareItemLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:padding="3dp"
  6. >
  7. <ImageView
  8. android:padding="1dip"
  9. android:layout_gravity="center"
  10. android:id="@+id/iv_photo"
  11. android:scaleType="centerCrop"
  12. android:layout_width="match_parent"
  13. android:background="@drawable/__picker_photo_bg"
  14. android:layout_height="match_parent"
  15. android:adjustViewBounds="true"
  16. />
  17.  
  18. <ImageView
  19. android:layout_alignParentTop="true"
  20. android:layout_alignParentRight="true"
  21. android:clickable="true"
  22. android:paddingTop="10dip"
  23. android:paddingRight="10dip"
  24. android:paddingLeft="20dip"
  25. android:paddingBottom="20dip"
  26. android:id="@+id/v_selected"
  27. android:src="@drawable/__picker_checkbox_bg"
  28. android:layout_width="wrap_content"
  29. android:layout_height="wrap_content"
  30. />
  31.  
  32. </me.iwf.photopicker.widget.SquareItemLayout>

2.10、修改图片列表项选中后的颜色值(colors.xml文件中修改)

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources>
  3.  
  4. <color name="__picker_pager_bg">#CA000000</color>
  5. <color name="__picker_selected_bg">#44000000</color>
  6. <color name="__picker_black_40">#282828</color>
  7. <color name="__picker_common_primary">#f3f3f3</color>
  8.  
  9. <color name="__picker_text_40">#282828</color>
  10. <color name="__picker_text_80">#505050</color>
  11. <color name="__picker_text_120">#787878</color>
  12. <!--<color name="__picker_item_photo_border_selected">#ff99cc00</color>-->
  13. <!--why-->
  14. <color name="__picker_item_photo_border_selected">#1A78EC</color>
  15. <color name="__picker_item_photo_border_n">#33ffffff</color>
  16.  
  17. </resources>

至此,PhotoPicker基本上修改完了,后续可以根据需求继续修改。下面就是运用到APP中的步骤【导入步骤跟方式1几乎一样,不同的就是app的build.gradle导入的photopicker不一样】。

2.11、在APP的build.gradle文件添加以下代码

  1. apply plugin: 'com.android.application'
  2.  
  3. android {
  4. compileSdkVersion 27
  5. defaultConfig {
  6. applicationId "com.why.project.photopickernewdemo"
  7. minSdkVersion 16
  8. targetSdkVersion 27
  9. versionCode 1
  10. versionName "1.0"
  11. testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
  12. }
  13. buildTypes {
  14. release {
  15. minifyEnabled false
  16. proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
  17. }
  18. }
  19. }
  20.  
  21. dependencies {
  22. implementation fileTree(dir: 'libs', include: ['*.jar'])
  23. implementation 'com.android.support:appcompat-v7:27.1.1'
  24. implementation 'com.android.support.constraint:constraint-layout:1.1.2'
  25. testImplementation 'junit:junit:4.12'
  26. androidTestImplementation 'com.android.support.test:runner:1.0.2'
  27. androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
  28.  
  29. //PhotoPicker
  30. //compile 'me.iwf.photopicker:PhotoPicker:0.9.12@aar'
  31. //方式2:使用自己导入并且修改后的module
  32. implementation project(':PhotoPicker')
  33. //compile 'com.android.support:appcompat-v7:27.1.1'//需要注释,因为新建项目都会自动引用这个appcompat-v7
  34. compile 'com.android.support:recyclerview-v7:27.1.1'
  35. compile 'com.android.support:design:27.1.1'
  36. compile 'com.github.bumptech.glide:glide:4.1.1'
  37. }

2.12、在APP的AndroidManifest.xml中添加以下代码

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.why.project.photopickernewdemo">
  4.  
  5. <application
  6. android:allowBackup="true"
  7. android:icon="@mipmap/ic_launcher"
  8. android:label="@string/app_name"
  9. android:roundIcon="@mipmap/ic_launcher_round"
  10. android:supportsRtl="true"
  11. android:theme="@style/AppTheme">
  12. <activity android:name=".MainActivity">
  13. <intent-filter>
  14. <action android:name="android.intent.action.MAIN"/>
  15.  
  16. <category android:name="android.intent.category.LAUNCHER"/>
  17. </intent-filter>
  18. </activity>
  19.  
  20. <!-- PhotoPicker -->
  21. <activity android:name="me.iwf.photopicker.PhotoPickerActivity"
  22. android:theme="@style/customTheme"
  23. />
  24. <activity android:name="me.iwf.photopicker.PhotoPagerActivity"
  25. android:theme="@style/customTheme"/>
  26. </application>
  27.  
  28. </manifest>

2.13、在styles.xml文件中添加以下代码

  1. <resources>
  2.  
  3. <!-- Base application theme. -->
  4. <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
  5. <!-- Customize your theme here. -->
  6. <item name="colorPrimary">@color/colorPrimary</item>
  7. <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
  8. <item name="colorAccent">@color/colorAccent</item>
  9. </style>
  10.  
  11. <!-- PhotoPicker -->
  12. <style name="customTheme" parent="Theme.AppCompat.Light.NoActionBar">
  13. <!-- 解开注释的话,右侧的完成文本始终是设置的颜色,无法实现禁用状态下是灰色的功能 -->
  14. <!--<item name="actionBarTheme">@style/actionBarTheme</item>-->
  15. <!--背景颜色值-->
  16. <item name="colorPrimary">#ffffff</item>
  17. <!--导航栏高度值-->
  18. <item name="actionBarSize">52dp</item>
  19. <!-- 状态栏着色 -->
  20. <item name="colorPrimaryDark">#378dfc</item>
  21. </style>
  22. <style name="actionBarTheme" parent="ThemeOverlay.AppCompat.Dark.ActionBar">
  23. <!--标题颜色值-->
  24. <item name="android:textColorPrimary">#434343</item>
  25. <!--右侧完成文本的大小值-->
  26. <item name="android:textSize">16sp</item>
  27. <!--右侧完成文本的颜色值-->
  28. <item name="android:actionMenuTextColor">#1A78EC</item>
  29. </style>
  30.  
  31. </resources>

具体使用参考《三、使用方法》

使用步骤

一、项目组织结构图

注意事项:

1、  导入类文件后需要change包名以及重新import R文件路径

2、  Values目录下的文件(strings.xml、dimens.xml、colors.xml等),如果项目中存在,则复制里面的内容,不要整个覆盖

二、导入步骤【方式1的导入步骤】

(1)在app的build.gradle文件中导入PhotoPicker【修改recyclerview、design的版本号和appcompat-v7统一】

注意:appcompat-v7version >= 23.0.0

  1. apply plugin: 'com.android.application'
  2.  
  3. android {
  4. compileSdkVersion 27
  5. defaultConfig {
  6. applicationId "com.why.project.photopickernewdemo"
  7. minSdkVersion 16
  8. targetSdkVersion 27
  9. versionCode 1
  10. versionName "1.0"
  11. testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
  12. }
  13. buildTypes {
  14. release {
  15. minifyEnabled false
  16. proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
  17. }
  18. }
  19. }
  20.  
  21. dependencies {
  22. implementation fileTree(dir: 'libs', include: ['*.jar'])
  23. implementation 'com.android.support:appcompat-v7:27.1.1'
  24. implementation 'com.android.support.constraint:constraint-layout:1.1.2'
  25. testImplementation 'junit:junit:4.12'
  26. androidTestImplementation 'com.android.support.test:runner:1.0.2'
  27. androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
  28.  
  29. //PhotoPicker
  30. compile 'me.iwf.photopicker:PhotoPicker:0.9.12@aar'
  31. //compile 'com.android.support:appcompat-v7:27.1.1'//需要注释,因为新建项目都会自动引用这个appcompat-v7
  32. compile 'com.android.support:recyclerview-v7:27.1.1'
  33. compile 'com.android.support:design:27.1.1'
  34. compile 'com.github.bumptech.glide:glide:4.1.1'
  35. }

(2)在APP的styles.xml文件中自定义样式(颜色、高度值等)

  1. <resources>
  2.  
  3. <!-- Base application theme. -->
  4. <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
  5. <!-- Customize your theme here. -->
  6. <item name="colorPrimary">@color/colorPrimary</item>
  7. <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
  8. <item name="colorAccent">@color/colorAccent</item>
  9. </style>
  10.  
  11. <!-- PhotoPicker -->
  12. <style name="customTheme" parent="Theme.AppCompat.Light.NoActionBar">
  13. <!-- 解开注释的话,右侧的完成文本始终是设置的颜色,无法实现禁用状态下是灰色的功能 -->
  14. <!--<item name="actionBarTheme">@style/actionBarTheme</item>-->
  15. <!--背景颜色值-->
  16. <item name="colorPrimary">#ffffff</item>
  17. <!--导航栏高度值-->
  18. <item name="actionBarSize">52dp</item>
  19. <!-- 状态栏着色 -->
  20. <item name="colorPrimaryDark">#378dfc</item>
  21. </style>
  22. <style name="actionBarTheme" parent="ThemeOverlay.AppCompat.Dark.ActionBar">
  23. <!--标题颜色值-->
  24. <item name="android:textColorPrimary">#434343</item>
  25. <!--右侧完成文本的大小值-->
  26. <item name="android:textSize">16sp</item>
  27. <!--右侧完成文本的颜色值-->
  28. <item name="android:actionMenuTextColor">#1A78EC</item>
  29. </style>
  30.  
  31. </resources>

(3)在APP的AndroidManifest.xml中添加以下代码【注意:使用上面自定义的样式】

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.why.project.photopickernewdemo">
  4.  
  5. <application
  6. android:allowBackup="true"
  7. android:icon="@mipmap/ic_launcher"
  8. android:label="@string/app_name"
  9. android:roundIcon="@mipmap/ic_launcher_round"
  10. android:supportsRtl="true"
  11. android:theme="@style/AppTheme">
  12. <activity android:name=".MainActivity">
  13. <intent-filter>
  14. <action android:name="android.intent.action.MAIN"/>
  15.  
  16. <category android:name="android.intent.category.LAUNCHER"/>
  17. </intent-filter>
  18. </activity>
  19.  
  20. <!-- PhotoPicker -->
  21. <activity android:name="me.iwf.photopicker.PhotoPickerActivity"
  22. android:theme="@style/customTheme"
  23. />
  24. <activity android:name="me.iwf.photopicker.PhotoPagerActivity"
  25. android:theme="@style/customTheme"/>
  26. </application>
  27.  
  28. </manifest>

三、使用方法

(1)在项目中实现Recyclerview基本数据展现【比较简单,省略】【或者参考《Android快速开发常用知识点系列目录》下的RecyclerView篇章相关文章】

注意:PictureAdapter.java中使用的Glide是4.1.1版本,所以写法跟之前的Glide3.7.0版本是不一样的。

  1. package com.why.project.photopickernewdemo.adapter;
  2.  
  3. import android.content.Context;
  4. import android.net.Uri;
  5. import android.support.v7.widget.RecyclerView;
  6. import android.util.Log;
  7. import android.view.LayoutInflater;
  8. import android.view.View;
  9. import android.view.ViewGroup;
  10. import android.widget.ImageView;
  11. import android.widget.LinearLayout;
  12. import android.widget.RelativeLayout;
  13. import android.widget.TextView;
  14.  
  15. import com.bumptech.glide.Glide;
  16. import com.bumptech.glide.Priority;
  17. import com.bumptech.glide.load.engine.DiskCacheStrategy;
  18. import com.bumptech.glide.request.RequestOptions;
  19. import com.why.project.photopickernewdemo.R;
  20. import com.why.project.photopickernewdemo.bean.PictureBean;
  21.  
  22. import java.io.File;
  23. import java.util.ArrayList;
  24. import java.util.List;
  25.  
  26. import static com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions.withCrossFade;
  27.  
  28. /**
  29. * Created by HaiyuKing
  30. * Used 照片网格适配器
  31. */
  32.  
  33. public class PictureAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
  34.  
  35. private static final String TAG = PictureAdapter.class.getSimpleName();
  36.  
  37. /**上下文*/
  38. private Context myContext;
  39. /**自定义列表项标题集合*/
  40. private ArrayList<PictureBean> listitemList;
  41.  
  42. final static int TYPE_ADD = 1;
  43. final static int TYPE_PHOTO = 2;
  44.  
  45. public final static int MAX = 15;//总数目,这里根据实际情况设置,设置100基本上表明无限制了
  46.  
  47. /*
  48. * 构造函数
  49. */
  50. public PictureAdapter(Context context, ArrayList<PictureBean> itemlist) {
  51. myContext = context;
  52. listitemList = itemlist;
  53. }
  54.  
  55. /**
  56. * 获取总的条目数
  57. */
  58. @Override
  59. public int getItemCount() {
  60. Log.w(TAG,"{getItemCount}listitemList.size()="+listitemList.size());
  61. int count = listitemList.size();
  62. if (count > MAX) {
  63. count = MAX;
  64. }
  65. count = count + 1;
  66. return count;
  67. }
  68.  
  69. @Override
  70. public int getItemViewType(int position) {
  71. Log.w(TAG,"{getItemViewType}position="+position);
  72. Log.w(TAG,"{getItemViewType}listitemList.size()="+listitemList.size());
  73. return (position == listitemList.size()) ? TYPE_ADD : TYPE_PHOTO;
  74. }
  75.  
  76. /**
  77. * 创建ViewHolder
  78. */
  79. @Override
  80. public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
  81. if(viewType == TYPE_ADD) {
  82. View viewfoot = LayoutInflater.from(myContext).inflate(R.layout.pic_grid_foot_item, parent, false);
  83. ItemFootViewHolder itemfootViewHolder = new ItemFootViewHolder(viewfoot);
  84. return itemfootViewHolder;
  85. } else if(viewType == TYPE_PHOTO) {
  86. View view = LayoutInflater.from(myContext).inflate(R.layout.pic_grid_item, parent, false);
  87. ItemViewHolder itemViewHolder = new ItemViewHolder(view);
  88. return itemViewHolder;
  89. }
  90. return null;
  91. }
  92.  
  93. /**
  94. * 声明列表项ViewHolder*/
  95. static class ItemViewHolder extends RecyclerView.ViewHolder
  96. {
  97. public ItemViewHolder(View view)
  98. {
  99. super(view);
  100. griditemLayout = (LinearLayout) view.findViewById(R.id.griditemLayout);
  101. griditemimgLayout = (RelativeLayout) view.findViewById(R.id.griditemimgLayout);
  102. grid_img = (ImageView) view.findViewById(R.id.grid_img);
  103. grid_img_state = (TextView) view.findViewById(R.id.grid_img_state);
  104. }
  105.  
  106. LinearLayout griditemLayout;
  107. RelativeLayout griditemimgLayout;
  108. ImageView grid_img;
  109.  
  110. TextView grid_img_state;
  111. }
  112.  
  113. /**
  114. * 声明最后一个ViewHolder*/
  115. static class ItemFootViewHolder extends RecyclerView.ViewHolder
  116. {
  117. public ItemFootViewHolder(View view)
  118. {
  119. super(view);
  120. gridfootitemLayout = (RelativeLayout) view.findViewById(R.id.gridfootitemLayout);
  121. }
  122. RelativeLayout gridfootitemLayout;
  123. }
  124.  
  125. /**
  126. * 将数据绑定至ViewHolder
  127. */
  128. @Override
  129. public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int index) {
  130.  
  131. if(viewHolder instanceof ItemViewHolder){
  132. PictureBean listItemModel = listitemList.get(index);
  133. final ItemViewHolder itemViewHold = ((ItemViewHolder)viewHolder);
  134.  
  135. Uri uri = Uri.fromFile(new File(listItemModel.getPicPath()));
  136.  
  137. RequestOptions options = new RequestOptions()
  138. //设置等待时的图片
  139. .placeholder(R.drawable.img_loading)
  140. //设置加载失败后的图片显示
  141. .error(R.drawable.img_error)
  142. //缓存策略,跳过内存缓存【此处应该设置为false,否则列表刷新时会闪一下】
  143. .skipMemoryCache(false)
  144. //缓存策略,硬盘缓存-仅仅缓存最终的图像,即降低分辨率后的(或者是转换后的)
  145. .diskCacheStrategy(DiskCacheStrategy.ALL)
  146. //设置图片加载的优先级
  147. .priority(Priority.HIGH);
  148.  
  149. Glide.with(myContext)
  150. .load(uri)
  151. .apply(options)
  152. //默认淡入淡出动画
  153. .transition(withCrossFade())
  154. .into(itemViewHold.grid_img);
  155.  
  156. itemViewHold.grid_img_state.setText("(" + (index+1) + "/" + listitemList.size() + ")");
  157.  
  158. //如果设置了回调,则设置点击事件
  159. if (mOnItemClickLitener != null)
  160. {
  161. itemViewHold.grid_img.setOnClickListener(new View.OnClickListener() {
  162. @Override
  163. public void onClick(View view) {
  164. int position = itemViewHold.getLayoutPosition();//在增加数据或者减少数据时候,position和index就不一样了
  165. mOnItemClickLitener.onItemClick(view,position);
  166. }
  167. });
  168. }
  169. }else if(viewHolder instanceof ItemFootViewHolder){
  170. final ItemFootViewHolder itemFootViewHold = ((ItemFootViewHolder)viewHolder);
  171. //如果设置了回调,则设置点击事件
  172. if (mOnItemClickLitener != null)
  173. {
  174. itemFootViewHold.gridfootitemLayout.setOnClickListener(new View.OnClickListener() {
  175. @Override
  176. public void onClick(View view) {
  177. mOnItemClickLitener.onItemAddClick();
  178. }
  179. });
  180. }
  181. }
  182.  
  183. }
  184.  
  185. /**
  186. * 添加Item--用于动画的展现*/
  187. public void addItem(int position,PictureBean itemModel) {
  188. listitemList.add(position,itemModel);
  189. notifyItemInserted(position);
  190. }
  191. /**
  192. * 删除Item--用于动画的展现*/
  193. public void removeItem(int position) {
  194. listitemList.remove(position);
  195. notifyItemRemoved(position);
  196. }
  197.  
  198. /*=====================添加OnItemClickListener回调================================*/
  199. public interface OnItemClickLitener
  200. {
  201. /**图片的点击事件*/
  202. void onItemClick(View view, int position);
  203. /**添加的点击事件*/
  204. void onItemAddClick();
  205. }
  206.  
  207. private OnItemClickLitener mOnItemClickLitener;
  208.  
  209. public void setOnItemClickLitener(OnItemClickLitener mOnItemClickLitener)
  210. {
  211. this.mOnItemClickLitener = mOnItemClickLitener;
  212. }
  213.  
  214. //返回当前图片集合的所有路径集合【用于预览】
  215. public List<String> getAllPhotoPaths() {
  216. List<String> allPhotoPaths = new ArrayList<String>(listitemList.size());
  217. for (PictureBean pictureBean: listitemList) {
  218. allPhotoPaths.add(pictureBean.getPicPath());
  219. }
  220. return allPhotoPaths;
  221. }
  222.  
  223. }

(2)常规使用

  1. package com.why.project.photopickernewdemo;
  2.  
  3. import android.app.Activity;
  4. import android.content.Intent;
  5. import android.os.Bundle;
  6. import android.support.v7.app.AppCompatActivity;
  7. import android.support.v7.widget.GridLayoutManager;
  8. import android.support.v7.widget.RecyclerView;
  9. import android.util.Log;
  10. import android.view.View;
  11. import android.widget.Toast;
  12.  
  13. import com.why.project.photopickernewdemo.adapter.PictureAdapter;
  14. import com.why.project.photopickernewdemo.bean.PictureBean;
  15. import com.why.project.photopickernewdemo.utils.Globals;
  16.  
  17. import java.util.ArrayList;
  18.  
  19. import me.iwf.photopicker.PhotoPicker;
  20. import me.iwf.photopicker.PhotoPreview;
  21.  
  22. public class MainActivity extends AppCompatActivity {
  23.  
  24. private static final String TAG = MainActivity.class.getSimpleName();
  25.  
  26. private RecyclerView mRecyclerView;
  27. private ArrayList<PictureBean> mPictureBeansList;
  28. private PictureAdapter mPictureAdapter;
  29.  
  30. private ArrayList<String> selPhotosPath = null;//选中的图片路径集合
  31.  
  32. @Override
  33. protected void onCreate(Bundle savedInstanceState) {
  34. super.onCreate(savedInstanceState);
  35. setContentView(R.layout.activity_main);
  36.  
  37. initViews();
  38. initDatas();
  39. initEvents();
  40. }
  41.  
  42. private void initViews() {
  43. mRecyclerView = findViewById(R.id.picture_grid);
  44. }
  45.  
  46. private void initDatas() {
  47. selPhotosPath = new ArrayList<String>();
  48. //=============图片九宫格=========================
  49. mPictureAdapter = null;
  50. mPictureBeansList = new ArrayList<PictureBean>();
  51. //设置布局管理器
  52. GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 3);
  53. mRecyclerView.setLayoutManager(gridLayoutManager);
  54.  
  55. if(mPictureAdapter == null){
  56. //设置适配器
  57. mPictureAdapter = new PictureAdapter(this, mPictureBeansList);
  58. mRecyclerView.setAdapter(mPictureAdapter);
  59. //添加分割线
  60. //设置添加删除动画
  61. //调用ListView的setSelected(!ListView.isSelected())方法,这样就能及时刷新布局
  62. mRecyclerView.setSelected(true);
  63. }else{
  64. mPictureAdapter.notifyDataSetChanged();
  65. }
  66. }
  67.  
  68. private void initEvents() {
  69. //图片九宫格点击事件
  70. mPictureAdapter.setOnItemClickLitener(new PictureAdapter.OnItemClickLitener() {
  71. @Override
  72. public void onItemClick(View v, int position) {
  73. //打开图片预览界面
  74. ArrayList<String> photos = (ArrayList<String>) mPictureAdapter.getAllPhotoPaths();
  75. PhotoPreview.builder()
  76. .setPhotos(photos)
  77. .setCurrentItem(position)
  78. .setShowDeleteButton(false)
  79. .start(MainActivity.this);
  80. }
  81.  
  82. @Override
  83. public void onItemAddClick() {
  84. PhotoPicker.builder()
  85. .setPhotoCount(mPictureAdapter.MAX)
  86. .setGridColumnCount(3)
  87. //.setSelected(selPhotosPath)
  88. .start(MainActivity.this, Globals.CHOOSE_PIC_REQUEST_CODE);
  89. }
  90. });
  91. }
  92.  
  93. @Override
  94. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  95. super.onActivityResult(requestCode, resultCode, data);
  96.  
  97. Log.w(TAG, "{onActivityResult}resultCode="+resultCode);
  98. Log.w(TAG, "{onActivityResult}requestCode="+requestCode);
  99. if (resultCode == Activity.RESULT_OK) {
  100. //选择照片
  101. if(requestCode == Globals.CHOOSE_PIC_REQUEST_CODE){
  102.  
  103. if (data != null) {
  104. selPhotosPath = data.getStringArrayListExtra(PhotoPicker.KEY_SELECTED_PHOTOS);
  105. }
  106. if (selPhotosPath != null) {
  107.  
  108. //下面的代码主要用于这样一个场景,就是注释了.setSelected(selPhotosPath)之后,还想要保证选择的图片不重复
  109. /*for(String path : selPhotosPath){
  110. Log.w(TAG,"path="+path);///storage/emulated/0/tempHxzk/IMG_1498034535796.jpg
  111. boolean existThisPic = false;
  112. for(int i=0;i<mPictureBeansList.size();i++){
  113. if(path.equals(mPictureBeansList.get(i).getPicPath())){
  114. //如果新选择的图片集合中存在之前选中的图片,那么跳过去
  115. existThisPic = true;
  116. break;
  117. }
  118. }
  119. if(! existThisPic){
  120. PictureBean pictureBean = new PictureBean();
  121. pictureBean.setPicPath(path);
  122. pictureBean.setPicName(getFileName(path));
  123. //去掉总数目的限制,这里通过增大MAX的数字来实现
  124. if (mPictureBeansList.size() < mPictureAdapter.MAX) {
  125. mPictureBeansList.add(pictureBean);
  126. } else {
  127. Toast.makeText(MainActivity.this, "最多可以选择" + mPictureAdapter.MAX + "张图片", Toast.LENGTH_SHORT).show();
  128. break;
  129. }
  130. }
  131. }*/
  132.  
  133. //是常规操作,和上面的代码不可共存
  134. for (String path : selPhotosPath) {
  135. PictureBean pictureBean = new PictureBean();
  136. pictureBean.setPicPath(path);
  137. pictureBean.setPicName(Globals.getFileName(path));
  138. //去掉总数目的限制,这里通过增大MAX的数字来实现
  139. if (mPictureBeansList.size() < mPictureAdapter.MAX) {
  140. mPictureBeansList.add(pictureBean);
  141. } else {
  142. Toast.makeText(MainActivity.this, "最多可以选择" + mPictureAdapter.MAX + "张图片", Toast.LENGTH_SHORT).show();
  143. break;
  144. }
  145. }
  146. mPictureAdapter.notifyDataSetChanged();
  147. }
  148. }
  149. }
  150. }
  151. }

混淆配置

  1. # PhotoPicker混淆
  2. # Glide
  3. -keep public class * implements com.bumptech.glide.module.GlideModule
  4. -keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
  5. **[] $VALUES;
  6. public *;
  7. }
  8. # support-v7-appcompat
  9. -keep public class android.support.v7.widget.** { *; }
  10. -keep public class android.support.v7.internal.widget.** { *; }
  11. -keep public class android.support.v7.internal.view.menu.** { *; }
  12. -keep public class * extends android.support.v4.view.ActionProvider {
  13. public <init>(android.content.Context);
  14. }
  15. # support-design
  16. -dontwarn android.support.design.**
  17. -keep class android.support.design.** { *; }
  18. -keep interface android.support.design.** { *; }
  19. -keep public class android.support.design.R$* { *; }

参考资料

donglua/PhotoPicker

项目demo下载地址

https://github.com/haiyuKing/PhotoPickerNewDemo

PhotoPickerNewDemo【PhotoPicker0.9.12的个性化修改以及使用(内部glide版本号是4.1.1)】的更多相关文章

  1. PhotoPickerDemo【PhotoPicker0.9.8的个性化修改以及使用(内部glide版本号是3.7.0)】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 本Demo使用的是PhotoPicker 0.9.8版本,属于比较旧的版本,里面集成的glide版本号是3.7.0.本篇文章主要是留 ...

  2. Ubuntu 12/14 个性化配置

    计算机名:jianbao-pc    用户名:jianbao 修改 /opt目录的 用户名 及 用户组 : sudo chown -R jianbao:jianbao /opt Ubuntu 如何开启 ...

  3. 修改AssemblyInfo.cs自动生成版本号

    一. 版本号自动生成方法 1.把 AssemblyInfo.cs文件中的[assembly:AssemblyVersion("1.0.0.0")]改成[assembly:Assem ...

  4. nginx.conf(centos6, 1.12)主配置文件修改

    #nginx1.12 centos6.xuser admin admin;worker_processes 4; error_log /data/services/logs/nginx_error.l ...

  5. MySQL8.0.12版本密码修改策略问题

    查看密码策略(修改临时密码之后才可查看) show variables like 'validate_password%'; 8之前 validate_password_     8之后validat ...

  6. STS IDE 个性化修改

    JDK: Eclipse或MyEclipse文件系统不同步的解决方法 STS汉化: 1.解压STS中的language文件夹 以我的安装目录为例,我的STS的安装在D:盘下.将解压后的“languag ...

  7. 个性化修改Linux登录时的字符界面

    如果采用root账号登录编辑/etc/bashrc内容,那所有其他帐号登录都会提示相同的内容,如果想每个用户进行配置,那就去每个帐号的目录下去配置吧. 这里提供改一个文件所有帐号都能看到的个性显示内容 ...

  8. android studio 汉化 美化 个性化 修改 安卓工作室 2.3.3 最新版

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 先看一下效果. 建议全屏看图,或者新标签看图.

  9. Nginx修改版本信息或隐藏版本号

    一,隐藏版本号.首先说明,这个是某一方面隐藏,不是彻底隐藏.未隐藏之前查看nginx信息: 隐藏方法: 修改nginx.conf配置文件,在http { } 标签里边加入字段: server_toke ...

随机推荐

  1. spring boot整合shiro

    安全框架Shiro和Spring Security比较,本文主要围绕Shiro进行学习 一 Shiro 是一个强大而灵活的开源安全框架,能够清晰的处理认证 授权 管理会话以及,密码加密 01 .认证与 ...

  2. 各位情人节快乐, Python帮忙撒狗粮, 我连夜做了这个程序!

    阅读本文大概需要5分钟 码农的情人节 一年一度的情人节要来啦,这个浪漫温馨的节日,走在大街小巷,走在地铁里,走在商场里,走在电影院,姑娘们手里几乎都捧着一束花,心里都是乐滋滋的,一脸幸福的样子,忽然想 ...

  3. eclipse下搭建hibernate5.0环境

    hibernate引入的jar包:hibernate-release-5.0.12.Final.zip 数据库驱动:mysql-connector-java-5.1.46 二.安装hibernate插 ...

  4. grpc.go

    package,,), etcd.WithPrefix(), etcd.WithPrevKV()}     gw.wch = gw.c.Watch(gw.ctx, gw.target, opts... ...

  5. Python初学者必看(1)

    python介绍 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语言 ...

  6. CISP-PTE注册信息安全专业人员渗透测试工程师知识体系大纲

    CISP-PTE注册信息安全专业人员渗透测试工程师知识体系大纲 都是图.. 不足之处,欢迎补充

  7. java.lang.NoSuchMethodError: org.springframework.boot.builder.SpringApplicationBuilder.<init>([Ljava

    搭建spring cloud的时候,报以下错误: java.lang.NoSuchMethodError: org.springframework.boot.builder.SpringApplica ...

  8. 【SAP S/4 1511之变】:主数据之变

    本博文主要讲述SAP S/4 1511版本的变化,主要是跟ECC版本的对比.变化还是挺多的,相当一部分是后勤,但绝大部分还是财务成本这一块.作为从事S/4版本的从业者,了解1511版本的变化还是挺有必 ...

  9. C/C++反三角函数使用注意

    最近写的东西用到了数学库中的acos函数,但是代码在运行的时候有时候会出莫名其妙的错误,比如返回值是个特别大的数. 最后在debug 的时候发现acos返回的数据很奇怪,但是传入的参数明明没有问题,可 ...

  10. 聚焦“云开发圆桌论坛”,大前端Serverless大佬们释放了这些讯号!

    4月14日,由云加社区举办的TVP&腾讯云技术交流日云开发专场,暨"腾讯云-云开发圆桌论坛"在北京.深圳两地同步举行. 当天下午,一场主题为"基于大前端和node ...