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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM