Redesign exchange currency picker (#402)
Omar Hatem committed
Jul 1, 2022 at 12:17 UTC
3bd9301be1c4b906d88b973bec00943584514716
7 files changed
+259
-306
lib/src/screens/contact/contact_page.dart
+1
@@ -150,6 +150,7 @@ class ContactPage extends BasePage {
150
contactViewModel.currencies.indexOf(contactViewModel.currency),
151
items: contactViewModel.currencies,
152
title: S.of(context).please_select,
153
+ hintText: S.of(context).search_currency,
154
onItemSelected: (CryptoCurrency item) =>
155
contactViewModel.currency = item),
156
context: context);
lib/src/screens/exchange/widgets/currency_picker.dart
+106
-123
@@ -1,8 +1,8 @@
1
import 'dart:ui';
2
-import 'package:cake_wallet/generated/i18n.dart';
3
-import 'package:cake_wallet/palette.dart';
2
+import 'package:cake_wallet/src/screens/exchange/widgets/currency_picker_item_widget.dart';
3
import 'package:cake_wallet/src/screens/exchange/widgets/currency_utils.dart';
4
import 'package:cake_wallet/src/screens/exchange/widgets/picker_item.dart';
5
+import 'package:cake_wallet/src/widgets/alert_close_button.dart';
6
import 'package:flutter/cupertino.dart';
7
import 'package:flutter/material.dart';
8
import 'package:cw_core/crypto_currency.dart';
@@ -13,8 +13,9 @@ class CurrencyPicker extends StatefulWidget {
13
CurrencyPicker(
14
{@required this.selectedAtIndex,
15
@required this.items,
16
- @required this.title,
16
@required this.onItemSelected,
17
+ this.title,
18
+ this.hintText,
19
this.isMoneroWallet = false,
20
this.isConvertFrom = false});
21
@@ -24,6 +25,7 @@ class CurrencyPicker extends StatefulWidget {
25
final Function(CryptoCurrency) onItemSelected;
26
final bool isMoneroWallet;
27
final bool isConvertFrom;
28
+ final String hintText;
29
30
@override
31
CurrencyPickerState createState() => CurrencyPickerState(items);
@@ -34,11 +36,8 @@ class CurrencyPickerState extends State<CurrencyPicker> {
36
: isSearchBarActive = false,
37
textFieldValue = '',
38
subPickerItemsList = [],
37
- appBarTextStyle = TextStyle(
38
- fontSize: 20,
39
- fontFamily: 'Lato',
40
- backgroundColor: Colors.transparent,
41
- color: Colors.white);
39
+ appBarTextStyle =
40
+ TextStyle(fontSize: 20, fontFamily: 'Lato', backgroundColor: Colors.transparent, color: Colors.white);
41
42
@override
43
void initState() {
@@ -61,13 +60,10 @@ class CurrencyPickerState extends State<CurrencyPicker> {
60
TextStyle appBarTextStyle;
61
62
void cleanSubPickerItemsList() {
64
- subPickerItemsList = pickerItemsList
65
- .where((element) => items.contains(element.original))
66
- .toList();
63
+ subPickerItemsList = pickerItemsList.where((element) => items.contains(element.original)).toList();
64
}
65
69
- void currencySearchBySubstring(
70
- String subString, List<PickerItem<CryptoCurrency>> list) {
66
+ void currencySearchBySubstring(String subString, List<PickerItem<CryptoCurrency>> list) {
67
setState(() {
68
if (subString.isNotEmpty) {
69
subPickerItemsList = subPickerItemsList
@@ -84,118 +80,104 @@ class CurrencyPickerState extends State<CurrencyPicker> {
80
@override
81
Widget build(BuildContext context) {
82
return AlertBackground(
87
- child: SafeArea(
88
- child: Scaffold(
89
- resizeToAvoidBottomInset: false,
90
- backgroundColor: Colors.transparent,
91
- body: Column(
92
- children: [
93
- Padding(
94
- padding: EdgeInsets.symmetric(horizontal: 26.0, vertical: 0),
95
- child: Row(
96
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
97
- children: [
98
- isSearchBarActive
99
- ? Expanded(
100
- child: Row(
101
- mainAxisAlignment:
102
- MainAxisAlignment.spaceBetween,
103
- children: [
104
- InkWell(
105
- child: Text(
106
- S.of(context).cancel,
107
- style: appBarTextStyle,
108
- ),
109
- onTap: () {
110
- setState(() {
111
- isSearchBarActive = false;
112
- textFieldValue = '';
113
- cleanSubPickerItemsList();
114
- });
115
- }),
116
- Container(
117
- width: 100.0,
118
- child: CupertinoTextField(
119
- autofocus: true,
120
- placeholder:
121
- S.of(context).search + '...',
122
- placeholderStyle: appBarTextStyle,
123
- decoration: BoxDecoration(
124
- color: Colors.transparent),
125
- cursorColor: Colors.white,
126
- cursorHeight: 23.0,
127
- style: appBarTextStyle,
128
- onChanged: (value) {
129
- this.textFieldValue = value;
130
- cleanSubPickerItemsList();
131
- currencySearchBySubstring(
132
- textFieldValue,
133
- subPickerItemsList);
134
- }),
135
- )
136
- ],
137
- ),
138
- )
139
- : Text(
140
- widget.title,
141
- style: appBarTextStyle,
142
- ),
143
- IconButton(
144
- splashRadius: 23,
145
- icon: Icon(Icons.search, color: Colors.white),
146
- onPressed: () {
147
- setState(() {
148
- isSearchBarActive = true;
149
- });
150
- },
151
- )
152
- ]),
153
- ),
154
- Expanded(
155
- flex: 12,
156
- child: Padding(
157
- padding: const EdgeInsets.symmetric(
158
- horizontal: 26.0, vertical: 26.0),
159
- child: Container(
160
- child: CurrencyPickerWidget(
161
- crossAxisCount: 2,
162
- selectedAtIndex: widget.selectedAtIndex,
163
- itemsCount: subPickerItemsList.length,
164
- pickerItemsList: subPickerItemsList,
165
- pickListItem: (int index) {
166
- setState(() {
167
- widget.selectedAtIndex = index;
168
- });
169
- widget
170
- .onItemSelected(subPickerItemsList[index].original);
171
- if (widget.isConvertFrom &&
172
- !widget.isMoneroWallet &&
173
- (subPickerItemsList[index].original ==
174
- CryptoCurrency.xmr)) {
175
- } else {
176
- Navigator.of(context).pop();
177
- }
178
- },
83
+ child: Stack(
84
+ alignment: Alignment.center,
85
+ children: [
86
+ Column(
87
+ mainAxisSize: MainAxisSize.min,
88
+ children: <Widget>[
89
+ if (widget.title?.isNotEmpty ?? false)
90
+ Container(
91
+ padding: EdgeInsets.symmetric(horizontal: 24),
92
+ child: Text(
93
+ widget.title,
94
+ textAlign: TextAlign.center,
95
+ style: TextStyle(
96
+ fontSize: 18,
97
+ fontFamily: 'Lato',
98
+ fontWeight: FontWeight.bold,
99
+ decoration: TextDecoration.none,
100
+ color: Colors.white,
101
),
102
),
103
),
182
- ),
183
- Expanded(
184
- flex: 2,
185
- child: Container(
186
- width: 42.0,
187
- alignment: Alignment.topCenter,
188
- child: FittedBox(
189
- child: FloatingActionButton(
190
- elevation: 0,
191
- backgroundColor: Colors.white,
192
- onPressed: () {
193
- Navigator.of(context).pop();
194
- },
195
- child: Icon(
196
- Icons.close_outlined,
197
- color: Palette.darkBlueCraiola,
198
- size: 30.0,
104
+ Padding(
105
+ padding: EdgeInsets.only(left: 24, right: 24, top: 24),
106
+ child: ClipRRect(
107
+ borderRadius: BorderRadius.all(Radius.circular(30)),
108
+ child: Container(
109
+ color: Theme.of(context).accentTextTheme.title.color,
110
+ child: ConstrainedBox(
111
+ constraints: BoxConstraints(
112
+ maxHeight: MediaQuery.of(context).size.height * 0.65,
113
+ ),
114
+ child: Column(
115
+ mainAxisSize: MainAxisSize.min,
116
+ children: [
117
+ if (widget.hintText != null)
118
+ Padding(
119
+ padding: const EdgeInsets.all(16),
120
+ child: TextFormField(
121
+ style: TextStyle(color: Theme.of(context).primaryTextTheme.title.color),
122
+ decoration: InputDecoration(
123
+ hintText: widget.hintText,
124
+ prefixIcon: Image.asset("assets/images/search_icon.png"),
125
+ filled: true,
126
+ fillColor: const Color(0xffF2F0FA),
127
+ alignLabelWithHint: false,
128
+ contentPadding: const EdgeInsets.symmetric(vertical: 4, horizontal: 16),
129
+ enabledBorder: OutlineInputBorder(
130
+ borderRadius: BorderRadius.circular(14),
131
+ borderSide: const BorderSide(
132
+ color: Colors.transparent,
133
+ )),
134
+ focusedBorder: OutlineInputBorder(
135
+ borderRadius: BorderRadius.circular(14),
136
+ borderSide: const BorderSide(
137
+ color: Colors.transparent,
138
+ )),
139
+ ),
140
+ onChanged: (value) {
141
+ this.textFieldValue = value;
142
+ cleanSubPickerItemsList();
143
+ currencySearchBySubstring(textFieldValue, subPickerItemsList);
144
+ },
145
+ ),
146
+ ),
147
+ Divider(
148
+ color: Theme.of(context).accentTextTheme.title.backgroundColor,
149
+ height: 1,
150
+ ),
151
+ if (widget.selectedAtIndex != -1)
152
+ AspectRatio(
153
+ aspectRatio: 6,
154
+ child: PickerItemWidget(
155
+ title: pickerItemsList[widget.selectedAtIndex].title,
156
+ iconPath: pickerItemsList[widget.selectedAtIndex].iconPath,
157
+ isSelected: true,
158
+ tag: pickerItemsList[widget.selectedAtIndex].tag,
159
+ ),
160
+ ),
161
+ Flexible(
162
+ child: CurrencyPickerWidget(
163
+ crossAxisCount: 2,
164
+ selectedAtIndex: widget.selectedAtIndex,
165
+ pickerItemsList: subPickerItemsList,
166
+ pickListItem: (int index) {
167
+ setState(() {
168
+ widget.selectedAtIndex = index;
169
+ });
170
+ widget.onItemSelected(subPickerItemsList[index].original);
171
+ if (widget.isConvertFrom &&
172
+ !widget.isMoneroWallet &&
173
+ (subPickerItemsList[index].original == CryptoCurrency.xmr)) {
174
+ } else {
175
+ Navigator.of(context).pop();
176
+ }
177
+ },
178
+ ),
179
+ ),
180
+ ],
181
),
182
),
183
),
@@ -203,7 +185,8 @@ class CurrencyPickerState extends State<CurrencyPicker> {
185
),
186
],
187
),
206
- ),
188
+ AlertCloseButton(),
189
+ ],
190
),
191
);
192
}
lib/src/screens/exchange/widgets/currency_picker_item_widget.dart
+47
-66
@@ -2,8 +2,7 @@ import 'package:flutter/material.dart';
2
import 'package:cake_wallet/palette.dart';
3
4
class PickerItemWidget extends StatelessWidget {
5
- const PickerItemWidget(
6
- {this.iconPath, this.title, this.isSelected, this.tag, this.onTap});
5
+ const PickerItemWidget({this.iconPath, this.title, this.isSelected = false, this.tag, this.onTap});
6
7
final String iconPath;
8
final String title;
@@ -16,74 +15,56 @@ class PickerItemWidget extends StatelessWidget {
15
return GestureDetector(
16
onTap: onTap,
17
child: Container(
19
- color: isSelected
20
- ? Theme.of(context).textTheme.bodyText1.color
21
- : Theme.of(context).accentTextTheme.headline6.color,
22
- child: Center(
23
- child: Padding(
24
- padding: const EdgeInsets.all(8.0),
25
- child: Row(
26
- mainAxisAlignment: MainAxisAlignment.center,
27
- children: [
28
- Expanded(
29
- child: Container(
30
- child: Image.asset(
31
- iconPath,
32
- height: 32.0,
33
- width: 32.0,
34
- ),
35
- ),
18
+ color: Theme.of(context).accentTextTheme.headline6.color,
19
+ child: Padding(
20
+ padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 24),
21
+ child: Row(
22
+ children: [
23
+ Container(
24
+ child: Image.asset(
25
+ iconPath,
26
+ height: 20.0,
27
+ width: 20.0,
28
),
37
- Expanded(
38
- child: Stack(
39
- clipBehavior: Clip.none,
40
- alignment: Alignment.centerLeft,
41
- children: [
42
- Text(
43
- title,
44
- style: TextStyle(
45
- color: isSelected
46
- ? Palette.blueCraiola
47
- : Theme.of(context).primaryTextTheme.title.color,
48
- fontSize: 18.0,
49
- fontFamily: 'Lato',
29
+ ),
30
+ const SizedBox(width: 6),
31
+ Expanded(
32
+ child: Row(
33
+ children: [
34
+ Text(
35
+ title,
36
+ style: TextStyle(
37
+ color: isSelected ? Palette.blueCraiola : Theme.of(context).primaryTextTheme.title.color,
38
+ fontSize: isSelected ? 16 : 14.0,
39
+ fontFamily: 'Lato',
40
+ fontWeight: FontWeight.w600,
41
+ ),
42
+ ),
43
+ if (tag != null)
44
+ Align(
45
+ alignment: Alignment.topCenter,
46
+ child: Container(
47
+ width: 35.0,
48
+ height: 18.0,
49
+ child: Center(
50
+ child: Text(
51
+ tag,
52
+ style: TextStyle(
53
+ fontSize: 7.0, fontFamily: 'Lato', color: Theme.of(context).textTheme.body1.color),
54
+ ),
55
+ ),
56
+ decoration: BoxDecoration(
57
+ borderRadius: BorderRadius.circular(6.0),
58
+ //border: Border.all(color: ),
59
+ color: Theme.of(context).textTheme.body1.decorationColor,
60
+ ),
61
),
62
),
52
- tag != null
53
- ? Positioned(
54
- top: -20.0,
55
- right: 7.0,
56
- child: Container(
57
- width: 35.0,
58
- height: 18.0,
59
- child: Center(
60
- child: Text(
61
- tag,
62
- style: TextStyle(
63
- fontSize: 7.0,
64
- fontFamily: 'Lato',
65
- color: Theme.of(context)
66
- .textTheme
67
- .body1
68
- .color),
69
- ),
70
- ),
71
- decoration: BoxDecoration(
72
- borderRadius: BorderRadius.circular(6.0),
73
- //border: Border.all(color: ),
74
- color: Theme.of(context)
75
- .textTheme
76
- .body1
77
- .decorationColor,
78
- ),
79
- ),
80
- )
81
- : Container(),
82
- ],
83
- ),
63
+ ],
64
),
85
- ],
86
- ),
65
+ ),
66
+ if (isSelected) Icon(Icons.check_circle, color: Theme.of(context).accentTextTheme.body2.color)
67
+ ],
68
),
69
),
70
),
lib/src/screens/exchange/widgets/currency_picker_widget.dart
+27
-38
@@ -4,58 +4,47 @@ import 'picker_item.dart';
4
import 'currency_picker_item_widget.dart';
5
6
class CurrencyPickerWidget extends StatelessWidget {
7
- const CurrencyPickerWidget({
7
+ CurrencyPickerWidget({
8
@required this.crossAxisCount,
9
@required this.selectedAtIndex,
10
- @required this.itemsCount,
10
@required this.pickerItemsList,
11
@required this.pickListItem,
12
});
13
14
final int crossAxisCount;
15
final int selectedAtIndex;
17
- final int itemsCount;
16
final Function pickListItem;
17
final List<PickerItem<CryptoCurrency>> pickerItemsList;
18
19
+ final ScrollController _scrollController = ScrollController();
20
+
21
@override
22
Widget build(BuildContext context) {
23
- return LayoutBuilder(
24
- builder: (BuildContext context, BoxConstraints constraints) {
25
- return Container(
26
- decoration: BoxDecoration(
27
- color: Theme.of(context).accentTextTheme.headline6.backgroundColor,
28
- borderRadius: BorderRadius.circular(14.0),
29
- ),
30
- child: ClipRRect(
31
- borderRadius: BorderRadius.circular(14.0),
32
- child: Scrollbar(
33
- showTrackOnHover: true,
34
- isAlwaysShown: true,
35
- thickness: 6.0,
36
- radius: Radius.circular(3),
37
- child: GridView.builder(
38
- gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
39
- crossAxisCount: crossAxisCount,
40
- crossAxisSpacing: 1,
41
- mainAxisExtent: constraints.maxHeight / 8,
42
- mainAxisSpacing: 1),
43
- itemCount: pickerItemsList.length,
44
- itemBuilder: (BuildContext ctx, index) {
45
- return PickerItemWidget(
46
- onTap: () {
47
- pickListItem(index);
48
- },
49
- title: pickerItemsList[index].title,
50
- iconPath: pickerItemsList[index].iconPath,
51
- isSelected: index == selectedAtIndex,
52
- tag: pickerItemsList[index].tag,
53
- );
54
- }),
23
+ return Container(
24
+ color: Theme.of(context).accentTextTheme.headline6.backgroundColor,
25
+ child: Scrollbar(
26
+ controller: _scrollController,
27
+ child: GridView.builder(
28
+ controller: _scrollController,
29
+ padding: EdgeInsets.zero,
30
+ shrinkWrap: true,
31
+ gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
32
+ crossAxisCount: crossAxisCount,
33
+ crossAxisSpacing: 2,
34
+ childAspectRatio: 3,
35
),
56
- ),
57
- );
58
- },
36
+ itemCount: pickerItemsList.length,
37
+ itemBuilder: (BuildContext ctx, index) {
38
+ return PickerItemWidget(
39
+ onTap: () {
40
+ pickListItem(index);
41
+ },
42
+ title: pickerItemsList[index].title,
43
+ iconPath: pickerItemsList[index].iconPath,
44
+ tag: pickerItemsList[index].tag,
45
+ );
46
+ }),
47
+ ),
48
);
49
}
50
}
lib/src/screens/exchange/widgets/exchange_card.dart
+1
-1
@@ -445,7 +445,7 @@ class ExchangeCardState extends State<ExchangeCard> {
445
builder: (_) => CurrencyPicker(
446
selectedAtIndex: widget.currencies.indexOf(_selectedCurrency),
447
items: widget.currencies,
448
- title: S.of(context).change_currency,
448
+ hintText: S.of(context).search_currency,
449
isMoneroWallet: _isMoneroWallet,
450
isConvertFrom: widget.hasRefundAddress,
451
onItemSelected: (CryptoCurrency item) =>
lib/src/widgets/alert_close_button.dart
+8
-2
@@ -1,10 +1,16 @@
1
+import 'package:cake_wallet/palette.dart';
2
import 'package:flutter/material.dart';
3
4
class AlertCloseButton extends StatelessWidget {
4
- AlertCloseButton({@required this.image});
5
+ AlertCloseButton({this.image});
6
7
final Image image;
8
9
+ final closeButton = Image.asset(
10
+ 'assets/images/close.png',
11
+ color: Palette.darkBlueCraiola,
12
+ );
13
+
14
@override
15
Widget build(BuildContext context) {
16
return Positioned(
@@ -19,7 +25,7 @@ class AlertCloseButton extends StatelessWidget {
25
shape: BoxShape.circle
26
),
27
child: Center(
22
- child: image,
28
+ child: image ?? closeButton,
29
),
30
),
31
)
lib/src/widgets/picker.dart
+69
-76
@@ -3,7 +3,6 @@ import 'package:flutter/cupertino.dart';
3
import 'package:flutter/material.dart';
4
import 'package:cake_wallet/src/widgets/alert_background.dart';
5
import 'package:cake_wallet/src/widgets/alert_close_button.dart';
6
-import 'package:cake_wallet/palette.dart';
6
7
class Picker<Item extends Object> extends StatefulWidget {
8
Picker({
@@ -49,10 +48,6 @@ class PickerState<Item> extends State<Picker> {
48
49
final TextEditingController searchController = TextEditingController();
50
52
- final closeButton = Image.asset(
53
- 'assets/images/close.png',
54
- color: Palette.darkBlueCraiola,
55
- );
51
ScrollController controller = ScrollController();
52
53
@override
@@ -98,81 +93,78 @@ class PickerState<Item> extends State<Picker> {
93
),
94
Padding(
95
padding: EdgeInsets.only(left: 24, right: 24, top: 24),
101
- child: GestureDetector(
102
- onTap: () => null,
103
- child: ClipRRect(
104
- borderRadius: BorderRadius.all(Radius.circular(30)),
105
- child: Container(
106
- color: Theme.of(context).accentTextTheme.title.color,
107
- child: ConstrainedBox(
108
- constraints: BoxConstraints(
109
- maxHeight: MediaQuery.of(context).size.height * 0.65,
110
- ),
111
- child: Column(
112
- mainAxisSize: MainAxisSize.min,
113
- children: [
114
- if (widget.hintText != null)
115
- Padding(
116
- padding: const EdgeInsets.all(16),
117
- child: TextFormField(
118
- controller: searchController,
119
- style: TextStyle(color: Theme.of(context).primaryTextTheme.title.color),
120
- decoration: InputDecoration(
121
- hintText: widget.hintText,
122
- prefixIcon: Image.asset("assets/images/search_icon.png"),
123
- filled: true,
124
- fillColor: Theme.of(context).accentTextTheme.display2.color,
125
- alignLabelWithHint: false,
126
- contentPadding: const EdgeInsets.symmetric(vertical: 4, horizontal: 16),
127
- enabledBorder: OutlineInputBorder(
128
- borderRadius: BorderRadius.circular(14),
129
- borderSide: const BorderSide(
130
- color: Colors.transparent,
131
- )),
132
- focusedBorder: OutlineInputBorder(
133
- borderRadius: BorderRadius.circular(14),
134
- borderSide: const BorderSide(
135
- color: Colors.transparent,
136
- )),
137
- ),
96
+ child: ClipRRect(
97
+ borderRadius: BorderRadius.all(Radius.circular(30)),
98
+ child: Container(
99
+ color: Theme.of(context).accentTextTheme.title.color,
100
+ child: ConstrainedBox(
101
+ constraints: BoxConstraints(
102
+ maxHeight: MediaQuery.of(context).size.height * 0.65,
103
+ ),
104
+ child: Column(
105
+ mainAxisSize: MainAxisSize.min,
106
+ children: [
107
+ if (widget.hintText != null)
108
+ Padding(
109
+ padding: const EdgeInsets.all(16),
110
+ child: TextFormField(
111
+ controller: searchController,
112
+ style: TextStyle(color: Theme.of(context).primaryTextTheme.title.color),
113
+ decoration: InputDecoration(
114
+ hintText: widget.hintText,
115
+ prefixIcon: Image.asset("assets/images/search_icon.png"),
116
+ filled: true,
117
+ fillColor: Theme.of(context).accentTextTheme.display2.color,
118
+ alignLabelWithHint: false,
119
+ contentPadding: const EdgeInsets.symmetric(vertical: 4, horizontal: 16),
120
+ enabledBorder: OutlineInputBorder(
121
+ borderRadius: BorderRadius.circular(14),
122
+ borderSide: const BorderSide(
123
+ color: Colors.transparent,
124
+ )),
125
+ focusedBorder: OutlineInputBorder(
126
+ borderRadius: BorderRadius.circular(14),
127
+ borderSide: const BorderSide(
128
+ color: Colors.transparent,
129
+ )),
130
),
131
),
140
- Divider(
141
- color: Theme.of(context).accentTextTheme.title.backgroundColor,
142
- height: 1,
132
),
144
- if (widget.selectedAtIndex != -1) buildSelectedItem(),
145
- Flexible(
146
- child: Stack(
147
- alignment: Alignment.center,
148
- children: <Widget>[
149
- (items?.length ?? 0) > 3 ? Scrollbar(
150
- controller: controller,
151
- child: itemsList(),
152
- ) : itemsList(),
153
- (widget.description?.isNotEmpty ?? false)
154
- ? Positioned(
155
- bottom: 24,
156
- left: 24,
157
- right: 24,
158
- child: Text(
159
- widget.description,
160
- textAlign: TextAlign.center,
161
- style: TextStyle(
162
- fontSize: 12,
163
- fontWeight: FontWeight.w500,
164
- fontFamily: 'Lato',
165
- decoration: TextDecoration.none,
166
- color: Theme.of(context).primaryTextTheme.title.color,
167
- ),
133
+ Divider(
134
+ color: Theme.of(context).accentTextTheme.title.backgroundColor,
135
+ height: 1,
136
+ ),
137
+ if (widget.selectedAtIndex != -1) buildSelectedItem(),
138
+ Flexible(
139
+ child: Stack(
140
+ alignment: Alignment.center,
141
+ children: <Widget>[
142
+ (items?.length ?? 0) > 3 ? Scrollbar(
143
+ controller: controller,
144
+ child: itemsList(),
145
+ ) : itemsList(),
146
+ (widget.description?.isNotEmpty ?? false)
147
+ ? Positioned(
148
+ bottom: 24,
149
+ left: 24,
150
+ right: 24,
151
+ child: Text(
152
+ widget.description,
153
+ textAlign: TextAlign.center,
154
+ style: TextStyle(
155
+ fontSize: 12,
156
+ fontWeight: FontWeight.w500,
157
+ fontFamily: 'Lato',
158
+ decoration: TextDecoration.none,
159
+ color: Theme.of(context).primaryTextTheme.title.color,
160
),
169
- )
170
- : Offstage(),
171
- ],
172
- ),
161
+ ),
162
+ )
163
+ : Offstage(),
164
+ ],
165
),
174
- ],
175
- ),
166
+ ),
167
+ ],
168
),
169
),
170
),
@@ -180,7 +172,7 @@ class PickerState<Item> extends State<Picker> {
172
)
173
],
174
),
183
- AlertCloseButton(image: closeButton)
175
+ AlertCloseButton(),
176
],
177
),
178
);
@@ -193,6 +185,7 @@ class PickerState<Item> extends State<Picker> {
185
? GridView.builder(
186
padding: EdgeInsets.zero,
187
controller: controller,
188
+ shrinkWrap: true,
189
itemCount: items == null || items.isEmpty ? 0 : items.length,
190
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
191
crossAxisCount: 2,