如图:

拍照、相册使用开源库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
