Flutter如何实现仿京东商品详情底部操作栏

前言 不知道大家有没有留意京东 App的商品详情页,在底部有5个操作按钮,分成了3组,然后每一组占了1 3的宽度。这种布局,简单直接的方法是写死每一组宽度为屏幕

前言

不知道大家有没有留意京东 App的商品详情页,在底部有5个操作按钮,分成了3组,然后每一组占了1/3的宽度。这种布局,简单直接的方法是写死每一组宽度为屏幕宽度的1/3。能用,但是不太优雅。

本篇我们就来介绍一个布局组件,能够通过比例控制子组件的尺寸,从而可以达到类似京东底部操作按钮这种布局效果。这个组件就是FractionallySizedBox

FractionallySizedBox介绍

看组件名称就知道这是一个按比例控制的布局组件,FractionallySizedBox用于控制其子组件在它的父组件的控件宽高占比,定义如下:

const FractionallySizedBox({
  Key? key,
  this.alignment = Alignment.center,
  this.widthFactor,
  this.heightFactor,
  Widget? child,
})

可以看到,其实非常简单,总共就4个参数:

  • alignment:子组件相对父组件的对齐方式,默认是居中;
  • widthFactor:子组件宽度占父组件的比例,需要大于等于0,为空的话则由外部控制子组件的宽度;
  • heightFactor:子组件高度度占父组件的比例,为空的话则由外部控制子组件的高度;
  • child:被控制布局的子组件。

我们看一个简单的例子,我们在屏幕中间显示3个矩形框,然后每个矩形框都是上一个的一半尺寸,如下图所示。

对应的代码如下:

body: Center(
  child: FractionallySizedBox(
    widthFactor: 0.5,
    heightFactor: 0.5,
    child: Container(
      color: Colors.red[200],
      child: FractionallySizedBox(
        widthFactor: 0.5,
        heightFactor: 0.5,
        child: Container(
          color: Colors.red[400],
          child: FractionallySizedBox(
            widthFactor: 0.5,
            heightFactor: 0.5,
            child: Container(
              color: Colors.red[600],
            ),
          ),
        ),
      ),
    ),
  ),
),

仿京东商品详情底部操作栏

接下来我们来仿一下京东商品详情的操作栏。分析一下布局,实际上可以看作是一个分成了3等分的行组件,然后被分成了3组。其中左侧的图标按钮又是一个行组件。每一组内的宽高我们可以通过FractionallySizedBox来通过比例限制,从而保证了不同屏幕尺寸自适应。

注意的是,根据官方说明,要将FractionallySizedBox作为 Row 组件的子组件,需要使用一个Flexible组件包裹FractionallySizedBox。因此,我们需要使用三个 Flexible 弹性布局组件作为 Row 组件的子组件,设置每个 Flexible 组件的的 flex 参数都是1,这样就能够实现3等分了。当然,我们也可以调整为不同的flex值,达到不等分的效果。

接下来就是用FractionallySizedBox来设置具体操作元素的尺寸了,我们统一设置宽度占85%,高度占60%。最终的代码如下所示。

bottomSheet: Container(
  height: 68,
  decoration: BoxDecoration(
      color: Colors.black87,
      border: Border(
        top: BorderSide(
            width: 1.0, color: Colors.grey[300]!.withAlpha(20)),
      )),
  child: Row(
    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
    children: <Widget>[
      Flexible(
        flex: 1,
        child: FractionallySizedBox(
          widthFactor: _widthFactor,
          heightFactor: _heightFactor,
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: const [
              Icon(
                Icons.shopify,
                color: Colors.red,
              ),
              Icon(
                Icons.favorite_outline,
                color: Colors.red,
              ),
              Icon(
                Icons.star_border,
                color: Colors.red,
              )
            ],
          ),
        ),
      ),
      Flexible(
        flex: 1,
        child: FractionallySizedBox(
          widthFactor: _widthFactor,
          heightFactor: _heightFactor,
          child: Container(
            decoration: BoxDecoration(
              color: Colors.yellow[700],
              borderRadius: const BorderRadius.all(
                Radius.circular(20.0),
              ),
            ),
            child: TextButton(
              onPressed: () {},
              child: const Text(
                '加入购物车',
                style: TextStyle(
                  color: Colors.white,
                ),
              ),
            ),
          ),
        ),
      ),
      Flexible(
        flex: 1,
        child: FractionallySizedBox(
          widthFactor: _widthFactor,
          heightFactor: _heightFactor,
          child: Container(
            decoration: BoxDecoration(
              color: Colors.red[600],
              borderRadius: const BorderRadius.all(
                Radius.circular(20.0),
              ),
            ),
            child: TextButton(
              onPressed: () {},
              child: const Text(
                '立即购买',
                style: TextStyle(
                  color: Colors.white,
                ),
              ),
            ),
          ),
        ),
      ),
    ],
  ),
),

实现效果如下图所示,实际使用的时候我们可以根据需要调整宽度和高度比例,源码义提交至:Flutter 组件相关代码

总结

简单总结一下,我们可以看到,其实上面的例子不用FractionallySizedBox来做,我们的可选择的布局方案也会有很多种。然而如果不熟悉 Flutter 的布局组件的话,我们会感觉无从下手。个人的建议是,大家可以到 Flutter 官方的组件介绍中熟悉一些常用的组件。Flutter 官方的组件介绍文档链接为:docs.flutter.dev/ui/widgets,里面贴心地对组件做了分类。

到此这篇关于Flutter实现仿京东商品详情底部操作栏的文章就介绍到这了,更多相关Flutter底部操作栏内容请搜索好代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持好代码网!

您可能有感兴趣的文章
图文详解Flutter单例的如何实现

Flutter中如何使用setState时的6个简单技巧总结

Flutter路由fluro引入配置和如何使用的具体方法

Flutter如何实现下拉刷新和上拉加载更多

封装flutter状态管理工具示例详解