kotlin flexbox的用法

xzbxzb 安卓 2025-12-15 12 0
FlexboxLayout 是 Google 推出的 Android 布局库,对标前端的 Flexbox 布局,能灵活实现流式布局、自适应排列等效果,Kotlin 中使用它的方式如下,包含基础集成、核心属性、代码示例等核心内容:

一、集成依赖

首先在 build.gradle(Module 级别)中添加依赖(确保 Gradle 版本兼容):
dependencies {
    // 最新版本可查看 Google Maven:https://maven.google.com/web/index.html?q=flexbox#com.google.android.flexbox:flexbox
    implementation "com.google.android.flexbox:flexbox:3.0.0"
}

二、核心概念与属性

FlexboxLayout 继承自 ViewGroup,核心属性分为容器属性(控制整体布局)和子项属性(控制单个子 View):
类型
属性名
作用
可选值 / 说明
容器属性
flexDirection
主轴方向
ROW(水平,默认)、COLUMN(垂直)、ROW_REVERSECOLUMN_REVERSE
容器属性
flexWrap
是否换行
NOWRAP(不换行,默认)、WRAP(换行)、WRAP_REVERSE(反向换行)
容器属性
justifyContent
主轴方向对齐方式
FLEX_START(左 / 上)、FLEX_END(右 / 下)、CENTER
SPACE_BETWEENSPACE_AROUNDSPACE_EVENLY
容器属性
alignItems
交叉轴单行对齐方式
STRETCH(拉伸,默认)、FLEX_STARTFLEX_ENDCENTERBASELINE
容器属性
alignContent
交叉轴多行对齐方式(仅
flexWrap=WRAP
时生效)
justifyContent+STRETCH(默认)
子项属性
layout_flexGrow
子项剩余空间占比(类似 LinearLayout weight)
浮点数,默认 0(不占剩余空间)
子项属性
layout_flexShrink
子项空间不足时收缩比例
浮点数,默认 1(允许收缩)
子项属性
layout_alignSelf
单个子项交叉轴对齐方式(覆盖容器
alignItems
alignItems+AUTO(默认,继承容器)
子项属性
layout_order
子项排列顺序(数值越小越靠前)
整数,默认 0
子项属性
layout_flexBasisPercent
子项主轴方向基准宽度 / 高度(百分比)
0~100 的浮点数,如 50% 表示占容器 50%

三、使用示例

示例 1:XML 中静态使用(流式标签布局)

<!-- 布局文件 res/layout/activity_flexbox.xml -->
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.flexbox.FlexboxLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/flexboxLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:flexDirection="row"          <!-- 水平排列 -->
    app:flexWrap="wrap"              <!-- 自动换行 -->
    app:justifyContent="flex_start"  <!-- 左对齐 -->
    app:alignItems="center"          <!-- 垂直居中 -->
    android:padding="16dp">

    <!-- 子项1 -->
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="36dp"
        android:background="#E0F2FE"
        android:gravity="center"
        android:paddingHorizontal="12dp"
        android:text="Kotlin"
        android:textColor="#0369A1"
        app:layout_margin="4dp"/>

    <!-- 子项2 -->
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="36dp"
        android:background="#FEF3C7"
        android:gravity="center"
        android:paddingHorizontal="12dp"
        android:text="Flexbox"
        android:textColor="#92400E"
        app:layout_margin="4dp"/>

    <!-- 更多子项... -->
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="36dp"
        android:background="#D1FAE5"
        android:gravity="center"
        android:paddingHorizontal="12dp"
        android:text="Android"
        android:textColor="#065F46"
        app:layout_margin="4dp"/>

</com.google.android.flexbox.FlexboxLayout>

示例 2:Kotlin 代码动态添加子项

适合动态生成标签、标签云等场景:
import android.os.Bundle
import android.view.Gravity
import android.view.ViewGroup
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.google.android.flexbox.FlexboxLayout
import com.google.android.flexbox.FlexboxLayout.LayoutParams

class FlexboxDynamicActivity : AppCompatActivity() {

    // 模拟动态数据
    private val tags = listOf("Java", "Kotlin", "Android", "Flexbox", "Jetpack", "Compose", "Retrofit", "OkHttp")

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 1. 创建 FlexboxLayout 容器
        val flexboxLayout = FlexboxLayout(this).apply {
            layoutParams = ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT
            )
            flexDirection = FlexboxLayout.FLEX_DIRECTION_ROW // 水平
            flexWrap = FlexboxLayout.FLEX_WRAP_WRAP         // 换行
            justifyContent = FlexboxLayout.JUSTIFY_CONTENT_FLEX_START // 左对齐
            alignItems = FlexboxLayout.ALIGN_ITEMS_CENTER   // 垂直居中
            setPadding(64, 64, 64, 64) // 对应 16dp(px 需适配,此处简化)
        }

        // 2. 动态添加子项
        tags.forEach { tag ->
            // 创建 TextView 子项
            val tagView = TextView(this).apply {
                text = tag
                textSize = 14f
                gravity = Gravity.CENTER
                setPadding(48, 0, 48, 0) // 12dp 左右内边距(简化)
                height = 144 // 36dp 高度(简化)
                setBackgroundResource(R.drawable.bg_tag) // 自定义标签背景(可选)
                setTextColor(resources.getColor(R.color.white, theme))
            }

            // 3. 设置子项的 Flexbox 属性
            val lp = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT).apply {
                margin = 16 // 4dp 外边距(简化)
                // 可选:设置子项属性
                // flexGrow = 1f // 占满剩余空间
                // alignSelf = FlexboxLayout.ALIGN_SELF_CENTER
            }
            tagView.layoutParams = lp

            // 4. 添加到容器
            flexboxLayout.addView(tagView)
        }

        // 5. 设置布局
        setContentView(flexboxLayout)
    }
}

