父布局嵌套Stack形成两个组件样式

_buildBody() {
return Stack(
children: [_buildList(), _buildCid()],
);
}

第一个不用讲了。。第二个是我们今天的重点

_buildCid() {
return Positioned(
left: _offset.dx,
top: _offset.dy,
child: GestureDetector(
//滑动中,实时更新位置
onPanUpdate: (detail) {
setState(() {
_offset = Offset(
_offset.dx + detail.delta.dx, _offset.dy + detail.delta.dy);
});
},
//滑动结束 计算最后位置
onPanEnd: (detail) {
var margin = 5.0;
//得到屏幕宽度 根据宽度吸到边上
var screenWidth = MediaQuery.of(context).size.width;
var screenHeight = MediaQuery.of(context).size.height;
//得到当前控件宽
var weightWidgth = _cidGlobalKey.currentContext.size.width;
var weightHeight = _cidGlobalKey.currentContext.size.height;
//得到 当前偏移量
var offsetDx = _offset.dx;
var offsetDy = _offset.dy;
//右边吸边
if (offsetDx >= screenWidth / 2) {
offsetDx = screenWidth - weightWidgth - margin;
} else {
//左边吸边
offsetDx = margin;
}

if (offsetDy <= 0) {
offsetDy = margin;
}
//获取状态栏高度:
final double statusBarHeight = MediaQuery.of(context).padding.top;
//计算y轴的偏移量
var maxHeight = screenHeight -
weightHeight -
kBottomNavigationBarHeight -
kToolbarHeight -
margin -
statusBarHeight;
if (offsetDy > maxHeight) {
offsetDy = maxHeight;
}

setState(() {
_offset = Offset(offsetDx, offsetDy);
});
},
child: _cid.length > 0
? Chip(
key: _cidGlobalKey,
label: Text(
_cid,
style: TextStyle(color: Colors.white),
),
backgroundColor: _colorPrimary,
onDeleted: () {
setState(() {
_cid = "";
});
},
)
: Container(),
));
}
String _cid = "搞笑";

// 当前页数//设定Widget的偏移量
Offset _offset = Offset(20, 20);
final GlobalKey _cidGlobalKey = GlobalKey();

效果可以参照。头像表情包app  点金详情后再点击最下面的分

目前还没上架先贴一个图吧

Flutter 悬浮控件_控件

如果你的页面刚好包含FloatActionButton。。也需要处理一下

//得到FloatActionButton控件宽
var floatActionButtonWeightWidgth =
_floatActionButtonGlobalKey.currentContext.size.width + 20;
var floatActionButtonWeightHeight =
_floatActionButtonGlobalKey.currentContext.size.height + 20;
//y超过对x做限制 x超过对y做限制

//x和y分别都在FloatActionButton上面
if (offsetDy > maxHeight - floatActionButtonWeightHeight &&
offsetDx > maxWidth - floatActionButtonWeightWidgth) {
offsetDx = maxWidth;
offsetDy = maxHeight - floatActionButtonWeightHeight;
}