自定义GridView--添删图片

简单介绍一下:点击“+”号图标可添加图片,图片添加后点击可查看,长按弹出popView,可选择删除或查看。

这是在逍遥模拟器上运行后的效果,因为我设置的是一行4个图片,所以间隔有点大。

这里有几个要考虑的点,因为是涉及到图片,所以必要的权限一定是要给的。下面是我用Kotlin写的一个Activity,注意重写onRequestPermissionsResult方法,不然权限被关了的话不会出现要求获取访问图库的权限提示。

abstract class AddPictureActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }

    private var onPermissionListener: OnBooleanListener? = null
    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == 1) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                //权限通过
                if (onPermissionListener != null) {
                    onPermissionListener!!.onClick(true)
                }
            }
        } else {
            //权限拒绝
            if (onPermissionListener != null) {
                onPermissionListener!!.onClick(false)
            }
        }
        return
    }

    @TargetApi(Build.VERSION_CODES.M)
    fun permissionRequests(activity: Activity, permission: String, onBooleanListener: OnBooleanListener) {
        onPermissionListener = onBooleanListener
        if (ContextCompat.checkSelfPermission(this@AddPictureActivity, permission) != PackageManager.PERMISSION_GRANTED) {
            //                if (ActivityCompat.shouldShowRequestPermissionRationale(activity, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            //                    //权限通过
            //                    onPermissionListener.onClick(true);
            //                } else {
            //没有权限,申请一下
            ActivityCompat.requestPermissions(activity, arrayOf(permission), 1)
            //                }
        } else {
            //权限已有
            if (onPermissionListener != null) {
                onPermissionListener!!.onClick(true)
            }
        }
    }

    /**
     * 图片选择,图库或者相机
     */
    private var file: File? = null
    fun selectPic(tag: Boolean) {
        if (tag) {
            permissionRequests(this@AddPictureActivity, android.Manifest.permission.WRITE_EXTERNAL_STORAGE, object : OnBooleanListener {
                override fun onClick(bln: Boolean) {
                    if (bln) {
                        //图库选图的intent
                        val intent1 = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
                        //intent1.setDataAndType(, "image/*");
                        //相机拍照
                        val intent2 = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
                        file = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), System.currentTimeMillis().toString() + ".jpg")
                        val imageUri = Uri.fromFile(file)
                        intent2.putExtra(MediaStore.EXTRA_OUTPUT, imageUri)
                        val intent = Intent.createChooser(intent1, "选取上传图片方式")
                        intent.putExtra(Intent.EXTRA_INITIAL_INTENTS, arrayOf(intent2))
                        startActivityForResult(intent, ChgActivityCode.PicStoreCode)
                        //通过onResume()刷新数据
                    }
                }
            })
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (requestCode == ChgActivityCode.PicStoreCode) {
            //打开图片
            if (resultCode == Activity.RESULT_OK) {
                var picPath: String? = null
                var uri: Uri? = null
                if (data != null) {
                    uri = data.data
                    if (!TextUtils.isEmpty(uri!!.authority)) {
                        val cr = this.contentResolver
                        //查询选择图片
                        val cursor = cr.query(
                                uri,
                                arrayOf(MediaStore.Images.Media.DATA), null, null, null) ?: return
                        //返回 没找到选择图片
                        //光标移动至开头 获取图片路径
                        cursor.moveToFirst()
                        picPath = cursor.getString(cursor
                                .getColumnIndex(MediaStore.Images.Media.DATA))
                    }
                } else {
                    //拍照获取uri
                    uri = Uri.fromFile(file)
                    picPath = file.toString()
                }

                if (!TextUtils.isEmpty(picPath)) { //选择了图片并添加
                    iconAdd(picPath)
                }
            }
        }
        else if (resultCode == ChgActivityCode.ShowIconDelCode){
            iconDelete()
            afterIconDelete()
        }
        if (resultCode == ChgActivityCode.ALL_ACTIVITY_CLOSE){
            this.setResult(ChgActivityCode.ALL_ACTIVITY_CLOSE)
            finish()
        }
    }

    protected fun notifyGridViewDeleteData(position: Int, imgs: MutableList<String>, adapter: AddPictureAdapter){
        if (imgs.size == 6){
            imgs.add("")
        }
        imgs.removeAt(position)
        adapter.notifyDataSetChanged()
    }

    protected fun notifyGridViewAddData(path: String, position: Int, adapter: AddPictureAdapter){
        if (position == 5){
            adapter.getData()!![5] = path
        }
        else{
            adapter.getData()!!.add(position, path)
        }
        adapter.notifyDataSetChanged()
    }

    abstract fun iconAdd(path : String?);
    abstract fun iconDelete();
    abstract fun afterIconDelete();
}

