android 高度等分,自定义TableLayout 整齐堆叠宽度等分布局

博客介绍了如何在Android中自定义TableLayout组件,以实现按总宽度等分,从左到右放置子布局的功能。作者提供了源码,并在res/values/下创建了attr.xml文件来设置间距、子布局高度和每行数量。该组件适用于需要灵活布局的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求

现有需求,按总宽度N等分,从左往右放置子布局,至最右处换下行继续,整体布局高度按照子布局高度逐级扩张。

Android 自带的 GridLayout 和 TableLayout都不够好用,就自己写了个,原理和StackLabel类似。

代码import android.content.Context;

import android.content.res.Resources;

import android.content.res.TypedArray;

import android.graphics.Canvas;

import android.util.AttributeSet;

import android.view.View;

import android.view.ViewGroup;

import java.util.ArrayList;

import java.util.List;

/**

* Author:

* Github: https://github.com/kongzue/

* Homepage: http://kongzue.com/

* Mail: myzcxhh@live.cn

* CreateTime: 2019/4/24 15:51

*/

public class TableLayout extends ViewGroup {

private int maxColumn = 2;

private int itemMargin = 0;

private int itemHeight = dp2px(150);

private Context context;

public TableLayout(Context context) {

super(context);

this.context = context;

loadAttrs(context, null);

}

public TableLayout(Context context, AttributeSet attrs) {

super(context, attrs);

this.context = context;

loadAttrs(context, attrs);

}

public TableLayout(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

this.context = context;

loadAttrs(context, attrs);

}

private void loadAttrs(Context context, AttributeSet attrs) {

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TableLayout);

itemMargin = typedArray.getDimensionPixelOffset(R.styleable.TableLayout_marginDp, 0);

itemHeight = typedArray.getDimensionPixelOffset(R.styleable.TableLayout_itemHeight, dp2px(150));

maxColumn = typedArray.getInteger(R.styleable.TableLayout_column, 2);

typedArray.recycle();

}

protected void onLayout(boolean changed, int l, int t, int r, int b) {

}

private List items;

private int newHeight = 0;

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

refreshViews();

setMeasuredDimension(getMeasuredWidth(), newHeight);//设置宽高

}

private void refreshViews() {

int maxWidth = getMeasuredWidth() + itemMargin;

int itemWidth = maxWidth / maxColumn - itemMargin;

items = new ArrayList<>();

for (int i = 0; i < getChildCount(); i++) {

View child = getChildAt(i);

if (child.getVisibility() == VISIBLE) {

items.add(getChildAt(i));

}

}

newHeight = 0;

if (items != null && !items.isEmpty()) {

int l = 0, t = 0, r = 0, b = 0;

for (int i = 0; i < items.size(); i++) {

View item = items.get(i);

int mWidth = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); //AT_MOST:先按照最大宽度计算,如果小于则按实际值,如果大于,按最大宽度

int mHeight = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); //UNSPECIFIED:不确定,根据实际情况计算

item.measure(mWidth, mHeight);

int childHeight = itemHeight;

if (i != 0 && i % maxColumn == 0) {

l = 0;

t = t + childHeight + itemMargin;

}

r = l + itemWidth;

b = t + childHeight;

item.layout(l, t, r, b);

l = l + itemWidth + itemMargin;

newHeight = t + childHeight;

}

}

}

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

}

private int dp2px(float dpValue) {

return (int) (0.5f + dpValue * Resources.getSystem().getDisplayMetrics().density);

}

}

然后在res/values/新建attr.xml,内容如下

简单解释:marginDp 为间距,itemHeight为限制子布局高度值,column为每行几个(N等分)

使用

android:id="@+id/box_body"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:layout_marginHorizontal="10dp"

app:itemHeight="100dp"

app:marginDp="10dp">

完事儿。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值