使用 FlexboxLayout 创建灵活的布局

发布于 2024-10-14 12:09:40 字数 5999 浏览 5 评论 0

去年,Google I / O 发布了 ConstraintLayout ,它使你能够在维护平面视图层次结构的同时构建复杂的布局。它也在 Android Studio 的 可视化布局编辑器 中完全支持。

同时,我们开源的 FlexboxLayoutCSS Flexible Layout 模块 的相同功能移植到 Android。这里有一些 FlexboxLayout 特别有效的情况。FlexboxLayout可以解释为高级 LinearLayout,因为这两个布局都会顺序对齐其子视图。FlexboxLayout与 LinearLayout 之间的显著差异是FlexboxLayout有包装的特性。

那就是说,如果你加入了属性 flexWrap="wrap" ,如果在当前行的左边没有足够的空间给下一个 view 时,FlexboxLayout会自动加一行,如下图所示。

img

各种屏幕尺寸的布局

考虑到这个特点,让我们来看一下你想要依次放置视图,但如果可用空间发生变化(由于设备因素,方向更改或多窗口模式下的窗口调整大小),则可以将它们移动到新行。

img
Nexus 5X 竖屏

img
Nexus 5X 横屏

img
Pixel C 启用多窗口模式,左侧分隔线。

img
Pixel C 启用多窗口模式,分频线在中间。

img
Pixel C 启用多窗口模式,右侧分隔线。

你需要定义多个 DP-bucket 布局(如 layout-600dp,layout-720dp,layout-1020dp),以处理诸如 LinearLayout 或者传统布局的各种屏幕尺寸 RelativeLayout。但是上面的对话框是用一个单独的FlexboxLayout

该示例中使用的技术是 flexWrap="wrap"如上所述设置,

<com .google.android.flexbox.flexboxlayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     app:flexwrap="wrap">

那么您可以获得以下布局,其中子视图与新行对齐,而不是溢出其父对象。

img

我想强调的另一种技术是将layout_flexGrow属性设置为 单个子 view。这有助于在剩余空间时改善最终布局的外观。该 layout_flexGrow属性的作用类似于其中 LinearLayout 的 layout_weight 属性。这意味着 FlexboxLayout 根据layout_flexGrow在同一行中为每个孩子设置的值分配剩余空间。

在下面的示例中,它假定每个孩子的layout_flexGrow 属性设置为 1,所以可用空间将均匀分布到它们中。

<android .support.design.widget.TextInputLayout
    android:layout_width="100dp"
    android:layout_height="wrap_content" 
    app:layout_flexgrow="1">

img
您可以在 GitHub 存储库中查看完整的 布局 xml 文件。

RecyclerView 集成

另一个优点FlexboxLayout是可以与 RecyclerView 集成。随着最新版本的 Alpha 版本FlexboxLayoutManager扩展RecyclerView.LayoutManager,现在你可以以更多的内存高效的方式在可滚动容器中使用 Flexbox 功能。

请注意,你仍然可以实现滚动 Flexbox 的容器FlexboxLayout包裹着 ScrollView。但是,如果布局中包含的项目数量较大,则可能会遇到 jankiness 甚至 OutOfMemoryError,因为FlexboxLayout用户滚动时不会将视图回收到屏幕上的视图。

(如果你想详细了解 RecyclerView 的详细信息,你可以检查出从 Android 的 UI 工具包的团队,如视频 12

一个真实世界的例子,其中RecyclerView集成是非常有用的是对于像谷歌照片应用程序或新闻应用程序的应用程序,都期望大量物品而需要处理各种物品宽度。

FlexboxLayout的存储库中可以找到一个 例子程序 。你可以在存储库中看到,每个图像显示RecyclerView的宽度不同。但是通过将flexWrap设置设置为 wrap,

FlexboxLayoutManager layoutManager = new FlexboxLayoutManager();
layoutManager.setFlexWrap(FlexWrap.WRAP);

并给每一个孩子设置flexGrow(如你所看到的,你可以通过配置的属性FlexboxLayoutManagerFlexboxLayoutManager.LayoutParams设置孩子的属性,而不是从 XML 配置)属性。

void bindTo(Drawable drawable) {
    mImageView.setImageDrawable(drawable);
    ViewGroup.LayoutParams lp = mImageView.getLayoutParams();
    if (lp instanceof FlexboxLayoutManager.LayoutParams) {
    FlexboxLayoutManager.LayoutParams flexboxLp = 
        (FlexboxLayoutManager.LayoutParams) mImageView.getLayoutParams();
    flexboxLp.setFlexGrow(1.0f);
    }
}

img
无论屏幕方向如何,你都可以很好地看到每个图像在布局中很合适。

如果你想查看完整的 FlexboxLayout 示例,可以查看:

下一步是什么?

查看其他属性的完整 文档 ,以构建针对你的需求量身定制的灵活布局。如果你发现任何问题或功能请求,我们很乐意听到你的反馈,请在 GitHub 信息库中提出问题

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

伴我老

暂无简介

0 文章
0 评论
21 人气
更多

推荐作者

linfzu01

文章 0 评论 0

可遇━不可求

文章 0 评论 0

枕梦

文章 0 评论 0

qq_3LFa8Q

文章 0 评论 0

JP

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文