mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-23 03:59:23 +00:00
Redesign exchange currency picker (#402)
This commit is contained in:
parent
02533d68a0
commit
3bd9301be1
7 changed files with 259 additions and 306 deletions
|
@ -150,6 +150,7 @@ class ContactPage extends BasePage {
|
|||
contactViewModel.currencies.indexOf(contactViewModel.currency),
|
||||
items: contactViewModel.currencies,
|
||||
title: S.of(context).please_select,
|
||||
hintText: S.of(context).search_currency,
|
||||
onItemSelected: (CryptoCurrency item) =>
|
||||
contactViewModel.currency = item),
|
||||
context: context);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import 'dart:ui';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
import 'package:cake_wallet/src/screens/exchange/widgets/currency_picker_item_widget.dart';
|
||||
import 'package:cake_wallet/src/screens/exchange/widgets/currency_utils.dart';
|
||||
import 'package:cake_wallet/src/screens/exchange/widgets/picker_item.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_close_button.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
|
@ -13,8 +13,9 @@ class CurrencyPicker extends StatefulWidget {
|
|||
CurrencyPicker(
|
||||
{@required this.selectedAtIndex,
|
||||
@required this.items,
|
||||
@required this.title,
|
||||
@required this.onItemSelected,
|
||||
this.title,
|
||||
this.hintText,
|
||||
this.isMoneroWallet = false,
|
||||
this.isConvertFrom = false});
|
||||
|
||||
|
@ -24,6 +25,7 @@ class CurrencyPicker extends StatefulWidget {
|
|||
final Function(CryptoCurrency) onItemSelected;
|
||||
final bool isMoneroWallet;
|
||||
final bool isConvertFrom;
|
||||
final String hintText;
|
||||
|
||||
@override
|
||||
CurrencyPickerState createState() => CurrencyPickerState(items);
|
||||
|
@ -34,11 +36,8 @@ class CurrencyPickerState extends State<CurrencyPicker> {
|
|||
: isSearchBarActive = false,
|
||||
textFieldValue = '',
|
||||
subPickerItemsList = [],
|
||||
appBarTextStyle = TextStyle(
|
||||
fontSize: 20,
|
||||
fontFamily: 'Lato',
|
||||
backgroundColor: Colors.transparent,
|
||||
color: Colors.white);
|
||||
appBarTextStyle =
|
||||
TextStyle(fontSize: 20, fontFamily: 'Lato', backgroundColor: Colors.transparent, color: Colors.white);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
@ -61,13 +60,10 @@ class CurrencyPickerState extends State<CurrencyPicker> {
|
|||
TextStyle appBarTextStyle;
|
||||
|
||||
void cleanSubPickerItemsList() {
|
||||
subPickerItemsList = pickerItemsList
|
||||
.where((element) => items.contains(element.original))
|
||||
.toList();
|
||||
subPickerItemsList = pickerItemsList.where((element) => items.contains(element.original)).toList();
|
||||
}
|
||||
|
||||
void currencySearchBySubstring(
|
||||
String subString, List<PickerItem<CryptoCurrency>> list) {
|
||||
void currencySearchBySubstring(String subString, List<PickerItem<CryptoCurrency>> list) {
|
||||
setState(() {
|
||||
if (subString.isNotEmpty) {
|
||||
subPickerItemsList = subPickerItemsList
|
||||
|
@ -84,118 +80,104 @@ class CurrencyPickerState extends State<CurrencyPicker> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AlertBackground(
|
||||
child: SafeArea(
|
||||
child: Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
backgroundColor: Colors.transparent,
|
||||
body: Column(
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 26.0, vertical: 0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
isSearchBarActive
|
||||
? Expanded(
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
InkWell(
|
||||
child: Text(
|
||||
S.of(context).cancel,
|
||||
style: appBarTextStyle,
|
||||
),
|
||||
onTap: () {
|
||||
setState(() {
|
||||
isSearchBarActive = false;
|
||||
textFieldValue = '';
|
||||
cleanSubPickerItemsList();
|
||||
});
|
||||
}),
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
if (widget.title?.isNotEmpty ?? false)
|
||||
Container(
|
||||
width: 100.0,
|
||||
child: CupertinoTextField(
|
||||
autofocus: true,
|
||||
placeholder:
|
||||
S.of(context).search + '...',
|
||||
placeholderStyle: appBarTextStyle,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.transparent),
|
||||
cursorColor: Colors.white,
|
||||
cursorHeight: 23.0,
|
||||
style: appBarTextStyle,
|
||||
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.title.color,
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
maxHeight: MediaQuery.of(context).size.height * 0.65,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (widget.hintText != null)
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: TextFormField(
|
||||
style: TextStyle(color: Theme.of(context).primaryTextTheme.title.color),
|
||||
decoration: InputDecoration(
|
||||
hintText: widget.hintText,
|
||||
prefixIcon: Image.asset("assets/images/search_icon.png"),
|
||||
filled: true,
|
||||
fillColor: const Color(0xffF2F0FA),
|
||||
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,
|
||||
)),
|
||||
),
|
||||
onChanged: (value) {
|
||||
this.textFieldValue = value;
|
||||
cleanSubPickerItemsList();
|
||||
currencySearchBySubstring(
|
||||
textFieldValue,
|
||||
subPickerItemsList);
|
||||
}),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
widget.title,
|
||||
style: appBarTextStyle,
|
||||
),
|
||||
IconButton(
|
||||
splashRadius: 23,
|
||||
icon: Icon(Icons.search, color: Colors.white),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
isSearchBarActive = true;
|
||||
});
|
||||
currencySearchBySubstring(textFieldValue, subPickerItemsList);
|
||||
},
|
||||
)
|
||||
]),
|
||||
),
|
||||
Expanded(
|
||||
flex: 12,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 26.0, vertical: 26.0),
|
||||
child: Container(
|
||||
),
|
||||
Divider(
|
||||
color: Theme.of(context).accentTextTheme.title.backgroundColor,
|
||||
height: 1,
|
||||
),
|
||||
if (widget.selectedAtIndex != -1)
|
||||
AspectRatio(
|
||||
aspectRatio: 6,
|
||||
child: PickerItemWidget(
|
||||
title: pickerItemsList[widget.selectedAtIndex].title,
|
||||
iconPath: pickerItemsList[widget.selectedAtIndex].iconPath,
|
||||
isSelected: true,
|
||||
tag: pickerItemsList[widget.selectedAtIndex].tag,
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
child: CurrencyPickerWidget(
|
||||
crossAxisCount: 2,
|
||||
selectedAtIndex: widget.selectedAtIndex,
|
||||
itemsCount: subPickerItemsList.length,
|
||||
pickerItemsList: subPickerItemsList,
|
||||
pickListItem: (int index) {
|
||||
setState(() {
|
||||
widget.selectedAtIndex = index;
|
||||
});
|
||||
widget
|
||||
.onItemSelected(subPickerItemsList[index].original);
|
||||
widget.onItemSelected(subPickerItemsList[index].original);
|
||||
if (widget.isConvertFrom &&
|
||||
!widget.isMoneroWallet &&
|
||||
(subPickerItemsList[index].original ==
|
||||
CryptoCurrency.xmr)) {
|
||||
(subPickerItemsList[index].original == CryptoCurrency.xmr)) {
|
||||
} else {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Container(
|
||||
width: 42.0,
|
||||
alignment: Alignment.topCenter,
|
||||
child: FittedBox(
|
||||
child: FloatingActionButton(
|
||||
elevation: 0,
|
||||
backgroundColor: Colors.white,
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Icon(
|
||||
Icons.close_outlined,
|
||||
color: Palette.darkBlueCraiola,
|
||||
size: 30.0,
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -203,7 +185,8 @@ class CurrencyPickerState extends State<CurrencyPicker> {
|
|||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
AlertCloseButton(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2,8 +2,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:cake_wallet/palette.dart';
|
||||
|
||||
class PickerItemWidget extends StatelessWidget {
|
||||
const PickerItemWidget(
|
||||
{this.iconPath, this.title, this.isSelected, this.tag, this.onTap});
|
||||
const PickerItemWidget({this.iconPath, this.title, this.isSelected = false, this.tag, this.onTap});
|
||||
|
||||
final String iconPath;
|
||||
final String title;
|
||||
|
@ -16,43 +15,34 @@ class PickerItemWidget extends StatelessWidget {
|
|||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
color: isSelected
|
||||
? Theme.of(context).textTheme.bodyText1.color
|
||||
: Theme.of(context).accentTextTheme.headline6.color,
|
||||
child: Center(
|
||||
color: Theme.of(context).accentTextTheme.headline6.color,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 24),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
Container(
|
||||
child: Image.asset(
|
||||
iconPath,
|
||||
height: 32.0,
|
||||
width: 32.0,
|
||||
),
|
||||
height: 20.0,
|
||||
width: 20.0,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Expanded(
|
||||
child: Stack(
|
||||
clipBehavior: Clip.none,
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
color: isSelected
|
||||
? Palette.blueCraiola
|
||||
: Theme.of(context).primaryTextTheme.title.color,
|
||||
fontSize: 18.0,
|
||||
color: isSelected ? Palette.blueCraiola : Theme.of(context).primaryTextTheme.title.color,
|
||||
fontSize: isSelected ? 16 : 14.0,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
tag != null
|
||||
? Positioned(
|
||||
top: -20.0,
|
||||
right: 7.0,
|
||||
if (tag != null)
|
||||
Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: Container(
|
||||
width: 35.0,
|
||||
height: 18.0,
|
||||
|
@ -60,31 +50,22 @@ class PickerItemWidget extends StatelessWidget {
|
|||
child: Text(
|
||||
tag,
|
||||
style: TextStyle(
|
||||
fontSize: 7.0,
|
||||
fontFamily: 'Lato',
|
||||
color: Theme.of(context)
|
||||
.textTheme
|
||||
.body1
|
||||
.color),
|
||||
fontSize: 7.0, fontFamily: 'Lato', color: Theme.of(context).textTheme.body1.color),
|
||||
),
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(6.0),
|
||||
//border: Border.all(color: ),
|
||||
color: Theme.of(context)
|
||||
.textTheme
|
||||
.body1
|
||||
.decorationColor,
|
||||
color: Theme.of(context).textTheme.body1.decorationColor,
|
||||
),
|
||||
),
|
||||
)
|
||||
: Container(),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (isSelected) Icon(Icons.check_circle, color: Theme.of(context).accentTextTheme.body2.color)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -4,42 +4,35 @@ import 'picker_item.dart';
|
|||
import 'currency_picker_item_widget.dart';
|
||||
|
||||
class CurrencyPickerWidget extends StatelessWidget {
|
||||
const CurrencyPickerWidget({
|
||||
CurrencyPickerWidget({
|
||||
@required this.crossAxisCount,
|
||||
@required this.selectedAtIndex,
|
||||
@required this.itemsCount,
|
||||
@required this.pickerItemsList,
|
||||
@required this.pickListItem,
|
||||
});
|
||||
|
||||
final int crossAxisCount;
|
||||
final int selectedAtIndex;
|
||||
final int itemsCount;
|
||||
final Function pickListItem;
|
||||
final List<PickerItem<CryptoCurrency>> pickerItemsList;
|
||||
|
||||
final ScrollController _scrollController = ScrollController();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints constraints) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).accentTextTheme.headline6.backgroundColor,
|
||||
borderRadius: BorderRadius.circular(14.0),
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(14.0),
|
||||
child: Scrollbar(
|
||||
showTrackOnHover: true,
|
||||
isAlwaysShown: true,
|
||||
thickness: 6.0,
|
||||
radius: Radius.circular(3),
|
||||
controller: _scrollController,
|
||||
child: GridView.builder(
|
||||
controller: _scrollController,
|
||||
padding: EdgeInsets.zero,
|
||||
shrinkWrap: true,
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: crossAxisCount,
|
||||
crossAxisSpacing: 1,
|
||||
mainAxisExtent: constraints.maxHeight / 8,
|
||||
mainAxisSpacing: 1),
|
||||
crossAxisSpacing: 2,
|
||||
childAspectRatio: 3,
|
||||
),
|
||||
itemCount: pickerItemsList.length,
|
||||
itemBuilder: (BuildContext ctx, index) {
|
||||
return PickerItemWidget(
|
||||
|
@ -48,14 +41,10 @@ class CurrencyPickerWidget extends StatelessWidget {
|
|||
},
|
||||
title: pickerItemsList[index].title,
|
||||
iconPath: pickerItemsList[index].iconPath,
|
||||
isSelected: index == selectedAtIndex,
|
||||
tag: pickerItemsList[index].tag,
|
||||
);
|
||||
}),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -445,7 +445,7 @@ class ExchangeCardState extends State<ExchangeCard> {
|
|||
builder: (_) => CurrencyPicker(
|
||||
selectedAtIndex: widget.currencies.indexOf(_selectedCurrency),
|
||||
items: widget.currencies,
|
||||
title: S.of(context).change_currency,
|
||||
hintText: S.of(context).search_currency,
|
||||
isMoneroWallet: _isMoneroWallet,
|
||||
isConvertFrom: widget.hasRefundAddress,
|
||||
onItemSelected: (CryptoCurrency item) =>
|
||||
|
|
|
@ -1,10 +1,16 @@
|
|||
import 'package:cake_wallet/palette.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class AlertCloseButton extends StatelessWidget {
|
||||
AlertCloseButton({@required this.image});
|
||||
AlertCloseButton({this.image});
|
||||
|
||||
final Image image;
|
||||
|
||||
final closeButton = Image.asset(
|
||||
'assets/images/close.png',
|
||||
color: Palette.darkBlueCraiola,
|
||||
);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Positioned(
|
||||
|
@ -19,7 +25,7 @@ class AlertCloseButton extends StatelessWidget {
|
|||
shape: BoxShape.circle
|
||||
),
|
||||
child: Center(
|
||||
child: image,
|
||||
child: image ?? closeButton,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
|
@ -3,7 +3,6 @@ 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/palette.dart';
|
||||
|
||||
class Picker<Item extends Object> extends StatefulWidget {
|
||||
Picker({
|
||||
|
@ -49,10 +48,6 @@ class PickerState<Item> extends State<Picker> {
|
|||
|
||||
final TextEditingController searchController = TextEditingController();
|
||||
|
||||
final closeButton = Image.asset(
|
||||
'assets/images/close.png',
|
||||
color: Palette.darkBlueCraiola,
|
||||
);
|
||||
ScrollController controller = ScrollController();
|
||||
|
||||
@override
|
||||
|
@ -98,8 +93,6 @@ class PickerState<Item> extends State<Picker> {
|
|||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 24, right: 24, top: 24),
|
||||
child: GestureDetector(
|
||||
onTap: () => null,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.all(Radius.circular(30)),
|
||||
child: Container(
|
||||
|
@ -176,11 +169,10 @@ class PickerState<Item> extends State<Picker> {
|
|||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
AlertCloseButton(image: closeButton)
|
||||
AlertCloseButton(),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
@ -193,6 +185,7 @@ class PickerState<Item> extends State<Picker> {
|
|||
? GridView.builder(
|
||||
padding: EdgeInsets.zero,
|
||||
controller: controller,
|
||||
shrinkWrap: true,
|
||||
itemCount: items == null || items.isEmpty ? 0 : items.length,
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 2,
|
||||
|
|
Loading…
Reference in a new issue