自定义流式布局

本文介绍了流式布局的广泛应用,分析了其测量模式,包括MeasureSpec.EXACTLY、MeasureSpec.AT_MOST和MeasureSpec.UNSPECIFIED。接着,详细阐述了如何在自定义布局中实现流式布局的onMeasure()和onLayout()方法,以达到动态换行和子视图随机颜色的效果。文章还提供了具体的实现步骤,包括创建自定义JMFlowLayout类、动态加载数据以及处理点击事件,使子视图在点击时背景变为白色。
摘要由CSDN通过智能技术生成

流式布局的使用已盛行it界许久了,可谓随处可见,随时可见,再不了解一下它,那就太out了。今天就让我们来看看 类似热门标签的流式布局吧~

1.流式布局的应用场景
慕课网有用到:
这里写图片描述

淘宝有用到:
这里写图片描述

其他学习网站等都有用到:
这里写图片描述

以上都是从实际的应用中截取到的图片,事实证明流式布局真的很潮~

2.流式布局分析
这里写图片描述
说到流式布局我们要先了解一下测量模式
①测量模式
测量模式分三种即:

MeasureSpec.EXACTLY:精确模式, eg:100dp,match_parent.
(注:为什么match_parent属于精确模式呢?这是因为我们手机屏幕的大小是确定的,即使你已经先制定了一个控件比如TextView的高为50dp,下面又设置了一个View的高为match_parent,那实际上
该View的高=屏幕的高(确定的)-TextView的高(也是确定的)
确定的值 减去 确定的值 结果还是确定的
)
MeasureSpec.AT_MOST: 至多模式, view最多可以获得的宽高值,它需要计算所有包含的子view的宽高,最后计算出来的宽高总和值,eg:wrap_content.

UNSPECIFIED:未指定模式,想设置多宽多高,就给你多宽多高,一般的控件不会指定这种模式,但也存在,eg:scrollview的宽高测量,就是使用的此种模式

②那么在我们的流式布局内,应该怎么设置布局的宽高呢? onMeasure():

1:如果布局指定的宽是match_parent或者精确的宽度值,那么直接就可以从父控件传入的测量规格中直接获取布局宽度,高度同理.

2:如果布局指定的宽高不是EXACTLY,而是AT_MOST,那么这时候,就需要计算每一个子view的宽高,来决定布局的宽高了。

宽度:摆放的所有子view占据宽度最多的一行,作为布局宽度。
高度:摆放的所有子view总共占据几行的高度总和。

③实现子View的布局方式: onLayout()

使用onLayout():设置ViewGroup内包含的所有子view的位置;

获取到每一行的每一个子view,计算出它的left,top,right,bottom,调用layout方法设置其在流式布局当中的位置。

宽度=子view最多的那行的宽度=那一行每一个子view的宽度+leftMargin+rightMargin;

高度=所有行的高度 = 每一行的高度+topMargin+bottomMargin;

使用 setMeasureDimension()—>设置流式布局的宽高。

那么下面我就按照分析的步骤来实现如下效果的流式布局

实现效果:
这里写图片描述

该流式布局特点:在布局内,随意摆放任意个view,每行所摆放的view个数,根据实施计算出来的宽度,一旦当前要摆放的view宽度和之前摆放的所有view宽度加在一起,超过了布局的宽度,那么就把该view换行摆放。且每个子view的背景颜色随机,点击时会变为白色。

3.流式布局的具体实现
①.自定义JMFlowLayout类继承ViewGroup类

public class JMFlowLayout extends ViewGroup {
   
    //构造器
    public JMFlowLayout(Context context) {
        this(context, null);
    }

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

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

    //需重写的onLayout()方法
    @Override
    protected void onLayout(boolean b, int i, int i1, int i2, int i3) {

    }

}

②在布局中使用我们自己定义的FlowLayout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.chenjunmei.jmflowlayout.MainActivity">

    <!--先暂时设置Flowlayout的背景色,以方便结果的观察-->
    <com.example.chenjunmei.jmflowlayout.JMFlowLayout
        android:background="@android:color/holo_blue_light"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值