个人觉得在图片右上角加个“X”不好看,而且屏幕小了的话不好点,所以弄一个popView辅助,这里是防QQ来的做的样子。看下面的代码就知道,实际上就是两张图片做背景的按钮。没什么稀奇的。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:id="@+id/my_pop_btn_check"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:textSize="13sp"
        android:textColor="@color/colorWhite"
        android:background="@mipmap/ic_popbgl"
        android:paddingBottom="10dp"
        android:text="查看" />

    <Button
        android:id="@+id/my_pop_btn_delete"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:paddingBottom="10dp"
        android:layout_toRightOf="@+id/my_pop_btn_check"
        android:textSize="13sp"
        android:textColor="@color/colorWhite"
        android:background="@mipmap/ic_popbgr"
        android:text="删除" />

</RelativeLayout>

我写的这个popView最多可以适用4个按钮的layout资源,所以呢代码里面你会看到有两个在这里一点卵关系都没有的代码段,忽略就行了。就是下面这货也参与了。

class MyPopOption @JvmOverloads constructor(private val context: Context, private val parent: ViewGroup?, private val resouce: Int = R.layout.mypop_layout) {

    private var popupWidth: Int = 0
    private var popupHeight: Int = 0
    private var popupWindow: PopupWindow? = null
    private var mEvent: PopClickEvent? = null
    private var preBtn: Button? = null
    private var nextBtn: Button? = null

    private var mName: TextView? = null
    private var mContent: TextView? = null
    private var panoramaBtn: Button? = null
    private var navigateBtn: Button? = null
    private var buildingBean: BuildingBean? = null

    var view: View? = null
        private set
    private var locationX: Int = 0
    private var locationY: Int = 0
    private val oneDp: Int

    val isShown: Boolean
        get() = if (popupWindow == null) {
            false
        } else popupWindow!!.isShowing

    init {
        oneDp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1.0f, context.resources.displayMetrics).toInt()

        //        WindowManager windowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);

