Hi,
We're using stacked for a new project and enjoying it so far, but a lot to learn along the way.
One thing we are trying to figure out is the best way to create an OverlayEntry
, typicall with a StatefulWidget this would be simple but with stacked we're not sure exactly what to do.
We have this partially working example, which does everything you are not supposed to do with stacked:
import 'package:flutter/material.dart';
import 'package:myapp/models/icons/app_icons.dart';
import 'package:myapp/models/theme/extension.dart';
import 'package:myapp/ui/widgets/top_bar/top_bar_viewmodel.dart';
import 'package:stacked/stacked.dart';
class TopBarView extends StatelessWidget {
final GlobalKey widgetKey;
TopBarView({
@required this.widgetKey,
});
@override
Widget build(BuildContext context) {
return ViewModelBuilder<TopBarViewModel>.reactive(
builder: (context, model, child) => Column(
key: widgetKey,
children: [
IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// Selected option and chevron
Expanded(
child: TextButton(
onPressed: () => model.selectedOptionPressed(widgetKey),
child: Container(
padding: EdgeInsetsDirectional.only(start: 16, end: 4),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text(
model.selectedOption,
overflow: TextOverflow.fade,
maxLines: 1,
softWrap: false,
style: Theme.of(context).textTheme.headline4,
),
),
Icon(
AppIcons.chevron_down,
size: 24,
color: Theme.of(context).own().textColor,
)
],
),
),
),
),
// Icon Button
Container(
width: 48,
height: 48,
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
),
child: TextButton(
child: Icon(
AppIcons.search,
size: 24,
color: Theme.of(context).backgroundColor,
),
onPressed: model.iconPressed,
),
),
],
),
),
Container(
width: double.infinity,
height: 1,
decoration: BoxDecoration(
color: Theme.of(context).own().dividerColor,
),
),
],
),
viewModelBuilder: () => TopBarViewModel(context: context),
);
}
}
And then ViewModel
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:myapp/models/theme/extension.dart';
import 'package:stacked/stacked.dart';
class TopBarViewModel extends BaseViewModel {
final BuildContext context;
TopBarViewModel({@required this.context});
String _selectedOption = "an option";
String get selectedOption => _selectedOption;
bool _isOpen = false;
bool get isOpen => _isOpen;
RenderBox _renderBox;
Offset _offset;
OverlayEntry _dropdownOverlay;
void selectedOptionPressed(GlobalKey widgetKey) {
_renderBox = widgetKey.currentContext.findRenderObject();
_offset = _renderBox.localToGlobal(Offset.zero);
print(_renderBox.size.height);
print(_renderBox.size.width);
print(_offset.dx);
print(_offset.dy);
_isOpen = !_isOpen;
if (_isOpen) {
_dropdownOverlay = _topBarOverlayWidget();
Overlay.of(context).insert(_dropdownOverlay);
} else {
_dropdownOverlay.remove();
}
}
OverlayEntry _topBarOverlayWidget() {
return OverlayEntry(builder: (context) {
return Positioned(
top: _offset.dy + _renderBox.size.height,
left: _offset.dx,
width: _renderBox.size.width,
child: Container(
height: 200,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(
Theme.of(context).own().radiusLg,
),
bottomRight: Radius.circular(
Theme.of(context).own().radiusLg,
),
),
boxShadow: [Theme.of(context).own().shadowTopBarDropdown],
color: Theme.of(context).backgroundColor,
),
),
);
});
}
void iconPressed() {}
}
Hoping for some insight as to what the right way to do this with stacked would be, thanks in advance for any insight!