欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

一个很low的viewgroup改写

程序员文章站 2022-03-07 18:22:31
改写一个随着子控件的摆放,当到达viewgroup的宽度时自动换行的view思路:在onMeasure里计算控件的宽高并计算好摆放的位置,然后根据父控件的宽度来考虑是否要换行直接上代码:package com.example.opencvapplicationimport android.content.Contextimport android.graphics.Rectimport android.graphics.RectFimport android.util.Attribu...

改写一个随着子控件的摆放,当到达viewgroup的宽度时自动换行的view

思路:在onMeasure里计算控件的宽高并计算好摆放的位置,然后根据父控件的宽度来考虑是否要换行

直接上代码:

package com.example.opencvapplication

import android.content.Context
import android.graphics.Rect
import android.graphics.RectF
import android.util.AttributeSet
import android.util.Log
import android.view.View
import android.view.ViewGroup
import androidx.core.view.children
import androidx.core.view.marginBottom
import androidx.core.view.marginTop
import kotlin.math.max

class SteamViewGrop(context: Context?, attrs: AttributeSet?) : ViewGroup(context, attrs) {

    val rectList = ArrayList<Rect>()

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
//        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        var startLeft = 0
        var startTop = 0
        var maxHeight = 0
        var usedHeight = 0
        val viewWidth = MeasureSpec.getSize(widthMeasureSpec)
        val viewHeight = MeasureSpec.getSize(widthMeasureSpec)
        Log.e("xxj", "viewWidth=$viewWidth")
        for ((index, child) in children.withIndex()) {
            //计算子控件的宽高
            measureChildWithMargins(child,widthMeasureSpec,0,heightMeasureSpec,viewHeight-usedHeight)
            val margin = child.layoutParams as MarginLayoutParams
            maxHeight =max(maxHeight, child.measuredHeight + margin.bottomMargin + margin.topMargin)//取当前行最大的高度

            if (startLeft + child.measuredWidth > viewWidth) {//当宽度大于父控件的宽度时换行
                startTop += maxHeight
                usedHeight += maxHeight
                maxHeight = 0
                startLeft = 0
                //重新计算宽高
                measureChildWithMargins(child,widthMeasureSpec,0,heightMeasureSpec,viewHeight-usedHeight)

            }
            Log.e("xxj", "startLeft=$startLeft  startTop=$startTop  child.width=${child.measuredWidth}")
            if (index >= rectList.size) {
                rectList.add(Rect())
            }
            rectList[index].set(//设置子控件的位置
                startLeft + margin.leftMargin,
                startTop + margin.topMargin,
                startLeft + margin.leftMargin + child.measuredWidth,
                startTop + margin.topMargin + child.measuredHeight
            )

            startLeft += child.measuredWidth + margin.rightMargin
        }
        usedHeight += maxHeight
        setMeasuredDimension(viewWidth, usedHeight)
    }

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        for ((index, child) in children.withIndex()) {
            child.layout(
                rectList[index].left,
                rectList[index].top,
                rectList[index].right,
                rectList[index].bottom
            )
        }
    }

    override fun generateLayoutParams(attrs: AttributeSet?): LayoutParams {
        return MarginLayoutParams(context, attrs)
    }

}

使用:

<?xml version="1.0" encoding="utf-8"?>
<com.example.opencvapplication.SteamViewGrop xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".activity.MainActivity">

    <TextView
        style="@style/textStyle"
        android:text="伊利丹" />

    <TextView
        style="@style/textStyle"

        android:text="维伦" />

    <TextView
        style="@style/textStyle"
        android:text="基尔加丹" />

    <TextView
        style="@style/textStyle"

        android:text="格鲁姆.地狱咆哮" />

    <TextView
        style="@style/textStyle"

        android:text="玛法里奥.怒风" />

    <TextView
        style="@style/textStyle"

        android:text="帕克" />

    <TextView
        style="@style/textStyle"

        android:text="戴泽" />

    <TextView
        style="@style/textStyle"

        android:text="卡尔" />

    <TextView
        style="@style/textStyle"

        android:text="凯尔萨斯" />

    <TextView
        style="@style/textStyle"

        android:text="瓦里安.乌瑞恩" />


</com.example.opencvapplication.SteamViewGrop>

 

本文地址:https://blog.csdn.net/xxj_1234562/article/details/107875378