溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Android怎么自定義ViewGroup多行多列效果

發(fā)布時(shí)間:2021-09-02 16:46:46 來(lái)源:億速云 閱讀:221 作者:chen 欄目:開發(fā)技術(shù)

這篇文章主要介紹“Android怎么自定義ViewGroup多行多列效果”,在日常操作中,相信很多人在Android怎么自定義ViewGroup多行多列效果問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”Android怎么自定義ViewGroup多行多列效果”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

先看下效果圖

每行兩個(gè)子孩子

Android怎么自定義ViewGroup多行多列效果

每行一個(gè)子孩子

Android怎么自定義ViewGroup多行多列效果

實(shí)現(xiàn)思路

自定義viewGroup,實(shí)現(xiàn)測(cè)量和布局,使控件適應(yīng)業(yè)務(wù)場(chǎng)景。

測(cè)量

根據(jù)父控件的寬度,平均分給每個(gè)子孩子固定的寬度。高度就是行數(shù)乘以一個(gè)子孩子的高度,再加上空隙的高度。

根據(jù)子孩子個(gè)數(shù)計(jì)算行數(shù)  

val rows = if (childCount % perLineChild == 0) {
            childCount / perLineChild
        } else {
            childCount / perLineChild + 1
        }

代碼示例

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        val width = MeasureSpec.getSize(widthMeasureSpec)
        for (i in 0 until childCount) {
            val child: View = getChildAt(i)
            if (child.visibility != GONE) {
                val lp = child.layoutParams
                val childWidthMeasureSpec = getChildMeasureSpec(
                    widthMeasureSpec,
                    0, (width - (perLineChild - 1) * space) / perLineChild
                )
                val childHeightMeasureSpec = getChildMeasureSpec(
                    heightMeasureSpec,
                    0, lp.height
                )
                child.measure(childWidthMeasureSpec, childHeightMeasureSpec)
            }
        }
        val rows = if (childCount % perLineChild == 0) {
            childCount / perLineChild
        } else {
            childCount / perLineChild + 1
        }
        if (childCount > 0) {
            setMeasuredDimension(
                width,
                getChildAt(0).measuredHeight * rows + (rows - 1) * space
            )
        }
    }

布局

需要注意擺放的順序和位置,每行擺放固定的個(gè)數(shù),達(dá)到個(gè)數(shù)之后換行繼續(xù)擺放

代碼示例 

override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        var left = l
        var top = t
        children.forEachIndexed { index, view ->
            if (index % perLineChild == 0) {
                left = 0
                if (index != 0) {
                    top += view.measuredHeight
                    top+=space
                }
                view.layout(left, top, view.measuredWidth + left, top + view.measuredHeight)
            } else {
                view.layout(left, top, view.measuredWidth + left, top + view.measuredHeight)
            }
            left += view.measuredWidth
            left += space
        }
    }

完整代碼

class MultiLineViewG @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : ViewGroup(context, attrs, defStyleAttr) {

    var perLineChild = 2

    /**
     * 子孩子之間的空隙
     */
    var space = 10

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        val width = MeasureSpec.getSize(widthMeasureSpec)
        for (i in 0 until childCount) {
            val child: View = getChildAt(i)
            if (child.visibility != GONE) {
                val lp = child.layoutParams
                val childWidthMeasureSpec = getChildMeasureSpec(
                    widthMeasureSpec,
                    0, (width - (perLineChild - 1) * space) / perLineChild
                )
                val childHeightMeasureSpec = getChildMeasureSpec(
                    heightMeasureSpec,
                    0, lp.height
                )
                child.measure(childWidthMeasureSpec, childHeightMeasureSpec)
            }
        }
        val rows = if (childCount % perLineChild == 0) {
            childCount / perLineChild
        } else {
            childCount / perLineChild + 1
        }
        if (childCount > 0) {
            setMeasuredDimension(
                width,
                getChildAt(0).measuredHeight * rows + (rows - 1) * space
            )
        }
    }

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        var left = l
        var top = t
        children.forEachIndexed { index, view ->
            if (index % perLineChild == 0) {
                left = 0
                if (index != 0) {
                    top += view.measuredHeight
                    top+=space
                }
                view.layout(left, top, view.measuredWidth + left, top + view.measuredHeight)
            } else {
                view.layout(left, top, view.measuredWidth + left, top + view.measuredHeight)
            }
            left += view.measuredWidth
            left += space
        }
    }
}

到此,關(guān)于“Android怎么自定義ViewGroup多行多列效果”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI