mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-01-18 08:45:05 +00:00
CW-376-picker-ui-issue (#919)
* feat: use common modal widget for repeated picker logic and display * refactor: rename widget * refactor: clear wrapper logic from picker widget and move title to hasTitle * Minor code readability enhancements [skip ci] --------- Co-authored-by: OmarHatem <omarh.ismail1@gmail.com>
This commit is contained in:
parent
759e61f67e
commit
e28e2fbdde
4 changed files with 310 additions and 305 deletions
|
@ -1,13 +1,9 @@
|
|||
import 'dart:ui';
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/widgets/filter_tile.dart';
|
||||
import 'package:cake_wallet/src/widgets/section_divider.dart';
|
||||
import 'package:cake_wallet/src/widgets/standard_checkbox.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_background.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_close_button.dart';
|
||||
import 'package:cake_wallet/src/widgets/picker_wrapper_widget.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
//import 'package:date_range_picker/date_range_picker.dart' as date_rage_picker;
|
||||
|
@ -20,89 +16,93 @@ class FilterWidget extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
const sectionDivider = const SectionDivider();
|
||||
return AlertBackground(
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: <Widget>[
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 24, right: 24, top: 24),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.all(Radius.circular(24)),
|
||||
child: Container(
|
||||
color: Theme.of(context).textTheme!.bodyText1!.decorationColor!,
|
||||
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.all(24.0),
|
||||
child: Text(
|
||||
S.of(context).filter_by,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).primaryTextTheme.overline!.color!,
|
||||
fontSize: 16,
|
||||
fontFamily: 'Lato',
|
||||
decoration: TextDecoration.none,
|
||||
),
|
||||
return PickerWrapperWidget(
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 24, right: 24, top: 24),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.all(Radius.circular(24)),
|
||||
child: Container(
|
||||
color: Theme.of(context).textTheme!.bodyText1!.decorationColor!,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.all(24.0),
|
||||
child: Text(
|
||||
S.of(context).filter_by,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.overline!
|
||||
.color!,
|
||||
fontSize: 16,
|
||||
fontFamily: 'Lato',
|
||||
decoration: TextDecoration.none,
|
||||
),
|
||||
),
|
||||
sectionDivider,
|
||||
ListView.separated(
|
||||
padding: EdgeInsets.zero,
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemCount: dashboardViewModel.filterItems.length,
|
||||
separatorBuilder: (context, _) => sectionDivider,
|
||||
itemBuilder: (_, index1) {
|
||||
final title = dashboardViewModel.filterItems.keys.elementAt(index1);
|
||||
final section = dashboardViewModel.filterItems.values.elementAt(index1);
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 20, left: 24, right: 24),
|
||||
child: Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).primaryTextTheme!.headline6!.color!,
|
||||
fontSize: 16,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.bold,
|
||||
decoration: TextDecoration.none),
|
||||
),
|
||||
),
|
||||
sectionDivider,
|
||||
ListView.separated(
|
||||
padding: EdgeInsets.zero,
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemCount: dashboardViewModel.filterItems.length,
|
||||
separatorBuilder: (context, _) => sectionDivider,
|
||||
itemBuilder: (_, index1) {
|
||||
final title = dashboardViewModel.filterItems.keys
|
||||
.elementAt(index1);
|
||||
final section = dashboardViewModel.filterItems.values
|
||||
.elementAt(index1);
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
padding:
|
||||
EdgeInsets.only(top: 20, left: 24, right: 24),
|
||||
child: Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme!
|
||||
.headline6!
|
||||
.color!,
|
||||
fontSize: 16,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.bold,
|
||||
decoration: TextDecoration.none),
|
||||
),
|
||||
ListView.builder(
|
||||
padding: EdgeInsets.symmetric(vertical: 8.0),
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemCount: section.length,
|
||||
itemBuilder: (_, index2) {
|
||||
final item = section[index2];
|
||||
final content = Observer(
|
||||
builder: (_) => StandardCheckbox(
|
||||
value: item.value(),
|
||||
caption: item.caption,
|
||||
gradientBackground: true,
|
||||
borderColor: Theme.of(context).dividerColor,
|
||||
iconColor: Colors.white,
|
||||
onChanged: (value) => item.onChanged(),
|
||||
));
|
||||
return FilterTile(child: content);
|
||||
},
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
]),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
ListView.builder(
|
||||
padding: EdgeInsets.symmetric(vertical: 8.0),
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemCount: section.length,
|
||||
itemBuilder: (_, index2) {
|
||||
final item = section[index2];
|
||||
final content = Observer(
|
||||
builder: (_) => StandardCheckbox(
|
||||
value: item.value(),
|
||||
caption: item.caption,
|
||||
gradientBackground: true,
|
||||
borderColor:
|
||||
Theme.of(context).dividerColor,
|
||||
iconColor: Colors.white,
|
||||
onChanged: (value) =>
|
||||
item.onChanged(),
|
||||
));
|
||||
return FilterTile(child: content);
|
||||
},
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
]),
|
||||
),
|
||||
),
|
||||
AlertCloseButton()
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import 'package:cake_wallet/palette.dart';
|
||||
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_background.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_close_button.dart';
|
||||
import 'package:cake_wallet/src/widgets/picker_wrapper_widget.dart';
|
||||
|
||||
class CheckBoxPicker extends StatefulWidget {
|
||||
CheckBoxPicker({
|
||||
|
@ -32,73 +31,57 @@ class CheckBoxPickerState extends State<CheckBoxPicker> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AlertBackground(
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
Column(
|
||||
return PickerWrapperWidget(
|
||||
children: [
|
||||
if (widget.title.isNotEmpty)
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Text(
|
||||
widget.title,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.bold,
|
||||
decoration: TextDecoration.none,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 24, right: 24, top: 24),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.all(Radius.circular(30)),
|
||||
child: Container(
|
||||
color: Theme.of(context).accentTextTheme.headline6!.color!,
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
maxHeight: MediaQuery.of(context).size.height * 0.65,
|
||||
maxWidth: ResponsiveLayoutUtil.kPopupWidth,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
if (widget.title.isNotEmpty)
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Text(
|
||||
widget.title,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.bold,
|
||||
decoration: TextDecoration.none,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 24, right: 24, top: 24),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.all(Radius.circular(30)),
|
||||
child: Container(
|
||||
color: Theme.of(context).accentTextTheme.headline6!.color!,
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
maxHeight: MediaQuery.of(context).size.height * 0.65,
|
||||
maxWidth: ResponsiveLayoutUtil.kPopupWidth,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Flexible(
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: <Widget>[
|
||||
items.length > 3
|
||||
? Scrollbar(
|
||||
controller: controller,
|
||||
child: itemsList(),
|
||||
)
|
||||
: itemsList(),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
children: [
|
||||
Flexible(
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: <Widget>[
|
||||
items.length > 3
|
||||
? Scrollbar(
|
||||
controller: controller,
|
||||
child: itemsList(),
|
||||
)
|
||||
: itemsList(),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: ResponsiveLayoutUtil.kPopupSpaceHeight),
|
||||
AlertCloseButton(),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -111,7 +94,10 @@ class CheckBoxPickerState extends State<CheckBoxPicker> {
|
|||
shrinkWrap: true,
|
||||
separatorBuilder: (context, index) => widget.isSeparated
|
||||
? Divider(
|
||||
color: Theme.of(context).accentTextTheme.headline6!.backgroundColor!,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.headline6!
|
||||
.backgroundColor!,
|
||||
height: 1,
|
||||
)
|
||||
: const SizedBox(),
|
||||
|
|
|
@ -2,9 +2,8 @@
|
|||
|
||||
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_background.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_close_button.dart';
|
||||
import 'package:cw_core/currency.dart';
|
||||
import 'package:cake_wallet/src/widgets/picker_wrapper_widget.dart';
|
||||
|
||||
class Picker<Item> extends StatefulWidget {
|
||||
Picker({
|
||||
|
@ -114,171 +113,130 @@ class _PickerState<Item> extends State<Picker<Item>> {
|
|||
final mq = MediaQuery.of(context);
|
||||
final bottom = mq.viewInsets.bottom;
|
||||
final height = mq.size.height - bottom;
|
||||
final screenCenter = height / 2;
|
||||
|
||||
double closeButtonBottom = 60;
|
||||
double containerHeight = height * 0.65;
|
||||
if (bottom > 0) {
|
||||
// increase a bit or it gets too squished in the top
|
||||
containerHeight = height * 0.75;
|
||||
|
||||
final containerCenter = containerHeight / 2;
|
||||
final containerBottom = screenCenter - containerCenter;
|
||||
|
||||
final hasTitle = widget.title == null || widget.title!.isEmpty;
|
||||
|
||||
// position the close button right below the search container
|
||||
closeButtonBottom = closeButtonBottom -
|
||||
containerBottom +
|
||||
(hasTitle ? padding : padding / 1.5);
|
||||
}
|
||||
|
||||
return AlertBackground(
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: <Widget>[
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
if (widget.title?.isNotEmpty ?? false)
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: padding),
|
||||
child: Text(
|
||||
widget.title!,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.bold,
|
||||
decoration: TextDecoration.none,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: padding),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.all(Radius.circular(30)),
|
||||
child: Container(
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.headline6!
|
||||
.color!,
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
maxHeight: containerHeight,
|
||||
maxWidth: ResponsiveLayoutUtil.kPopupWidth,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (widget.hintText != null)
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: TextFormField(
|
||||
controller: searchController,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.headline6!
|
||||
.color!),
|
||||
decoration: InputDecoration(
|
||||
hintText: widget.hintText,
|
||||
prefixIcon: Image.asset(
|
||||
"assets/images/search_icon.png"),
|
||||
filled: true,
|
||||
fillColor: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.headline3!
|
||||
.color!,
|
||||
alignLabelWithHint: false,
|
||||
contentPadding:
|
||||
const EdgeInsets.symmetric(
|
||||
vertical: 4, horizontal: 16),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(14),
|
||||
borderSide: const BorderSide(
|
||||
color: Colors.transparent,
|
||||
)),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(14),
|
||||
borderSide: const BorderSide(
|
||||
color: Colors.transparent,
|
||||
)),
|
||||
),
|
||||
),
|
||||
),
|
||||
Divider(
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.headline6!
|
||||
.backgroundColor!,
|
||||
height: 1,
|
||||
),
|
||||
if (widget.selectedAtIndex != -1)
|
||||
buildSelectedItem(widget.selectedAtIndex),
|
||||
Flexible(
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: <Widget>[
|
||||
filteredItems.length > 3
|
||||
? Scrollbar(
|
||||
controller: controller,
|
||||
child: itemsList(),
|
||||
)
|
||||
: itemsList(),
|
||||
(widget.description?.isNotEmpty ?? false)
|
||||
? Positioned(
|
||||
bottom: padding,
|
||||
left: padding,
|
||||
right: padding,
|
||||
child: Text(
|
||||
widget.description!,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontFamily: 'Lato',
|
||||
decoration:
|
||||
TextDecoration.none,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.headline6!
|
||||
.color!,
|
||||
),
|
||||
),
|
||||
)
|
||||
: Offstage(),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
SizedBox(height: ResponsiveLayoutUtil.kPopupSpaceHeight),
|
||||
AlertCloseButton(bottom: closeButtonBottom),
|
||||
],
|
||||
return PickerWrapperWidget(
|
||||
hasTitle: widget.title?.isNotEmpty ?? false,
|
||||
children: [
|
||||
if (widget.title?.isNotEmpty ?? false)
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: padding),
|
||||
child: Text(
|
||||
widget.title!,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.bold,
|
||||
decoration: TextDecoration.none,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
// gives the extra spacing using MediaQuery.viewInsets.bottom
|
||||
// to simulate a keyboard area
|
||||
SizedBox(
|
||||
height: bottom,
|
||||
)
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: padding),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.all(Radius.circular(30)),
|
||||
child: Container(
|
||||
color: Theme.of(context).accentTextTheme.headline6!.color!,
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
maxHeight: containerHeight,
|
||||
maxWidth: ResponsiveLayoutUtil.kPopupWidth,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (widget.hintText != null)
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: TextFormField(
|
||||
controller: searchController,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.headline6!
|
||||
.color!),
|
||||
decoration: InputDecoration(
|
||||
hintText: widget.hintText,
|
||||
prefixIcon:
|
||||
Image.asset("assets/images/search_icon.png"),
|
||||
filled: true,
|
||||
fillColor: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.headline3!
|
||||
.color!,
|
||||
alignLabelWithHint: false,
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
vertical: 4, horizontal: 16),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
borderSide: const BorderSide(
|
||||
color: Colors.transparent,
|
||||
)),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
borderSide: const BorderSide(
|
||||
color: Colors.transparent,
|
||||
)),
|
||||
),
|
||||
),
|
||||
),
|
||||
Divider(
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.headline6!
|
||||
.backgroundColor!,
|
||||
height: 1,
|
||||
),
|
||||
if (widget.selectedAtIndex != -1)
|
||||
buildSelectedItem(widget.selectedAtIndex),
|
||||
Flexible(
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: <Widget>[
|
||||
filteredItems.length > 3
|
||||
? Scrollbar(
|
||||
controller: controller,
|
||||
child: itemsList(),
|
||||
)
|
||||
: itemsList(),
|
||||
(widget.description?.isNotEmpty ?? false)
|
||||
? Positioned(
|
||||
bottom: padding,
|
||||
left: padding,
|
||||
right: padding,
|
||||
child: Text(
|
||||
widget.description!,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontFamily: 'Lato',
|
||||
decoration: TextDecoration.none,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.headline6!
|
||||
.color!,
|
||||
),
|
||||
),
|
||||
)
|
||||
: Offstage(),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
|
|
61
lib/src/widgets/picker_wrapper_widget.dart
Normal file
61
lib/src/widgets/picker_wrapper_widget.dart
Normal file
|
@ -0,0 +1,61 @@
|
|||
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_background.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_close_button.dart';
|
||||
|
||||
class PickerWrapperWidget extends StatelessWidget {
|
||||
PickerWrapperWidget({required this.children, this.hasTitle = false});
|
||||
|
||||
final List<Widget> children;
|
||||
final bool hasTitle;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final double padding = 24;
|
||||
|
||||
final mq = MediaQuery.of(context);
|
||||
final bottom = mq.viewInsets.bottom;
|
||||
final height = mq.size.height - bottom;
|
||||
final screenCenter = height / 2;
|
||||
|
||||
double closeButtonBottom = 60;
|
||||
double containerHeight = height * 0.65;
|
||||
if (bottom > 0) {
|
||||
// increase a bit or it gets too squished in the top
|
||||
containerHeight = height * 0.75;
|
||||
|
||||
final containerCenter = containerHeight / 2;
|
||||
final containerBottom = screenCenter - containerCenter;
|
||||
|
||||
// position the close button right below the search container
|
||||
closeButtonBottom = closeButtonBottom -
|
||||
containerBottom + (!hasTitle ? padding : padding / 1.5);
|
||||
}
|
||||
|
||||
return AlertBackground(
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: <Widget>[
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: children,
|
||||
),
|
||||
SizedBox(height: ResponsiveLayoutUtil.kPopupSpaceHeight),
|
||||
AlertCloseButton(bottom: closeButtonBottom),
|
||||
],
|
||||
),
|
||||
),
|
||||
// gives the extra spacing using MediaQuery.viewInsets.bottom
|
||||
// to simulate a keyboard area
|
||||
SizedBox(
|
||||
height: bottom,
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue