如圖:

拍照、相冊使用開源庫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
