版权声明:本文为HaiyuKing原创文章,转载请注明出处!
前言
本Demo使用的是PhotoPicker 0.9.8版本,属于比较旧的版本,里面集成的glide版本号是3.7.0。本篇文章主要是留作记录。
在项目中使用建议使用《PhotoPickerNewDemo【PhotoPicker0.9.12的个性化修改以及使用(内部glide版本号是4.1.1)】》
效果图
代码分析
在原有的代码基础上根据实际项目需求进行了部分修改:
1、对MediaStoreHelper进行了优化【解决dialogFragment中显示问题】
2、添加NewImagePagerDialogFragment.java【和ImagePagerFragment.java代码类似,不同的是多了顶部导航栏】【用于独立出来进行图片预览对话框】
3、添加NewPhotoPickerFragment.java【基本上等同于PhotoPickerFragment,但是区别在于预览图片打开的是NewImagePagerDialogFragment,而且多了一个状态值:是否全屏显示预览界面】【用于独立出来作为Fragment集成到自定义Activity中】
4、修改颜色、高度和替换部分图片
使用步骤
一、项目组织结构图
注意事项:
1、 导入类文件后需要change包名以及重新import R文件路径
2、 Values目录下的文件(strings.xml、dimens.xml、colors.xml等),如果项目中存在,则复制里面的内容,不要整个覆盖
二、导入步骤
(1)将PhotoPicker导入到项目中
(2)解决Plugin with id 'com.novoda.bintray-release' not found.问题
在项目的build.gradle文件中添加以下代码
// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
//解决PhotoPicker的Plugin with id 'com.novoda.bintray-release' not found.
classpath 'com.novoda:bintray-release:0.5.0' // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
} allprojects {
repositories {
google()
jcenter()
}
} task clean(type: Delete) {
delete rootProject.buildDir
}
三、使用方法
(1)在app的build.gradle文件中引用photopicker
因为Demo中使用到了RecyclerVIew,所以还需要在app的build.gradle文件中引用recyclerview【版本号和appcompat保持一致】
apply plugin: 'com.android.application' android {
compileSdkVersion 27
defaultConfig {
applicationId "com.why.project.photopickerdemo"
minSdkVersion 16
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
} dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
//photopicker
implementation project(':PhotoPicker') //RecyclerView
compile 'com.android.support:recyclerview-v7:27.1.1' }
(2)演示调用写法
1、在项目中实现Recyclerview基本数据展现【比较简单,省略】【或者参考《Android快速开发常用知识点系列目录》下的RecyclerView篇章相关文章】
注意:因为PhotoPicker中已经引用了Glide3.7.0,所以PictureAdapter.java中可以直接使用Glide
package com.why.project.photopickerdemo.adapter; import android.content.Context;
import android.net.Uri;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView; import com.bumptech.glide.Glide;
import com.bumptech.glide.Priority;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.why.project.photopickerdemo.R;
import com.why.project.photopickerdemo.bean.PictureBean; import java.io.File;
import java.util.ArrayList;
import java.util.List; /**
* Created by HaiyuKing
* Used 照片网格适配器
*/ public class PictureAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{ private static final String TAG = PictureAdapter.class.getSimpleName(); /**上下文*/
private Context myContext;
/**自定义列表项标题集合*/
private ArrayList<PictureBean> listitemList; final static int TYPE_ADD = 1;
final static int TYPE_PHOTO = 2; public final static int MAX = 15;//总数目,这里根据实际情况设置,设置100基本上表明无限制了 /*
* 构造函数
*/
public PictureAdapter(Context context, ArrayList<PictureBean> itemlist) {
myContext = context;
listitemList = itemlist;
} /**
* 获取总的条目数
*/
@Override
public int getItemCount() {
Log.w(TAG,"{getItemCount}listitemList.size()="+listitemList.size());
int count = listitemList.size();
if (count > MAX) {
count = MAX;
}
count = count + 1;
return count;
} @Override
public int getItemViewType(int position) {
Log.w(TAG,"{getItemViewType}position="+position);
Log.w(TAG,"{getItemViewType}listitemList.size()="+listitemList.size());
return (position == listitemList.size()) ? TYPE_ADD : TYPE_PHOTO;
} /**
* 创建ViewHolder
*/
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType == TYPE_ADD) {
View viewfoot = LayoutInflater.from(myContext).inflate(R.layout.pic_grid_foot_item, parent, false);
ItemFootViewHolder itemfootViewHolder = new ItemFootViewHolder(viewfoot);
return itemfootViewHolder;
} else if(viewType == TYPE_PHOTO) {
View view = LayoutInflater.from(myContext).inflate(R.layout.pic_grid_item, parent, false);
ItemViewHolder itemViewHolder = new ItemViewHolder(view);
return itemViewHolder;
}
return null;
} /**
* 声明列表项ViewHolder*/
static class ItemViewHolder extends RecyclerView.ViewHolder
{
public ItemViewHolder(View view)
{
super(view);
griditemLayout = (LinearLayout) view.findViewById(R.id.griditemLayout);
griditemimgLayout = (RelativeLayout) view.findViewById(R.id.griditemimgLayout);
grid_img = (ImageView) view.findViewById(R.id.grid_img);
grid_img_state = (TextView) view.findViewById(R.id.grid_img_state);
} LinearLayout griditemLayout;
RelativeLayout griditemimgLayout;
ImageView grid_img; TextView grid_img_state;
} /**
* 声明最后一个ViewHolder*/
static class ItemFootViewHolder extends RecyclerView.ViewHolder
{
public ItemFootViewHolder(View view)
{
super(view);
gridfootitemLayout = (RelativeLayout) view.findViewById(R.id.gridfootitemLayout);
}
RelativeLayout gridfootitemLayout;
} /**
* 将数据绑定至ViewHolder
*/
@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int index) { if(viewHolder instanceof ItemViewHolder){
PictureBean listItemModel = listitemList.get(index);
final ItemViewHolder itemViewHold = ((ItemViewHolder)viewHolder); Uri uri = Uri.fromFile(new File(listItemModel.getPicPath())); Glide.with(myContext)
.load(uri)
//设置等待时的图片
.placeholder(R.drawable.img_loading)
//设置加载失败后的图片显示
.error(R.drawable.img_error)
//默认淡入淡出动画
.crossFade()
//缓存策略,跳过内存缓存【此处应该设置为false,否则列表刷新时会闪一下】
.skipMemoryCache(false)
//缓存策略,硬盘缓存-仅仅缓存最终的图像,即降低分辨率后的(或者是转换后的)
.diskCacheStrategy(DiskCacheStrategy.ALL)
//设置图片加载的优先级
.priority(Priority.HIGH)
.into(itemViewHold.grid_img); itemViewHold.grid_img_state.setText("(" + (index+1) + "/" + listitemList.size() + ")"); //如果设置了回调,则设置点击事件
if (mOnItemClickLitener != null)
{
itemViewHold.grid_img.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int position = itemViewHold.getLayoutPosition();//在增加数据或者减少数据时候,position和index就不一样了
mOnItemClickLitener.onItemClick(view,position);
}
});
}
}else if(viewHolder instanceof ItemFootViewHolder){
final ItemFootViewHolder itemFootViewHold = ((ItemFootViewHolder)viewHolder);
//如果设置了回调,则设置点击事件
if (mOnItemClickLitener != null)
{
itemFootViewHold.gridfootitemLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mOnItemClickLitener.onItemAddClick();
}
});
}
} } /**
* 添加Item--用于动画的展现*/
public void addItem(int position,PictureBean itemModel) {
listitemList.add(position,itemModel);
notifyItemInserted(position);
}
/**
* 删除Item--用于动画的展现*/
public void removeItem(int position) {
listitemList.remove(position);
notifyItemRemoved(position);
} /*=====================添加OnItemClickListener回调================================*/
public interface OnItemClickLitener
{
/**图片的点击事件*/
void onItemClick(View view,int position);
/**添加的点击事件*/
void onItemAddClick();
} private OnItemClickLitener mOnItemClickLitener; public void setOnItemClickLitener(OnItemClickLitener mOnItemClickLitener)
{
this.mOnItemClickLitener = mOnItemClickLitener;
} //返回当前图片集合的所有路径集合【用于预览】
public List<String> getAllPhotoPaths() {
List<String> allPhotoPaths = new ArrayList<String>(listitemList.size());
for (PictureBean pictureBean: listitemList) {
allPhotoPaths.add(pictureBean.getPicPath());
}
return allPhotoPaths;
} }
2、在代码中调用【橙色标记的是recyclerView常规写法,黄色标记的是PhotoPicker的调用,绿色标记是打开自定义图片预览对话框NewImagePagerDialogFragment,紫色标记的是自定义选图对话框界面】
package com.why.project.photopickerdemo; import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast; import com.why.project.photopickerdemo.adapter.PictureAdapter;
import com.why.project.photopickerdemo.bean.PictureBean;
import com.why.project.photopickerdemo.utils.Globals; import java.util.ArrayList;
import java.util.List; import me.iwf.photopicker.PhotoPicker;
import me.iwf.photopicker.fragment.NewImagePagerDialogFragment;
import me.iwf.photopicker.utils.PermissionsUtils; public class MainActivity extends AppCompatActivity { private static final String TAG = MainActivity.class.getSimpleName(); private RecyclerView mRecyclerView;
private ArrayList<PictureBean> mPictureBeansList;
private PictureAdapter mPictureAdapter; private ArrayList<String> selPhotosPath = null;//选中的图片路径集合 private Button mOpenPicDialog; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); initViews();
initDatas();
initEvents();
} private void initViews() {
mRecyclerView = findViewById(R.id.picture_grid);
mOpenPicDialog = findViewById(R.id.btn_openPicDialog);
} private void initDatas() {
selPhotosPath = new ArrayList<String>();
//=============图片九宫格=========================
mPictureAdapter = null;
mPictureBeansList = new ArrayList<PictureBean>();
//设置布局管理器
GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 3);
mRecyclerView.setLayoutManager(gridLayoutManager); if(mPictureAdapter == null){
//设置适配器
mPictureAdapter = new PictureAdapter(this, mPictureBeansList);
mRecyclerView.setAdapter(mPictureAdapter);
//添加分割线
//设置添加删除动画
//调用ListView的setSelected(!ListView.isSelected())方法,这样就能及时刷新布局
mRecyclerView.setSelected(true);
}else{
mPictureAdapter.notifyDataSetChanged();
}
} private void initEvents() {
//图片九宫格点击事件
mPictureAdapter.setOnItemClickLitener(new PictureAdapter.OnItemClickLitener() {
@Override
public void onItemClick(View v,int position) {
//打开自定义的图片预览对话框
List<String> photos = mPictureAdapter.getAllPhotoPaths(); int[] screenLocation = new int[2];
v.getLocationOnScreen(screenLocation); NewImagePagerDialogFragment newImagePagerDialogFragment = NewImagePagerDialogFragment.getInstance(MainActivity.this,photos,position,screenLocation, v.getWidth(),
v.getHeight(),false);
newImagePagerDialogFragment.show(getSupportFragmentManager(),"preview img");
} @Override
public void onItemAddClick() {
PhotoPicker.builder()
.setPhotoCount(mPictureAdapter.MAX)
.setGridColumnCount(3)
//.setSelected(selPhotosPath)
.start(MainActivity.this, Globals.CHOOSE_PIC_REQUEST_CODE);
}
}); //按钮的点击事件
mOpenPicDialog.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (PermissionsUtils.checkReadStoragePermission(MainActivity.this)) {//调用PhotoPicker中的运行时权限申请工具类,在这里也可以使用其他运行时权限申请库
Bundle bundle = new Bundle();
bundle.putInt(SelectPictureDialog.EXTRA_MAX_COUNT, 1);
SelectPictureDialog selectPictureDialog = SelectPictureDialog.getInstance(MainActivity.this, bundle);
selectPictureDialog.setOnSelPicDialogConfirmClickListener(new SelectPictureDialog.OnSelPicDialogConfirmClickListener() {
@Override
public void onConfirmClick(ArrayList<PictureBean> selectedPhotoList) {
String path = "";
if (selectedPhotoList.size() > 0) {
path = selectedPhotoList.get(0).getPicPath();
}
Toast.makeText(MainActivity.this, "path=" + path, Toast.LENGTH_SHORT).show();
}
});
selectPictureDialog.show(getSupportFragmentManager(), "previewWithScreen");
}
}
});
} @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data); Log.w(TAG, "{onActivityResult}resultCode="+resultCode);
Log.w(TAG, "{onActivityResult}requestCode="+requestCode);
if (resultCode == Activity.RESULT_OK) {
//选择照片
if(requestCode == Globals.CHOOSE_PIC_REQUEST_CODE){ if (data != null) {
selPhotosPath = data.getStringArrayListExtra(PhotoPicker.KEY_SELECTED_PHOTOS);
}
if (selPhotosPath != null) { //下面的代码主要用于这样一个场景,就是注释了.setSelected(selPhotosPath)之后,还想要保证选择的图片不重复
/*for(String path : selPhotosPath){
Log.w(TAG,"path="+path);///storage/emulated/0/tempHxzk/IMG_1498034535796.jpg
boolean existThisPic = false;
for(int i=0;i<mPictureBeansList.size();i++){
if(path.equals(mPictureBeansList.get(i).getPicPath())){
//如果新选择的图片集合中存在之前选中的图片,那么跳过去
existThisPic = true;
break;
}
}
if(! existThisPic){
PictureBean pictureBean = new PictureBean();
pictureBean.setPicPath(path);
pictureBean.setPicName(getFileName(path));
//去掉总数目的限制,这里通过增大MAX的数字来实现
if (mPictureBeansList.size() < mPictureAdapter.MAX) {
mPictureBeansList.add(pictureBean);
} else {
Toast.makeText(MainActivity.this, "最多可以选择" + mPictureAdapter.MAX + "张图片", Toast.LENGTH_SHORT).show();
break;
}
}
}*/ //是常规操作,和上面的代码不可共存
for (String path : selPhotosPath) {
PictureBean pictureBean = new PictureBean();
pictureBean.setPicPath(path);
pictureBean.setPicName(Globals.getFileName(path));
//去掉总数目的限制,这里通过增大MAX的数字来实现
if (mPictureBeansList.size() < mPictureAdapter.MAX) {
mPictureBeansList.add(pictureBean);
} else {
Toast.makeText(MainActivity.this, "最多可以选择" + mPictureAdapter.MAX + "张图片", Toast.LENGTH_SHORT).show();
break;
}
}
mPictureAdapter.notifyDataSetChanged();
}
}
}
} }
3、SelectPictureDialog中主要集成了NewPhotoPickerFragment,这里只是一个简单的写法,本来是有一个选项卡功能的,这里做了简化
package com.why.project.photopickerdemo; import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
import android.widget.Toast; import com.why.project.photopickerdemo.bean.PictureBean;
import com.why.project.photopickerdemo.utils.Globals; import java.util.ArrayList;
import java.util.List; import me.iwf.photopicker.fragment.NewPhotoPickerFragment; /**
* Created by HaiyuKing
* Used 选择图片对话框
*/ public class SelectPictureDialog extends DialogFragment {
private static final String TAG = SelectPictureDialog.class.getSimpleName(); /**View实例*/
private View myView;
/**context实例*/
private Context mContext;
/**标记:用来代表是从哪个界面打开的这个对话框*/
private String mTag; /**完成文本*/
private TextView mConfirmTv; public static final String EXTRA_MAX_COUNT = "maxCount";
public static final int DEFAULT_MAX_COUNT = 1;//默认只能选择一个图片 private boolean previewEnabled = true;//是否可预览
private boolean showGif = false;//是否显示gif
private int columnNumber = 3;//一行显示多少列
private int maxCount = 1;//最大可选择的数目
private Boolean fullscreen = false;//是否全屏展现预览界面的标志 private FragmentManager fragmentManager;//碎片管理器
private NewPhotoPickerFragment mLocalPicFragment; public static SelectPictureDialog getInstance(Context mContext, Bundle bundle)
{
SelectPictureDialog selectPictureDialog = new SelectPictureDialog();
selectPictureDialog.mContext = mContext;
selectPictureDialog.maxCount = bundle.getInt(EXTRA_MAX_COUNT,DEFAULT_MAX_COUNT); return selectPictureDialog;
} @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.w(TAG,"{onCreate}"); setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_NoTitleBar_Fullscreen);//全屏(在状态栏底下)
} @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.w(TAG,"{onCreateView}"); getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(0));//设置背景为透明,并且没有标题
getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);// 去掉标题栏
//设置窗体全屏
getDialog().getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); myView = inflater.inflate(R.layout.dialog_select_picture, container, false);
return myView;
} @Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
Log.w(TAG,"{onActivityCreated}"); //初始化控件以及设置
initView();
//初始化数据
initDatas();
//初始化事件
initEvent(); //初始化碎片管理器
fragmentManager = getChildFragmentManager();//必须使用getChildFragmentManager,否则子Fragment中无法使用getParentFragment获取父fragment } /**
* 设置宽度和高度值,以及打开的动画效果
*/
@Override
public void onStart() {
super.onStart();
if(mTag.equals("previewWithScreen")){//对话框全屏显示,预览图片也是全屏显示
fullscreen = true;
//设置对话框的宽高,必须在onStart中
Window window = this.getDialog().getWindow();
window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);//全屏(盖住状态栏)
window.setGravity(Gravity.BOTTOM);//设置在底部
//打开的动画效果--缩放+渐隐
}else{
fullscreen = false;
//设置对话框的宽高,必须在onStart中
DisplayMetrics metrics = new DisplayMetrics();
this.getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
Window window = this.getDialog().getWindow();
window.setLayout(metrics.widthPixels, metrics.heightPixels - getStatusBarHeight(mContext));
window.setGravity(Gravity.BOTTOM);//设置在底部
//打开的动画效果--缩放+渐隐
}
} /**获取状态栏的高度*/
private int getStatusBarHeight(Context context) {
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
return context.getResources().getDimensionPixelSize(resourceId);
} @Override
public void onResume() {
// TODO Auto-generated method stub
super.onResume();
ShowFragment();
} private void initView() {
mConfirmTv = (TextView) myView.findViewById(R.id.nav_selpic_edit_save);
} private void initDatas() {
mTag = this.getTag();
} private void initEvent() {
//完成图标
mConfirmTv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//返回界面,并传递值回去
ArrayList<PictureBean> selectedPhotoList = new ArrayList<PictureBean>(); if(maxCount <= 1){
ArrayList<String> selectedPhotos = new ArrayList<String>();
if(mLocalPicFragment != null) {
selectedPhotos = mLocalPicFragment.getPhotoGridAdapter().getSelectedPhotoPaths();
}
String imgPath = selectedPhotos.get(0);
PictureBean pictureBean = new PictureBean();
pictureBean.setPicPath(imgPath);
pictureBean.setPicName(Globals.getFileName(imgPath));
selectedPhotoList.add(pictureBean);
}else{
ArrayList<String> selectedPhotos = new ArrayList<String>();
if(mLocalPicFragment != null) {
selectedPhotos = mLocalPicFragment.getPhotoGridAdapter().getSelectedPhotoPaths();
}
for(String path : selectedPhotos){
PictureBean pictureBean = new PictureBean();
pictureBean.setPicPath(path);
pictureBean.setPicName(Globals.getFileName(path));
selectedPhotoList.add(pictureBean);
}
} backWithResult(selectedPhotoList);
}
});
//刚开始设置不可点击【必须在setOnclick事件之后,否则不起作用】
changeConfirmState(false);
} private void ShowFragment() {
//开启一个事务
FragmentTransaction transcation = fragmentManager.beginTransaction();
if(mLocalPicFragment == null){
mLocalPicFragment = NewPhotoPickerFragment.getInstance(true, showGif, previewEnabled, columnNumber, maxCount, null,fullscreen);
initLocalFragmentAdapterItemCheckListener();//初始化本地图片碎片界面的列表项的复选框图标点击事件
transcation.add(R.id.center_layout, mLocalPicFragment);
}else{
transcation.show(mLocalPicFragment);
}
transcation.commitAllowingStateLoss();
} //本地图片的选择监听
private void initLocalFragmentAdapterItemCheckListener() {
//本地图片的选择的监听事件
mLocalPicFragment.setOnOnLocalPhotoCheckListener(new NewPhotoPickerFragment.OnLocalPhotoCheckListener() {
@Override
public boolean onItemCheck(int position, String imgId, String imgName, String imgPath, int selectedItemCount) {
//如果选中的数目小于0,则顶部导航栏右侧的完成文本,不可点击
if(selectedItemCount > 0){
changeConfirmState(true);
}else{
changeConfirmState(false);
} //如果单选,那么选中的图片路径集合肯定只有一个
if (maxCount <= 1) {
List<String> photos = mLocalPicFragment.getPhotoGridAdapter().getSelectedPhotos();
if (!photos.contains(imgPath)) {//如果点击的当前选中的图片,则取消选中状态
photos.clear();//清空选中的图片集合
mLocalPicFragment.getPhotoGridAdapter().notifyDataSetChanged();
}
return true;
} if (selectedItemCount > maxCount) {
Toast.makeText(mContext,getString(R.string.over_max_count_tips, maxCount),Toast.LENGTH_SHORT).show();
return false;
}
mConfirmTv.setText(getString(R.string.done_with_count, selectedItemCount, maxCount));//更改导航栏右侧的 完成(1/9)
return true;
}
});
} //更换完成文本的点击状态
private void changeConfirmState(boolean canClick){
if(canClick){
mConfirmTv.setClickable(true);
mConfirmTv.setTextColor(getResources().getColor(R.color.nav_done_text_color));
}else{
mConfirmTv.setClickable(false);
mConfirmTv.setTextColor(getResources().getColor(R.color.nav_done_ennable_text_color));
}
} private void backWithResult(ArrayList<PictureBean> photosList) {
dismiss();
if(mOnSelPicDialogConfirmClickListener != null){
mOnSelPicDialogConfirmClickListener.onConfirmClick(photosList);
}
} /*=====================添加OnConfirmClickListener回调================================*/
private OnSelPicDialogConfirmClickListener mOnSelPicDialogConfirmClickListener; public void setOnSelPicDialogConfirmClickListener(OnSelPicDialogConfirmClickListener mOnSelPicDialogConfirmClickListener)
{
this.mOnSelPicDialogConfirmClickListener = mOnSelPicDialogConfirmClickListener;
} public interface OnSelPicDialogConfirmClickListener {
void onConfirmClick(ArrayList<PictureBean> selectedPhotoList);
}
}
混淆配置
# PhotoPicker混淆
# Glide
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
# support-v7-appcompat
-keep public class android.support.v7.widget.** { *; }
-keep public class android.support.v7.internal.widget.** { *; }
-keep public class android.support.v7.internal.view.menu.** { *; }
-keep public class * extends android.support.v4.view.ActionProvider {
public <init>(android.content.Context);
}
# support-design
-dontwarn android.support.design.**
-keep class android.support.design.** { *; }
-keep interface android.support.design.** { *; }
-keep public class android.support.design.R$* { *; }
参考资料
项目demo下载地址
https://github.com/haiyuKing/PhotoPickerDemo
PhotoPickerDemo【PhotoPicker0.9.8的个性化修改以及使用(内部glide版本号是3.7.0)】的更多相关文章
-
PhotoPickerNewDemo【PhotoPicker0.9.12的个性化修改以及使用(内部glide版本号是4.1.1)】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 本Demo使用的是PhotoPicker 0.9.12版本,里面集成的glide版本号是4.1.1.这里就不进行特殊的个性化处理了( ...
-
修改AssemblyInfo.cs自动生成版本号
一. 版本号自动生成方法 1.把 AssemblyInfo.cs文件中的[assembly:AssemblyVersion("1.0.0.0")]改成[assembly:Assem ...
-
Windows Azure Cloud Service (41) 修改云服务IIS托管管道模式为4.0经典模式
<Windows Azure Platform 系列文章目录> 这是笔者在之前的项目中遇到的问题,做一下总结,给网友做参考. 在一般情况下,Visual Studio开发的Cloud Se ...
-
STS IDE 个性化修改
JDK: Eclipse或MyEclipse文件系统不同步的解决方法 STS汉化: 1.解压STS中的language文件夹 以我的安装目录为例,我的STS的安装在D:盘下.将解压后的“languag ...
-
个性化修改Linux登录时的字符界面
如果采用root账号登录编辑/etc/bashrc内容,那所有其他帐号登录都会提示相同的内容,如果想每个用户进行配置,那就去每个帐号的目录下去配置吧. 这里提供改一个文件所有帐号都能看到的个性显示内容 ...
-
android studio 汉化 美化 个性化 修改 安卓工作室 2.3.3 最新版
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha 先看一下效果. 建议全屏看图,或者新标签看图.
-
修改或隐藏Nginx的版本号
隐藏版本号 隐藏nginx的版本号很简单,nginx的HttpCoreModule提供了一条叫做server_tokens指令,我这要将这条指令设置为“server_tokens off”就可以了. ...
-
Nginx修改版本信息或隐藏版本号
一,隐藏版本号.首先说明,这个是某一方面隐藏,不是彻底隐藏.未隐藏之前查看nginx信息: 隐藏方法: 修改nginx.conf配置文件,在http { } 标签里边加入字段: server_toke ...
-
gradle修改AndroidManifest.xml中的版本号
def VersionCode = "19" ant.replaceregexp(file:"../Assets/Plugins/Android/AndroidManif ...
随机推荐
-
python 获取进程pid号
#-*- encoding:UTF-8 -*- import os import sys import string import psutil import re def get_pid(name) ...
-
HDU 4349 Xiao Ming&#39;s Hope
有这样一个性质:C(n,m)%p=C(p1,q1)*C(p2,q2).......%p,其中pkpk-1...p1,qkqk-1...q1分别是n,m在p进制下的组成. 就完了. #include&l ...
-
lintcode:Number of Islands 岛屿的个数
题目: 岛屿的个数 给一个01矩阵,求不同的岛屿的个数. 0代表海,1代表岛,如果两个1相邻,那么这两个1属于同一个岛.我们只考虑上下左右为相邻. 样例 在矩阵: [ [1, 1, 0, 0, 0], ...
-
Ubuntu 下配置Samba 实现Linux和windows之间文件共享
一 Samba 的安装: sudo apt-get insall sambasudo apt-get install smbfs 二 在Ubuntu中创建共享目录: mkdir /home/shar ...
-
ArcEngine载入中SDE问题栅格数据
当直接加载矢量数据到IFeatureWorkspace接口可,但是,在装载门格当要传送的数据IRasterWorkspaceEx接口. 效果如下面的,对可以被添加到双击Globe在. watermar ...
-
python 计算两个日期相差多少个月
近期,由于业务需要计算两个日期之前相差多少个月.我在网上找了很久,结果发现万能的python,居然没有一个模块计算两个日期的月数,像Java.C#之类的高级语言,都会有(date1-date2).mo ...
-
201521123057《Java程序设计》第14周学习总结
0. 本周课程设计发布 Java课程设计 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多数据库相关内容. 数据库基本操作(目前为止主要介绍了表的基本操作) 创建表 CREATE ...
-
逆向工程-获得IPsearch的注册码
1)运行软件点击File->register 2)随便输入用户名和密码 3)记录弹窗的的关键字 4)发送到PEID查壳 4.1)未找到加密的壳 4.2)发送到OD打开,在反汇编目录下右键菜单找到 ...
-
gitbook build/serve 失败,Error: ENOENT: no such file or directory, stat ...
我使用的 gitbook 版本 CLI version: 2.3.2 GitBook version: 3.2.3 在使用 gitbook 生成文档时,发现编译偶尔不规律性地出现错误 d:\Mine\ ...
-
通用jsonp跨域技术获取天气数据
1. 前言 在进行网站开发的过程中经常会用到第三方的数据,但是由于同源策略的限制导致ajax不能发送请求,因此也无法获得数据.解决ajax的跨域问题可以使用jsonp技术 2.代码 <!DOCT ...