Android 选择图片、上传图片之PictureSelector
如图:
拍照、相册使用开源库PictureSelector
https://github.com/LuckSiege/PictureSelector 目前是一直在维护的,支持从相册或拍照选择图片或视频、音频,支持动态权限获取、裁剪(单图or多图裁剪)、压缩、主题自定义配置等功能、适配android 6.0+系统,而且你能遇到的问题,README文档都有解决方案。
添加依赖
repositories { google() mavenCentral() } dependencies { implementation 'io.github.lucksiege:pictureselector:v2.7.3-rc10' }
一个底部透明Fragment: BottomPictureFragment
package com.xzh.cssmartandroid.dialog import android.app.Dialog import android.content.Context import android.graphics.Color import android.graphics.drawable.ColorDrawable import android.os.Bundle import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.FrameLayout import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.xzh.cssmartandroid.R import com.xzh.cssmartandroid.databinding.FragmentBottomPictureBinding import com.xzh.cssmartandroid.ui.main.me.profile.UserProfileFragment class BottomPictureFragment: BottomSheetDialogFragment() { private lateinit var binding: FragmentBottomPictureBinding override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { Log.i("打印执行顺序:","onCreateDialog...") //return super.onCreateDialog(savedInstanceState) //返回这个不能设置圆角 //return BottomSheetDialog(requireContext()) //返回这个可以返回圆角 return if (mContext == null) { super.onCreateDialog(savedInstanceState) } else BottomSheetDialog(requireContext(), R.style.TransparentBottomSheetStyle) } private var mContext: Context? = context override fun onStart() { Log.i("打印执行顺序:","onStart...") super.onStart() //获取dialog对象 var dialog: BottomSheetDialog = dialog as BottomSheetDialog //点击外面是否允许取消 //dialog.setCanceledOnTouchOutside(false) //禁止手势拖动滑动 //dialog.setCancelable(false) //把windowsd的默认背景颜色去掉,不然圆角显示不见 dialog.window?.findViewById<View>(R.id.design_bottom_sheet)?.setBackgroundDrawable( ColorDrawable(Color.TRANSPARENT) ) //dialog.window?.findViewById<View>(R.id.design_bottom_sheet)?.setBackgroundColor(Color.TRANSPARENT) //获取diglog的根部局 var bottomSheet = dialog.delegate.findViewById<FrameLayout>(R.id.design_bottom_sheet) if (bottomSheet != null) { //获取根部局的LayoutParams对象 var layoutParams = bottomSheet.layoutParams //layoutParams.height = getPeekHeight() //修改弹窗的最大高度,不允许上滑(默认可以上滑) bottomSheet.layoutParams = layoutParams var behavior: BottomSheetBehavior<FrameLayout> = BottomSheetBehavior.from(bottomSheet) //behavior = BottomSheetBehavior.from(bottomSheet) //peekHeight即弹窗的最大高度 //behavior.peekHeight = getPeekHeight() // 初始为展开状态 behavior.state = BottomSheetBehavior.STATE_EXPANDED //关闭弹窗 //behavior.setState(BottomSheetBehavior.STATE_HIDDEN); } } /** * 弹窗高度,默认为屏幕高度的四分之三 * 子类可重写该方法返回peekHeight * * @return height */ fun getPeekHeight():Int { var peekHeight = resources.displayMetrics.heightPixels //设置弹窗高度为屏幕高度的3/4 return peekHeight - peekHeight / 3; } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { binding = FragmentBottomPictureBinding.inflate(layoutInflater) binding.camera.setOnClickListener { mListener?.onDialogClick(UserProfileFragment.TAG_LABEL_CAMERA) dismiss() } binding.photo.setOnClickListener { mListener?.onDialogClick(UserProfileFragment.TAG_LABEL_PHOTO) dismiss() } binding.cancel.setOnClickListener { dismiss() } return binding.root } interface OnDialogListener { fun onDialogClick(select: String?) } fun setOnDialogListener(dialogListener: OnDialogListener) { this.mListener = dialogListener } var mListener: OnDialogListener? = null }
布局文件:
<?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="vertical" android:background="@drawable/bottom_picture_bg"> <TextView android:id="@+id/camera" android:layout_width="match_parent" android:layout_height="60dp" android:text="@string/take_picture" android:textSize="16sp" android:textColor="@color/text_primary" android:gravity="center" android:layout_marginTop="10dp"></TextView> <View android:layout_width="match_parent" android:layout_height="0.5dp" android:background="@color/bg_search"/> <TextView android:id="@+id/photo" android:layout_width="match_parent" android:layout_height="60dp" android:text="@string/photo_album" android:textSize="16sp" android:textColor="@color/text_primary" android:gravity="center" android:background="@color/white"></TextView> <View android:layout_width="match_parent" android:layout_height="4dp" android:background="@color/bg_search"/> <TextView android:id="@+id/cancel" android:layout_width="match_parent" android:layout_height="60dp" android:text="@string/cancel" android:textSize="16sp" android:textColor="@color/text_primary" android:gravity="center" android:background="@color/white"></TextView> </LinearLayout>
圆角:bottom_picture_bg
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <corners android:topLeftRadius="20dp" android:topRightRadius="20dp"/> <solid android:color="@color/white"/> </shape>
弹出Fragment
/** * 打开图片选择 */ private fun openPictureSelect(){ val bottomPictureFragment = BottomPictureFragment() bottomPictureFragment.show(childFragmentManager,"Picture") bottomPictureFragment.setOnDialogListener(object : BottomPictureFragment.OnDialogListener { override fun onDialogClick(select: String?) { Log.i("打印图片选择返回的数据:","$select") when(select){ TAG_LABEL_CAMERA ->{//相机 takePhoto() } TAG_LABEL_PHOTO ->{//相册 pickImage() } } } }) }
拍照
// takePhoto 拍照 private fun takePhoto() { PictureSelector.create(this) .openCamera(PictureMimeType.ofImage()) .imageEngine(GlideEngine.createGlideEngine()) .forResult(object : OnResultCallbackListener<LocalMedia?> { override fun onResult(result: List<LocalMedia?>) { // 结果回调 if (result?.isNotEmpty()) { loadingDialog = ProgressDialog.show( requireContext(), "", getString(R.string.uploading), true ) viewModel.updateAvatar(File(result.first()?.realPath)) } } override fun onCancel() { // 取消 } }) }
相册
// pickImage 选择图片 private fun pickImage() { PictureSelector.create(this) .openGallery(PictureMimeType.ofImage()) .maxSelectNum(1) .imageEngine(GlideEngine.createGlideEngine()) .forResult(object: OnResultCallbackListener<LocalMedia> { override fun onResult(result: MutableList<LocalMedia>?) { if (result?.isNotEmpty() == true) { loadingDialog = ProgressDialog.show( requireContext(), "", getString(R.string.uploading), true ) viewModel.updateAvatar(File(result.first().realPath)) } } override fun onCancel() { } }) }
完成
参考:https://blog.csdn.net/yechaoa/article/details/79291552