Flutter 类似Android的对齐方式实现

最近重拾Flutter 打算用它山寨一个抖音.所以开始了漫长的学习之路
在构造底部NavigationBarItem时 发现底部白线的宽度要等于itemtitle的宽度.这下可难倒我了在这里插入图片描述
要实现的效果是在这里插入图片描述
一开始用笨办法写了很长一串代码,而且很绕 大概是这样的

 BottomNavigationBarItem createNavitem(String name, int index) {
    return new BottomNavigationBarItem(
        icon: new Icon(Icons.live_tv),
        title: Container(
          height: 40,
          child: Stack(
            children: <Widget>[
              Center(
                child: Text(name),
              ),
              Visibility(
                child: Align(
                  alignment: AlignmentDirectional.bottomCenter,
                  child: Wrap(
                    children: <Widget>[
                      Container(
                        child: Text(
                          name,
                          style:
                              TextStyle(color: Colors.transparent, height: 0),
                        ),
                        color: Colors.white,
                        height: 2,
                      )
                    ],
                  ),
                ),
                visible: _tabIndex == index,
              ),
            ],
          ),
        ));
  }

相当于写了个一样的text控件只是把它的高度为0 用Warp控件包裹它

自己看了这段代码都头痛
在这里插入图片描述
要是在大Android上那还不是分分钟的事
在这里插入图片描述

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center">

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="首页" />

    <View
        android:layout_width="wrap_content"
        android:layout_height="2dp"
        android:layout_below="@id/title"
        android:layout_alignLeft="@id/title"
        android:layout_alignRight="@id/title"
        android:background="@color/colorAccent" />

</RelativeLayout>

就是这么简单

于是在Flutter开发群里提问 可惜始终都每人回答,那就只能自己想办法解决了
首先在Flutter中文社区里看看所有的Widget 看看有没有类似的控件,看了很多终于找着了个 从解释上来看有点像这个东西
在这里插入图片描述
几经反转终于成功了
下面说说实现方式

1.自定义MultiChildLayoutDelegate
这里面可以拿到各个控件的size 且可以更改控件的位置和大小属性
如下面

class ItemLayoutDelegate extends MultiChildLayoutDelegate {
  ItemLayoutDelegate();

  static const String title = 'title';
  static const String divider = 'divider';

  @override
  void performLayout(Size size) {
    final BoxConstraints constraints =
    new BoxConstraints(maxWidth: size.width);

    final Size titleSize = layoutChild(title, constraints);
    positionChild(title, new Offset(0.0, 0.0));

    BoxConstraints constraints1 = new BoxConstraints(maxWidth: titleSize.width,maxHeight: 2);
    final double dividerY = titleSize.height;
    layoutChild(divider, constraints1);
    positionChild(divider, new Offset(0.0, dividerY));
  }

  @override
  bool shouldRelayout(ItemLayoutDelegate oldDelegate) => false;
}

调用

                 child: CustomMultiChildLayout(
                    delegate: ItemLayoutDelegate(),
                    children: <Widget>[
                      LayoutId(
                        id: ItemLayoutDelegate.title,
                        child: new Text("首页",
                            style: TextStyle(fontSize: 20.0, color: Colors.white)),
                      ),
                      LayoutId(
                        id: ItemLayoutDelegate.divider,
                        child: new Container(
                          color: Colors.red,
                          height: 2,
                        )
                      ),
                    ],
                  ),

如图片中想要实现的效果 白线长度等于 Text控件的长度
这个和Android中非常像
layoutChild(title, constraints)有点像Android中的findviewById 其中 title字符串相当于Id
接着设置白线的宽度等于文本的长度 和它的位置

BoxConstraints constraints1 = new BoxConstraints(maxWidth: titleSize.width,maxHeight: 2);
    final double descriptionY = titleSize.height;
    layoutChild(divider, constraints1);
    positionChild(divider, new Offset(0.0, dividerY));

因为前面已经得到title控件的size所以下面直接用title控件的宽度就行了
位置页可以拿title控件的位置进行相对设置.
本人新手其中有错误理解的地方请指出.这也是我自己对于此控件的理解
有更好的实现方式也请提出来吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值