zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    jquery $.getJSON()跨域请求
    JQuery 字符串转时间格式
    php Function ereg() is deprecated的解决方法
    ucenter 验证码看不到的解决办法
    C#通过UserAgent判断智能设备(Android,IOS,PC,Mac)
    gpio_irq出现错误genirq: Setting trigger mode 6 for irq 168 failed (gpio_set_irq_type+0x0/0x230)
    驱动模块的加载(linux4.1.15)!
    电压环控制逻辑!
    用电阻检测大电流时2线电阻的PCB画法。
    比较两点压差(比如两点温度相差太大),超过范围,做出动作!
  • 原文地址:https://www.cnblogs.com/changyiqiang/p/15683877.html
Copyright © 2011-2022 走看看