        init()
    }

    private fun init() {
        val popupView = LayoutInflater.from(context).inflate(resouce, parent, false)
        preBtn = popupView.findViewById<Button>(R.id.my_pop_btn_check)
        nextBtn = popupView.findViewById<Button>(R.id.my_pop_btn_delete)

        mName = popupView.findViewById<TextView>(R.id.building_pop_name)
        mContent = popupView.findViewById<TextView>(R.id.building_pop_introduce)

        if (mName != null) {
            popupWindow = PopupWindow(popupView, ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT, true)
            //            popupWindow.setBackgroundDrawable(new BitmapDrawable());

            panoramaBtn = popupView.findViewById<Button>(R.id.my_pop_btn_panorama)
            navigateBtn = popupView.findViewById<Button>(R.id.my_pop_btn_navigate)

            popupWindow!!.isTouchable = true
            popupWindow!!.isFocusable = false
            //            popupWindow.setOutsideTouchable(true);
            popupWindow!!.animationStyle = R.style.my_pop_window
            //            popupWindow.setTouchInterceptor(new View.OnTouchListener(){
            //
            //                @Override
            //                public boolean onTouch(View view, MotionEvent motionEvent) {
            //                    Log.i("hhh", "good " + motionEvent.getAction());
            //                    return false;
            //                }
            //            });
            var distance = 0f;
            var currentY = 0f;
            var startY = 0f;

            popupView.setOnTouchListener(object : View.OnTouchListener{
                override fun onTouch(p0: View?, motionEvent: MotionEvent?): Boolean {
                    when(motionEvent!!.action){
                        MotionEvent.ACTION_DOWN -> {
                            startY = motionEvent.y
                        }
                        MotionEvent.ACTION_MOVE -> {
                            currentY = motionEvent.y
                            distance = currentY - startY
                            if (distance > 0){
                                popupView.translationY = distance
                            }
                        }
                        MotionEvent.ACTION_UP -> {
                            currentY = motionEvent.y
                            distance = currentY - startY
                            if (distance > 30 * oneDp){
                                popupView.translationY = 0f
                                popupWindow!!.dismiss()
                            }
                            else {
                                addAnimationValue(popupView, distance)
                                if (valueAnimator != null){
                                    valueAnimator!!.start()
                                }
                            }
                            distance = 0f
                            startY = 0f
                            currentY = 0f
                        }
                        else -> {
                            return false
                        }
                    }
                    return true
                }
            })

        } else {
            popupWindow = PopupWindow(popupView, ViewGroup.LayoutParams.WRAP_CONTENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT, true)
            popupWindow!!.setBackgroundDrawable(BitmapDrawable())
        }

        popupView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
        popupWidth = popupView.measuredWidth
        popupHeight = popupView.measuredHeight
    }

    fun setBtnEnable(enable: Boolean) {
        if (preBtn != null) {
            preBtn!!.isEnabled = enable
        }
        if (nextBtn != null) {
            nextBtn!!.isEnabled = enable
        }
    }

    fun show(view: View) {
        this.view = view
        initEvent()
        val location = IntArray(2)
        view.getLocationOnScreen(location)
        popupWindow!!.showAtLocation(view, Gravity.NO_GRAVITY, location[0] + view.width / 2 - popupWidth / 2,
                location[1] - popupHeight)
    }

    fun show(marker: Marker) {
        initEvent()
        //        LatLng latLng = marker.getPosition();
        //        popupWindow.showAtLocation(parent, Gravity.NO_GRAVITY, locationX - 60 * oneDp, locationY - 60 * oneDp);
        if (parent != null) {
            popupWindow!!.showAtLocation(parent, Gravity.BOTTOM, 0, 0)
        }
    }

    fun dismiss() {
        popupWindow!!.dismiss()
    }

    private fun initEvent() {
        if (mEvent != null) {
            preBtn!!.setOnClickListener { mEvent!!.onPreBtnClick() }
            nextBtn!!.setOnClickListener { mEvent!!.onNextBtnClick() }
            //全景按钮
            if (panoramaBtn != null){
                panoramaBtn!!.setOnClickListener { mEvent!!.onPanoramaBtnClick() }
            }

            //导航按钮
            if (navigateBtn != null){
                navigateBtn!!.setOnClickListener { mEvent!!.onNavigateBtnClick() }
            }
        }
    }

    fun getmEvent(): PopClickEvent? {
        return mEvent
    }

    fun setmEvent(mEvent: PopClickEvent) {
        this.mEvent = mEvent
    }

    interface PopClickEvent {
        fun onPreBtnClick()
        fun onNextBtnClick()
        fun onPanoramaBtnClick()
        fun onNavigateBtnClick()
    }

    fun setPreBtnText(text: String) {
        preBtn!!.text = text
    }

    fun setNextBtn(text: String) {
        nextBtn!!.text = text
    }

    fun setLocationX(x: Int) {
        locationX = x
    }

    fun setLocationY(y: Int) {
        locationY = y
    }

    fun addBuildingBean(bean: BuildingBean) {
        buildingBean = bean
        if (buildingBean != null && mName != null) {
            mName!!.text = buildingBean!!.BuildingName
            mContent!!.text = buildingBean!!.OrganizationName
            if (buildingBean!!.BuildingState == "1") {
                setPreBtnText("恢复")
            }
            else {
                setPreBtnText("停用")
            }
        }
    }
    private var valueAnimator:ValueAnimator? = null
    private fun addAnimationValue(popView: View, popHeight: Float){
        valueAnimator = ValueAnimator.ofFloat(popHeight, 0f)
        valueAnimator!!.setDuration(500)
        valueAnimator!!.addUpdateListener(object : ValueAnimator.AnimatorUpdateListener{
            override fun onAnimationUpdate(p0: ValueAnimator?) {
                val value = p0!!.animatedValue as Float
                popView.translationY = value
                popView.requestLayout()
            }
        })
    }
}

GridView肯定是要配合Adapter用的,另外图片的显示也需要用图片缓存处理ImageCache来,如果你比较懒,可以看我另外一篇博客。至于GridView,还是需要改改的,至少onMeasure方法可以改一下,因为我的是嵌套在listView里面,所以不想变成滚动的GridView的话建议还是重写这个View吧。

class SubGridView : GridView {

    @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : super(context, attrs, 0) {}

    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {}

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {

        val expandSpec = View.MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE shr 2, View.MeasureSpec.AT_MOST)
        super.onMeasure(widthMeasureSpec, expandSpec)
    }
}

使用时就很简单了。收功~

<com.IntelligenceSecuritySystem.view.SubGridView
        android:id="@+id/add_inspect_pics"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="@+id/add_inspect_result"
        app:layout_constraintRight_toRightOf="@+id/add_inspect_result"
        app:layout_constraintTop_toBottomOf="@+id/add_inspect_result"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_marginTop="@dimen/inspect_margin_top"
        android:layout_marginBottom="@dimen/inspect_margin"
        android:verticalSpacing="10dp"
        android:numColumns="4">
    </com.IntelligenceSecuritySystem.view.SubGridView>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值