Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
演示 overlay 的用法
import 'package:flutter/material.dart';
class OverlayBasic extends StatefulWidget {
@override
_OverlayBasicState createState() => _OverlayBasicState();
}
class _OverlayBasicState extends State<OverlayBasic> {
OverlayEntry _entry;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Overlay基本用法')),
body: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
RaisedButton(
onPressed: () {
if (_entry == null) {
_entry = OverlayEntry(builder: (BuildContext context) {
return Positioned(
top: 0,
left: 0,
width: 100,
child: SafeArea(
child: Material(
child: Container(
width: 100,
alignment: Alignment.center,
color: Colors.grey[800].withOpacity(0.7),
child: Text('hello'),
),
),
));
});
}
Overlay.of(context).insert(_entry);
},
child: Text('show overlay'),
),
RaisedButton(
onPressed: () {
_entry?.remove();
_entry = null;
},
child: Text('hide overlay'),
),
],
)),
);
}
}
import 'package:flutter/material.dart';
class OverlayPos extends StatefulWidget {
@override
_OverlayPosState createState() => _OverlayPosState();
}
class _MyButton extends StatefulWidget {
final PosCallback callback;
const _MyButton({Key key, this.callback}) : super(key: key);
@override
__MyButtonState createState() => __MyButtonState();
}
class __MyButtonState extends State<_MyButton> {
List<double> _calcPos() {
RenderBox renderBox = context.findRenderObject();
var size = renderBox.size;
var offset = renderBox.localToGlobal(Offset.zero);
return [offset.dx, offset.dy + size.height];
}
@override
Widget build(BuildContext context) {
return RaisedButton(
onPressed: () {
List<double> list = _calcPos();
widget.callback(list[0], list[1]);
},
child: Text('show overlay'),
);
}
}
class _OverlayPosState extends State<OverlayPos> {
OverlayEntry _entry;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Overlay的位置')),
body: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
_MyButton(
callback: _callback,
),
RaisedButton(
onPressed: () {
_entry?.remove();
_entry = null;
},
child: Text('hide overlay'),
),
],
)),
);
}
_callback(double left, double top) {
if (_entry == null) {
_entry = OverlayEntry(builder: (BuildContext context) {
return Positioned(
top: top,//680, //list[1],
left: left,//0, //list[0],
width: 100,
child: Material(
child: Container(
width: 100,
alignment: Alignment.center,
color: Colors.grey[800].withOpacity(0.7),
child: Text('hello'),
),
));
});
}
Overlay.of(context).insert(_entry);
}
}
typedef PosCallback = Function(double left, double top);
import 'package:flutter/material.dart';
class OverlayScrollFollow extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'Overlay跟随滚动',
),
),
body: ListView.builder(
itemBuilder: (BuildContext context, int index) {
return MyListTile(
pos: index + 1,
);
},
itemCount: 100,
),
);
}
}
class MyListTile extends StatefulWidget {
final int pos;
MyListTile({Key key, this.pos}) : super(key: key);
@override
_MyListTileState createState() => _MyListTileState();
}
class _MyListTileState extends State<MyListTile> {
OverlayEntry _entry;
List<double> _calcPos(BuildContext context) {
RenderBox renderBox = context.findRenderObject();
var size = renderBox.size;
var offset = renderBox.localToGlobal(Offset.zero);
return [offset.dx, offset.dy + size.height];
}
@override
Widget build(BuildContext context) {
return CompositedTransformTarget(
link: _layerLink,
child: ListTile(
title: Text('hello ${widget.pos}'),
onTap: () {
if (_entry != null) {
_entry.remove();
_entry = null;
} else {
List<double> list = _calcPos(context);
if (widget.pos % 2 == 1) {
_showEntry(context, top: list[1], left: list[0]);
} else {
_showFollowEntry(context, top: list[1], left: list[0]);
}
}
},
),
);
}
_showEntry(BuildContext context, {double top, double left}) {
if (_entry == null) {
_entry = OverlayEntry(builder: (BuildContext context) {
return Positioned(
top: top, //680, //list[1],
left: left, //0, //list[0],
width: 100,
child: Material(
child: Container(
width: 100,
alignment: Alignment.center,
color: Colors.grey[800].withOpacity(0.7),
child: Text('tip overlay for ${widget.pos}'),
),
));
});
}
Overlay.of(context).insert(_entry);
}
_showFollowEntry(BuildContext context, {double top, double left}) {
if (_entry == null) {
_entry = OverlayEntry(builder: (BuildContext context) {
return Positioned(
top: top, //680, //list[1],
left: left, //0, //list[0],
width: 100,
child: CompositedTransformFollower(
link: _layerLink,
showWhenUnlinked: false,
child: Material(
child: Container(
width: 100,
alignment: Alignment.center,
color: Colors.grey[800].withOpacity(0.7),
child: Text('tip overlay for ${widget.pos}'),
),
),
));
});
}
Overlay.of(context).insert(_entry);
}
final LayerLink _layerLink = LayerLink();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment