Android FlowLayout流式布局

本文介绍如何在Android中实现一个自定义的FlowLayout,详细解析自定义ViewGroup的过程,包括重写onMeasure、onLayout和onDraw方法,以及解决子View重叠和自动换行的问题,最后通过提供对齐方式实现子View居中显示,并通过类似Adapter的方式简化布局设置。
摘要由CSDN通过智能技术生成

最近使用APP的时候经常看到有

这种流式布局 ,今天我就跟大家一起来动手撸一个这种自定义控件.

首先说一下自定义控件的流程:

自定义控件一般要么继承View要么继承ViewGroup

View的自定义流程:

继承一个View-->重写onMeasure方法-->重写onDraw方法-->定义自定义属性-->处理手势操作

ViewGroup的自定义流程:

继承一个ViewGroup-->重写onMeasure方法-->重写onLayout-->重写onDraw方法->定义自定义属性-->处理手势操作

我们可以看到自定义View和自定义ViewGroup略微有些不同,自定义ViewGroup多了个onlayout方法,那么这些方法都有什么作用呢?这里由于篇幅的问题不做过多的描述,简单的说

onMeasure:用来计算,计算自身显示在页面上的大小

onLayout:用来计算子View摆放的位置,因为View已经是最小单元了,所以没有字View,所以没有onLayout方法

onDraw:用来绘制你想展示的东西

定义自定义属性就是暴露一些属性给外部调用

好了,了解了自定义View的基本自定义流程,我们可以知道我们应该需要自定义一个ViewGroup就可以满足该需求.

首先自定义一个View命名为FlowLayout继承ViewGroup

public class FlowLayout extends ViewGroup {
    public FlowLayout(Context context) {
        this(context,null);
    }

    public FlowLayout(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            getChildAt(i).layout(l,t,r,b);
        }
    }
}

可以看到onLayout是必须重写的,不然系统不知道你这个ViewGroup的子View摆放的位置.

然后XML中引用

<test.hxy.com.testflowlayout.FlowLayout 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:id="@+id/mFlowLayout"
    android:layout_margin="10dp"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Activity中设置数据

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        FlowLayout mFlowLayout = (FlowLayout) findViewById(R.id.mFlowLayout);
        List<String> list = new ArrayList<>();
        list.add("java");
        list.add("javaEE");
        list.add("javaME");
        list.add("c");
        list.add("php");
        list.add("ios");
        list.add("c++");
        list.add("c#");
        list.add("Android");
        for (int i = 0; i < list.size(); i++) {
            View inflate = LayoutInflater.from(this).inflate(R.layout.item_personal_flow_labels, null);
            TextView label = (TextView) inflate.findViewById(R.id.tv_label_name);
            label.setText(list.get(i));
            mFlowLayout.addView(inflate);
        }
    }

运行一下:

咦!!!这时候发现我们添加的

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值