1. 程式人生 > 實用技巧 >Android自定義多圖片介面卡(根據圖片的個數展示不同的佈局)

Android自定義多圖片介面卡(根據圖片的個數展示不同的佈局)

一、概述&效果圖

  專案上有一個需求根據不同的圖片個數展示不同的的佈局樣式,且圖片個數不能超過四個。要說起來手動寫也挺方便的,就是程式碼看起來比較臃腫,考慮了兩秒決定用自定義佈局試實現

  思路:

  1.讓佈局繼承ViewGroup

  2.利用ViewGroup測量自己以及測量子View的寬高

  3.根據寬高在layout方法中進行手動佈局

  廢話不多說,大家可以看下效果圖

  

二、原始碼(主要部分)

  測量自己和測量子View

 override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        
//測量子View measureChildren(widthMeasureSpec, heightMeasureSpec) //獲取ziView的數量 val childCount = childCount if (childCount > 4) { //如果元素超過四個就丟擲異常 throw IndexOutOfBoundsException("元素數量不能超過四個") } val widthMode = MeasureSpec.getMode(widthMeasureSpec) val width
= MeasureSpec.getSize(widthMeasureSpec) val heightMode = MeasureSpec.getMode(heightMeasureSpec) val height = MeasureSpec.getSize(heightMeasureSpec) //佈局必須是固定寬高的,如果不是就丟擲異常 if (widthMode != MeasureSpec.EXACTLY || heightMode != MeasureSpec.EXACTLY) { throw RuntimeException("
主佈局必須指定寬高") } //指定佈局寬高範圍 setMeasuredDimension(width, height) //以下預設佈局都是有固定寬高的 for (index in 0 until childCount) { when (childCount) { //當只有一個子元素的時候,佈局的寬高就是子元素的寬高 1 -> { val childView = getChildAt(index) val params = ViewGroup.LayoutParams(width, height) childView.layoutParams = params } 2 -> { for (index in 0 until 2) { val childView = getChildAt(index) val params = ViewGroup.LayoutParams((width - margin) / 2, height) childView.layoutParams = params } } 3 -> { for (index in 0 until 3) { val childView = getChildAt(index) var childWidth = 0 var childHeight = 0 if (index == 0) { childWidth = (width - margin) / 2 childHeight = height } else { childWidth = (width - margin) / 2 childHeight = (height - margin) / 2 } val params = ViewGroup.LayoutParams(childWidth, childHeight) childView.layoutParams = params } } 4 -> { for (index in 0 until 4) { val childView = getChildAt(index) val params = ViewGroup.LayoutParams((width - margin) / 2, (width - margin) / 2) childView.layoutParams = params } } } } }

  佈局子View

  /**
     * @description 開始佈局
     * @date: 2020/11/6 16:20
     * @author: wei.yang
     * @param
     * @return
     */
    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        Log.e("margin:", margin.toString())
        val childCount = childCount
        when (childCount) {
            1 -> {
                val childView = getChildAt(0)
                childView.layout(0, 0, childView.measuredWidth, childView.measuredHeight)
            }
            2 -> {
                val childView1 = getChildAt(0)
                val childWidth = childView1.measuredWidth
                childView1.layout(0, 0, childWidth, childView1.measuredHeight)
                val childView2 = getChildAt(1)
                childView2.layout(
                    childWidth + margin,
                    0,
                    childWidth * 2 + margin,
                    childView2.measuredHeight
                )
            }
            3 -> {
                val childView1 = getChildAt(0)
                val childWidth = childView1.measuredWidth
                childView1.layout(0, 0, childWidth, childView1.measuredHeight)
                val childView2 = getChildAt(1)
                childView2.layout(
                    childWidth + margin,
                    0,
                    childWidth * 2 + margin,
                    childView2.measuredHeight
                )
                val childView3 = getChildAt(2)
                childView3.layout(
                    childWidth + margin,
                    childWidth + margin,
                    childWidth * 2 + margin,
                    childView3.measuredHeight * 2 + margin
                )
            }
            4 -> {
                Log.e("CustomerMusdfj", "佈局了四個")
                val childView = getChildAt(0)
                val childWidth = childView.measuredWidth
                val childHeight = childView.measuredHeight
                childView.layout(0, 0, childWidth, childHeight)
                getChildAt(1).layout(childWidth + margin, 0, childWidth * 2 + margin, childHeight)
                getChildAt(2).layout(0, childHeight + margin, childWidth, childHeight * 2 + margin)
                getChildAt(3).layout(
                    childWidth + margin,
                    childHeight + margin,
                    childWidth * 2 + margin,
                    childHeight * 2 + margin
                )
            }
        }

    }

  設定資料來源

 /**
     * @description 設定圖片的資料來源
     * @date: 2020/11/6 16:39
     * @author: wei.yang
     * @param margin 單位是dp
     * @return
     */
    fun setAdapter(views: ArrayList<View>, margin: Float) {
        removeAllViews()
        this.margin = dp2px(margin)
        views?.apply {
            this.forEach {
                addView(it)
            }
        }
        requestLayout()

    }

三、下載地址