忽然觉得简书不适合分享代码 看着很乱 所以我上博客分享了我的代码
首先记录一下写的比较好的二个
这个是调用PictureSelector 依赖来实现的 PictureSelector 主要是帮助多图选取的(简单)//www.greatytc.com/p/48fd284b70a6
这个完全是自己实现的(困难) //www.greatytc.com/p/fd61fce8a3ef
这个不知道好不好用https://www.cnblogs.com/zhangqie/p/6709179.html
https://cloud.tencent.com/developer/article/1331025
https://blog.csdn.net/qq_36416136/article/details/71552681
自己实现
主布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_white">
<include
android:id="@+id/include"
layout="@layout/titles" />
<Button
android:id="@+id/tv_btn_logout"
android:layout_width="match_parent"
android:layout_height="54dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginLeft="22dp"
android:layout_marginTop="10dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="5dp"
android:background="@drawable/btn_background"
android:text="提交"
android:textColor="@color/color_white"
android:textSize="18sp" />
<ScrollView
android:id="@+id/scroview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/tv_btn_logout"
android:layout_below="@+id/include"
android:orientation="vertical"
android:scrollbars="none">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/color_white"
android:orientation="horizontal">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tv_phone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="28dp"
android:layout_marginTop="10dp"
android:text="您的手机号、QQ号、邮箱是?"
android:textColor="@color/black"
android:textSize="18sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_toRightOf="@id/tv_phone"
android:text="(选填)"
android:textSize="15sp" />
<EditText
android:id="@+id/ed_fj"
android:layout_width="500dp"
android:layout_height="50dp"
android:layout_marginLeft="15dp"
android:layout_marginTop="50dp"
android:layout_marginRight="15dp"
android:background="@drawable/under_line_transparent"
android:hint="填写多种联系方式时,请用逗号分隔。"
android:imeOptions="actionDone"
android:inputType="number"
android:paddingLeft="20dp"
android:textSize="14sp" />
<TextView
android:id="@+id/tv_question"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/ed_fj"
android:layout_marginLeft="30dp"
android:layout_marginTop="30dp"
android:text="问题/意见描述"
android:textColor="@color/black"
android:textSize="17sp" />
<TextView
android:id="@+id/tv_required"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/ed_fj"
android:layout_marginLeft="5dp"
android:layout_marginTop="32dp"
android:layout_toRightOf="@id/tv_question"
android:text="(必填)"
android:textSize="14sp" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/ed_fj"
android:orientation="horizontal">
<TextView
android:id="@+id/et_xz"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginTop="30dp"
android:layout_marginRight="20dp"
android:text="(0/300)"
android:textSize="14sp" />
</RelativeLayout>
<EditText
android:id="@+id/ed_idea"
android:layout_width="500dp"
android:layout_height="184dp"
android:layout_below="@id/tv_question"
android:layout_marginLeft="15dp"
android:layout_marginTop="13dp"
android:layout_marginRight="15dp"
android:background="@drawable/under_line_transparent"
android:hint="请留下您宝贵的意见,字数不少于10个字"
android:imeOptions="actionDone"
android:maxLength="300"
android:paddingLeft="20dp"
android:paddingBottom="140dp"
android:textSize="14sp" />
<TextView
android:id="@+id/tv_sc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/ed_idea"
android:layout_marginLeft="17dp"
android:layout_marginTop="20dp"
android:text="上传图片"
android:textColor="@color/black"
android:textSize="18sp" />
<TextView
android:id="@+id/button_get_photo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/ed_idea"
android:layout_marginLeft="90dp"
android:layout_marginTop="23dp"
android:text="(选填,您可以上传3张)"
android:textSize="14sp" />
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tv_sc"
android:layout_marginLeft="10dp"
android:layout_marginTop="15dp"
android:layout_marginRight="10dp"
android:overScrollMode="never" />
</RelativeLayout>
</LinearLayout>
</ScrollView>
</RelativeLayout>
recyclerview item布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="85dp"
android:layout_height="85dp"
android:layout_centerInParent="true">
<ImageView
android:id="@+id/fiv"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginTop="10dp"
android:contentDescription="@null"
android:scaleType="centerCrop"
android:src="@color/cus_view_detail_lines" />
<LinearLayout
android:id="@+id/ll_del"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:gravity="end"
android:orientation="vertical">
<ImageView
android:id="@+id/iv_del"
android:layout_width="25dp"
android:layout_height="25dp"
android:contentDescription="@null"
android:scaleType="fitXY"
android:src="@mipmap/red" />
</LinearLayout>
<ImageView
android:id="@+id/iv_duration"
android:layout_width="80dp"
android:layout_height="80dp"
android:scaleType="centerCrop" />
</RelativeLayout>
</RelativeLayout>
java代码
集合工具类
public class Image {
private Bitmapphoto;
public Image(Bitmap photo) {
this.photo = photo;
}
public BitmapgetPhoto() {
return photo;
}
public void setPhoto(Bitmap photo) {
this.photo = photo;
}
}
recyclerview适配器
public class CommitsAdapterextends RecyclerView.Adapter {
//用于判断是否显示图标
//有图片
public static final int TYPE_CAMERA =1;
//没有图片
public static final int TYPE_PICTURE =2;
private LayoutInflatermInflater;
private Contextcontext;
private int selectMax =4;
/**
* 点击添加图片跳转
*/
private onAddPicClickListenermOnAddPicClickListener;
public interface onAddPicClickListener {
void onAddPicClick();
}
//获取最大显示个数
public void setSelectMax(int selectMax) {
this.selectMax = selectMax;
}
//获取图片集合
this.list = list;
}
public CommitsAdapter(Context context, onAddPicClickListener mOnAddPicClickListener) {
this.context = context;
mInflater = LayoutInflater.from(context);
this.mOnAddPicClickListener = mOnAddPicClickListener;
}
/**
* 创建ViewHolder
*/
@NonNull
@Override
public ViewHolderonCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view =mInflater.inflate(R.layout.photo_item,
viewGroup, false);
final ViewHolder viewHolder =new ViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder viewHolder, int position) {
//少于selectMax张,显示继续添加的图标
if (getItemViewType(position) ==TYPE_CAMERA) {
// Image image = list.get(position);
viewHolder.mImg.setImageResource(R.mipmap.group);
// viewHolder.mImg.setImageBitmap(image.getPhoto());
viewHolder.mImg.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mOnAddPicClickListener.onAddPicClick();
}
});
viewHolder.ll_del.setVisibility(View.INVISIBLE);
}else {
Image image =list.get(position);
// viewHolder.mImg.setImageResource(R.mipmap.group);
viewHolder.mImg.setImageBitmap(image.getPhoto());
viewHolder.ll_del.setVisibility(View.VISIBLE);
viewHolder.ll_del.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int index =viewHolder.getAdapterPosition();
// 这里有时会返回-1造成数据下标越界,具体可参考getAdapterPosition()源码,
// 通过源码分析应该是bindViewHolder()暂未绘制完成导致,知道原因的也可联系我~感谢
if (index != RecyclerView.NO_POSITION) {
list.remove(index);
notifyItemRemoved(index);
notifyItemRangeChanged(index, list.size());
// DebugUtil.i("delete position:", index + "--->remove after:" + list.size());
}
}
});
//itemView 的点击事件
if (mItemClickListener !=null) {
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int adapterPosition =viewHolder.getAdapterPosition();
mItemClickListener.onItemClick(adapterPosition, v);
}
});
}
}
}
//点击事件接口
protected OnItemClickListenermItemClickListener;
public interface OnItemClickListener {
void onItemClick(int position, View v);
}
public void setOnItemClickListener(OnItemClickListener listener) {
this.mItemClickListener = listener;
}
@Override
public int getItemCount() {
//判断存储图片个数和最大个数
if (list.size()
return list.size() +1;
}else {
return list.size();
}
}
//形式:条件表达式 ?程序块1 :程序块2 ;
//含义:如果条件表达式为真,则本程序语句执行程序块1,程序块1的值即为整个表达式的值, 否则为表达式2的值。
private boolean isShowAddItem(int position) {
int size =list.size() ==0 ?0 :list.size();
return position == size;
}
@Override
public int getItemViewType(int position) {
if (isShowAddItem(position)) {
//有图片
return TYPE_CAMERA;
}else {
//没有图片
return TYPE_PICTURE;
}
}
public class ViewHolderextends RecyclerView.ViewHolder {
ImageViewmImg;
LinearLayoutll_del;
ImageViewiv_duration;
public ViewHolder(@NonNull View view) {
super(view);
mImg = (ImageView) view.findViewById(R.id.fiv);
ll_del = (LinearLayout) view.findViewById(R.id.ll_del);
iv_duration = (ImageView) view.findViewById(R.id.iv_duration);
}
}
}
主类
public class CommitsActivityextends Activity {
public static final int CHOOSE_PHOTO =2;// 相册
private RecyclerViewrecyclerview;
private int maxSelectNum =3;//最多到几张还可以选择
private CommitsAdapteradapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
setContentView(R.layout.feedback_commits);
super.onCreate(savedInstanceState);
setinit();
setonclick();
}
private void setinit() {
recyclerview = findViewById(R.id.recyclerview); //设置布局管理器
// GridLayoutManager layoutManager = new GridLayoutManager(this, 3);
GridLayoutManager layoutManager =new GridLayoutManager(this, 3, LinearLayoutManager.VERTICAL,false);
recyclerview.setLayoutManager(layoutManager);
//设置adapter
adapter =new CommitsAdapter(this,onAddPicClickListener);
adapter.setList(selectList);
adapter.setSelectMax(maxSelectNum);
recyclerview.setAdapter(adapter);
}
private void setonclick() {
}
private CommitsAdapter.onAddPicClickListeneronAddPicClickListener =new CommitsAdapter.onAddPicClickListener() {
@Override
public void onAddPicClick() {
show();
}
};
private void show() {
final Dialog dialog =new Dialog(this, R.style.ActionSheetDialogStyle);
View inflate = LayoutInflater.from(this).inflate(R.layout.dialog_item, null);
//相册
Button bt_camera = inflate.findViewById(R.id.bt_camera);
//取消
Button bt_cancel = inflate.findViewById(R.id.bt_cancel);
dialog.setContentView(inflate);
Window dialogWindow = dialog.getWindow();
dialogWindow.setGravity(Gravity.BOTTOM);
WindowManager.LayoutParams lp = dialogWindow.getAttributes();
lp.y =20;
dialogWindow.setAttributes(lp);
bt_cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dialog.dismiss();
}
});
bt_camera.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dialog.dismiss();
if (ContextCompat.checkSelfPermission(CommitsActivity.this,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(CommitsActivity.this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE, android.Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
}else {
//从相册获取图片
openAlbum();
}
}
});
dialog.show();
}
private void openAlbum() {
Intent intent =new Intent("android.intent.action.GET_CONTENT");
intent.setType("image/*");
startActivityForResult(intent, CHOOSE_PHOTO);//打开相册
}
//相册
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 1:
if (grantResults.length >0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
openAlbum();
}else {
Toast.makeText(this, "你拒绝了权限申请,可能无法打开相册哟", Toast.LENGTH_SHORT).show();
}
break;
default:
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case CHOOSE_PHOTO:
if (resultCode ==RESULT_OK) {
// 判断手机系统版本号
if (Build.VERSION.SDK_INT >=19) {
// 4.4及以上系统使用这个方法处理图片
handleImageOnKitKat(data);
}else {
// 4.4以下系统使用这个方法处理图片
handleImageBeforeKitKat(data);
}
}
break;
default:
break;
}
}
@TargetApi(19)
private void handleImageOnKitKat(Intent data) {
String imagePath =null;
Uri uri = data.getData();
if (DocumentsContract.isDocumentUri(this, uri)) {
// 如果是document类型的Uri,则通过document id处理
String docId = DocumentsContract.getDocumentId(uri);
if ("com.android.providers.media.documents".equals(uri.getAuthority())) {
String id = docId.split(":")[1]; // 解析出数字格式的id
String selection = MediaStore.Images.Media._ID +"=" + id;
imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection);
}else if ("com.android.providers.downloads.documents".equals(uri.
getAuthority())) {
Uri contentUri = ContentUris.withAppendedId(Uri.parse("content: downloads/public_downloads"), Long.valueOf(docId));
imagePath = getImagePath(contentUri, null);
}
}else if ("content".equalsIgnoreCase(uri.getScheme())) {
// 如果是content类型的Uri,则使用普通方式处理
imagePath = getImagePath(uri, null);
}else if ("file".equalsIgnoreCase(uri.getScheme())) {
// 如果是file类型的Uri,直接获取图片路径即可
imagePath = uri.getPath();
}
displayImage(imagePath); // 根据图片路径显示图片
// mWeiboDialog = WeiboDialogUtils.createLoadingDialog(FeedbackDetails.this, "加载中...");
// handler.sendEmptyMessageDelayed(1, 2000);
}
private void handleImageBeforeKitKat(Intent data) {
Uri uri = data.getData();
String imagePath = getImagePath(uri, null);
displayImage(imagePath);
// mWeiboDialog = WeiboDialogUtils.createLoadingDialog(FeedbackDetails.this, "加载中...");
// handler.sendEmptyMessageDelayed(1, 2000);
}
private StringgetImagePath(Uri uri, String selection) {
String path =null;
// 通过Uri和selection来获取真实的图片路径
Cursor cursor = getContentResolver().query(uri, null, selection, null, null);
if (cursor !=null) {
if (cursor.moveToFirst()) {
path = cursor.getString(cursor.getColumnIndex(MediaStore.
Images.Media.DATA));
}
cursor.close();
}
return path;
}
private void displayImage(String imagePath) {
BitmapFactory.Options options =new BitmapFactory.Options();
options.inJustDecodeBounds =false;
// Bitmap bitmap = BitmapFactory.decodeFile(imagePath, options);
Bitmap bitmap1=getBitmapFromUri(this, getImageContentUri(this,imagePath));
if (bitmap1 !=null) {
//获取图片
// File headFile = null;
//把获取到的图片放进集合里 每次获取一个
selectList.add(new Image(bitmap1));
adapter.setList(selectList);
adapter.notifyDataSetChanged();
//把bitmap转为数组
// File headFile = saveMyBitmap(bitmap1, "head");
// upphoto(headFile);
}else {
Toast.makeText(this, "获取图片失败", Toast.LENGTH_SHORT).show();
}
}
// 通过uri加载图片
public static BitmapgetBitmapFromUri(Context context, Uri uri) {
try {
ParcelFileDescriptor parcelFileDescriptor =
context.getContentResolver().openFileDescriptor(uri, "r");
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
parcelFileDescriptor.close();
return image;
}catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static UrigetImageContentUri(Context context, String path) {
Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[] { MediaStore.Images.Media._ID }, MediaStore.Images.Media.DATA +"=? ",
new String[] { path }, null);
if (cursor !=null && cursor.moveToFirst()) {
int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID));
Uri baseUri = Uri.parse("content://media/external/images/media");
return Uri.withAppendedPath(baseUri, "" + id);
}else {
// 如果图片不在手机的共享图片数据库,就先把它插入。
if (new File(path).exists()) {
ContentValues values =new ContentValues();
values.put(MediaStore.Images.Media.DATA, path);
return context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
}else {
return null;
}
}
}
//将bitmap转化为png格式
//首先获取了系统相册的地址,然后每次我拍下照片或者选择照片时,
// 都进行简单的压缩,因为图片要上传到服务器进行审核管理,做成微信头像之类的超级压缩方法有损画质,
// 所以我只是进行了简单的压缩上传最后写成一个文件。(在第二个页面的时候可能会有几个问题,
// 三个ImageView即是三个bitmap,三个File文件。如何判断及正确的显示,我们可以定义成全局变量,
// 因为都是点击事件,所以bitmap会在点击后修改,然后保存下来。
public FilesaveMyBitmap(Bitmap mBitmap, String prefix) {
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
File file =null;
try {
file = File.createTempFile(
prefix, /* prefix */
".jpg"
// , /* suffix */
// storageDir /* directory */
);
FileOutputStream fos =new FileOutputStream(file); //创建一个字节数组输出流对象
//Bitmap.CompressFormat format 图像的压缩格式;
//int quality 图像压缩率,0-100。 0 压缩100%,100意味着不压缩;
//OutputStream stream 写入压缩数据的输出流;
mBitmap.compress(Bitmap.CompressFormat.JPEG, 50, fos);//通过bitmap中的compress,将图片压缩到os流对象中.
//其中第二个参数quality,为100表示不压缩,如果为80,表示压缩百分之20.
// Bitmap.createScaledBitmap(mBitmap, mBitmap.getWidth()/2, mBitmap.getHeight()/2, true);
fos.flush();
fos.close();
}catch (Exception e) {
e.printStackTrace();
}
return file;
}
}