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

 

posted on 2021-12-13 16:09  巫山老妖  阅读(2795)  评论(0编辑  收藏  举报