有同学在QQ群里问动态Badget怎么实现?效果图如下
image.png
想了一下,可以用Stack和Positioned结合来实现,难点就是怎么获取到文字部分的坐标。
- 如果文字长度固定,那么可以使用LayoutBuilder来获取文字右上角的坐标
- 如果文字长度不固定,那么只能等build完成后,使用GlobalKey来获取文字的长度了。
考虑到动态徽章可以在页面build完成后再显示,那这里就采用第二种方法。
Stack(
overflow: Overflow.visible,
children: <Widget>[
Text(
'你说啥?',
key: _key, //页面完成build后,使用这个_key来得到文字的长度
style: TextStyle(
fontSize: 16.0
),
),
Positioned(
left: _left,//动态徽章坐标
top: -6,
child: ClipRRect(
borderRadius: BorderRadius.all(
Radius.circular(4.0)
),
child: Container(
color: Colors.redAccent,
child: Padding(
padding: const EdgeInsets.only(
left: 3.0,
right: 3.0
),
child: Text(_numStr),
)
),
),
)
],
)
// 获取到文字的长度
setState(() {
_numStr = '99';
_left = _key.currentContext.size.width;
});
点击浮动按钮后,获取到文字的长度,再显示动态徽章
效果图如下
image.png
当然这里只提供了思路,UI的细节只能根据要求慢慢调整了。
最后完整代码如下:
import 'package:flutter/material.dart';
class RedBadget extends StatefulWidget {
@override
_RedBadgetState createState() => _RedBadgetState();
}
class _RedBadgetState extends State<RedBadget> {
GlobalKey _key = GlobalKey();
String _numStr = '99';
double _left = -5000.0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Red Badget'),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
_numStr = '99';
_left = _key.currentContext.size.width;
});
},
child: Icon(Icons.adjust),
),
body: Container(
child: Center(
child: Container(
// width: 100.0,
color: Colors.blueAccent,
child: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return Stack(
overflow: Overflow.visible,
children: <Widget>[
Text(
'你说啥?',
key: _key,
style: TextStyle(
fontSize: 16.0
),
),
Positioned(
left: _left,
top: -6,
child: ClipRRect(
borderRadius: BorderRadius.all(
Radius.circular(4.0)
),
child: Container(
color: Colors.redAccent,
child: Padding(
padding: const EdgeInsets.only(
left: 3.0,
right: 3.0
),
child: Text(_numStr),
)
),
),
)
],
);
},
),
),
),
),
);
}
}
网友评论