最近重拾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控件的位置进行相对设置.
本人新手其中有错误理解的地方请指出.这也是我自己对于此控件的理解
有更好的实现方式也请提出来吧