示例 3:FlexboxLayoutManager(RecyclerView 结合 Flexbox)

实现 RecyclerView 的流式布局(如瀑布流、多行列表),这是 Flexbox 最常用的场景之一:
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.RecyclerView
import com.google.android.flexbox.FlexDirection
import com.google.android.flexbox.FlexboxLayoutManager
import com.google.android.flexbox.JustifyContent

class FlexboxRecyclerActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_flexbox_recycler)

        val recyclerView = findViewById<RecyclerView>(R.id.recyclerView)
        
        // 1. 创建 FlexboxLayoutManager
        val layoutManager = FlexboxLayoutManager(this).apply {
            flexDirection = FlexDirection.ROW // 水平排列
            justifyContent = JustifyContent.FLEX_START // 左对齐
            flexWrap = com.google.android.flexbox.FlexWrap.WRAP // 换行
        }

        // 2. 设置给 RecyclerView
        recyclerView.layoutManager = layoutManager
        
        // 3. 设置适配器(自定义 Adapter)
        recyclerView.adapter = TagAdapter(tags) // tags 为数据源
    }
}

四、关键注意事项

  1. 单位适配:示例中直接用 px 是简化写法,实际开发需用 dp2px 工具类转换:

fun dp2px(dp: Int): Int {
    val density = resources.displayMetrics.density
    return (dp * density + 0.5f).toInt()
}
  1. 性能优化:动态添加大量子项时,建议用 RecyclerView + FlexboxLayoutManager 替代直接添加,避免布局嵌套过深和内存泄漏。

  2. 兼容性flexbox:3.0.0 要求 minSdk ≥ 14,如需更低版本可降级到 2.0.1。

  3. 属性优先级:子项的 layout_alignSelf 会覆盖容器的 alignItemslayout_flexGrow 仅在主轴有剩余空间时生效。

五、常见场景

  • 流式标签布局(如搜索历史、话题标签);

  • 自适应网格布局(替代 GridLayout,更灵活);

  • RecyclerView 流式列表(如商品列表、图片瀑布流);

  • 复杂的多行列自适应布局(替代嵌套 LinearLayout)。

通过以上用法,可快速实现前端 Flexbox 风格的灵活布局,解决 Android 原生布局难以实现的自适应排列问题。
 您阅读本篇文章共花了: 

版权声明

本文章如果涉及侵权,请联系我。
部分文章系本人原创未经许可,不得转载。

喜欢0发布评论

评论列表

发表评论

  • 昵称(必填)
  • 邮箱
  • 网址