mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-11-17 17:57:40 +00:00
desktop send/receive + transactions for eth view
This commit is contained in:
parent
b820b113e4
commit
387e2d8403
6 changed files with 277 additions and 254 deletions
|
@ -252,6 +252,7 @@ class _TransactionsListState extends ConsumerState<TransactionsList> {
|
||||||
},
|
},
|
||||||
child: Util.isDesktop
|
child: Util.isDesktop
|
||||||
? ListView.separated(
|
? ListView.separated(
|
||||||
|
shrinkWrap: true,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
BorderRadius? radius;
|
BorderRadius? radius;
|
||||||
if (_transactions2.length == 1) {
|
if (_transactions2.length == 1) {
|
||||||
|
|
|
@ -39,6 +39,8 @@ class DesktopTokenView extends ConsumerStatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _DesktopTokenViewState extends ConsumerState<DesktopTokenView> {
|
class _DesktopTokenViewState extends ConsumerState<DesktopTokenView> {
|
||||||
|
static const double sendReceiveColumnWidth = 460;
|
||||||
|
|
||||||
late final WalletSyncStatus initialSyncStatus;
|
late final WalletSyncStatus initialSyncStatus;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -168,11 +170,58 @@ class _DesktopTokenViewState extends ConsumerState<DesktopTokenView> {
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 24,
|
height: 24,
|
||||||
),
|
),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: sendReceiveColumnWidth,
|
||||||
|
child: Text(
|
||||||
|
"My wallet",
|
||||||
|
style: STextStyles.desktopTextExtraSmall(context).copyWith(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.textFieldActiveSearchIconLeft,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 16,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Recent transactions",
|
||||||
|
style:
|
||||||
|
STextStyles.desktopTextExtraSmall(context).copyWith(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.textFieldActiveSearchIconLeft,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
CustomTextButton(
|
||||||
|
text: "See all",
|
||||||
|
onTap: () {
|
||||||
|
Navigator.of(context).pushNamed(
|
||||||
|
AllTransactionsView.routeName,
|
||||||
|
arguments: widget.walletId,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 14,
|
||||||
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Row(
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 450,
|
width: sendReceiveColumnWidth,
|
||||||
child: MyWallet(
|
child: MyWallet(
|
||||||
walletId: widget.walletId,
|
walletId: widget.walletId,
|
||||||
contractAddress: ref.watch(
|
contractAddress: ref.watch(
|
||||||
|
@ -186,40 +235,8 @@ class _DesktopTokenViewState extends ConsumerState<DesktopTokenView> {
|
||||||
width: 16,
|
width: 16,
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: TokenTransactionsList(
|
||||||
children: [
|
walletId: widget.walletId,
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
"Recent transactions",
|
|
||||||
style: STextStyles.desktopTextExtraSmall(context)
|
|
||||||
.copyWith(
|
|
||||||
color: Theme.of(context)
|
|
||||||
.extension<StackColors>()!
|
|
||||||
.textFieldActiveSearchIconLeft,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
CustomTextButton(
|
|
||||||
text: "See all",
|
|
||||||
onTap: () {
|
|
||||||
Navigator.of(context).pushNamed(
|
|
||||||
AllTransactionsView.routeName,
|
|
||||||
arguments: widget.walletId,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 16,
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: TokenTransactionsList(
|
|
||||||
walletId: widget.walletId,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -309,6 +309,7 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Row(
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: sendReceiveColumnWidth,
|
width: sendReceiveColumnWidth,
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:stackwallet/pages/wallet_view/sub_widgets/transactions_list.dart';
|
||||||
import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_receive.dart';
|
import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_receive.dart';
|
||||||
import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send.dart';
|
import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send.dart';
|
||||||
import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_token_send.dart';
|
import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_token_send.dart';
|
||||||
import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/send_receive_tab_menu.dart';
|
import 'package:stackwallet/providers/global/wallets_provider.dart';
|
||||||
import 'package:stackwallet/utilities/constants.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
import 'package:stackwallet/widgets/custom_tab_view.dart';
|
||||||
|
import 'package:stackwallet/widgets/rounded_white_container.dart';
|
||||||
|
|
||||||
class MyWallet extends StatefulWidget {
|
class MyWallet extends ConsumerStatefulWidget {
|
||||||
const MyWallet({
|
const MyWallet({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.walletId,
|
required this.walletId,
|
||||||
|
@ -17,67 +20,82 @@ class MyWallet extends StatefulWidget {
|
||||||
final String? contractAddress;
|
final String? contractAddress;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<MyWallet> createState() => _MyWalletState();
|
ConsumerState<MyWallet> createState() => _MyWalletState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _MyWalletState extends State<MyWallet> {
|
class _MyWalletState extends ConsumerState<MyWallet> {
|
||||||
int _selectedIndex = 0;
|
final titles = [
|
||||||
|
"Send",
|
||||||
|
"Receive",
|
||||||
|
];
|
||||||
|
|
||||||
|
late final bool isEth;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
isEth = ref
|
||||||
|
.read(walletsChangeNotifierProvider)
|
||||||
|
.getManager(widget.walletId)
|
||||||
|
.coin ==
|
||||||
|
Coin.ethereum;
|
||||||
|
|
||||||
|
if (isEth && widget.contractAddress == null) {
|
||||||
|
titles.add("Transactions");
|
||||||
|
}
|
||||||
|
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ListView(
|
return ListView(
|
||||||
primary: false,
|
primary: false,
|
||||||
children: [
|
children: [
|
||||||
Container(
|
RoundedWhiteContainer(
|
||||||
decoration: BoxDecoration(
|
padding: EdgeInsets.zero,
|
||||||
color: Theme.of(context).extension<StackColors>()!.popupBG,
|
child: CustomTabView(
|
||||||
borderRadius: BorderRadius.vertical(
|
titles: titles,
|
||||||
top: Radius.circular(
|
children: [
|
||||||
Constants.size.circularBorderRadius,
|
widget.contractAddress == null
|
||||||
),
|
? Padding(
|
||||||
),
|
padding: const EdgeInsets.all(20),
|
||||||
),
|
child: DesktopSend(
|
||||||
child: SendReceiveTabMenu(
|
walletId: widget.walletId,
|
||||||
onChanged: (index) {
|
),
|
||||||
setState(() {
|
|
||||||
_selectedIndex = index;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Theme.of(context).extension<StackColors>()!.popupBG,
|
|
||||||
borderRadius: BorderRadius.vertical(
|
|
||||||
bottom: Radius.circular(
|
|
||||||
Constants.size.circularBorderRadius,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: AnimatedCrossFade(
|
|
||||||
firstChild: Padding(
|
|
||||||
key: const Key("desktopSendViewPortKey"),
|
|
||||||
padding: const EdgeInsets.all(20),
|
|
||||||
child: widget.contractAddress == null
|
|
||||||
? DesktopSend(
|
|
||||||
walletId: widget.walletId,
|
|
||||||
)
|
)
|
||||||
: DesktopTokenSend(
|
: Padding(
|
||||||
walletId: widget.walletId,
|
padding: const EdgeInsets.all(20),
|
||||||
|
child: DesktopTokenSend(
|
||||||
|
walletId: widget.walletId,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
Padding(
|
||||||
secondChild: Padding(
|
padding: const EdgeInsets.all(20),
|
||||||
key: const Key("desktopReceiveViewPortKey"),
|
child: DesktopReceive(
|
||||||
padding: const EdgeInsets.all(20),
|
walletId: widget.walletId,
|
||||||
child: DesktopReceive(
|
contractAddress: widget.contractAddress,
|
||||||
walletId: widget.walletId,
|
),
|
||||||
contractAddress: widget.contractAddress,
|
|
||||||
),
|
),
|
||||||
),
|
if (isEth && widget.contractAddress == null)
|
||||||
crossFadeState: _selectedIndex == 0
|
Padding(
|
||||||
? CrossFadeState.showFirst
|
padding: const EdgeInsets.only(top: 8.0),
|
||||||
: CrossFadeState.showSecond,
|
child: ConstrainedBox(
|
||||||
duration: const Duration(milliseconds: 250),
|
constraints: BoxConstraints(
|
||||||
|
maxHeight: MediaQuery.of(context).size.height - 362,
|
||||||
|
),
|
||||||
|
child: TransactionsList(
|
||||||
|
walletId: widget.walletId,
|
||||||
|
managerProvider: ref.watch(
|
||||||
|
walletsChangeNotifierProvider.select(
|
||||||
|
(value) => value.getManagerProvider(
|
||||||
|
widget.walletId,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,165 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:stackwallet/utilities/text_styles.dart';
|
|
||||||
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
|
||||||
|
|
||||||
class SendReceiveTabMenu extends StatefulWidget {
|
|
||||||
const SendReceiveTabMenu({
|
|
||||||
Key? key,
|
|
||||||
this.initialIndex = 0,
|
|
||||||
this.onChanged,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
final int initialIndex;
|
|
||||||
final void Function(int)? onChanged;
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<SendReceiveTabMenu> createState() => _SendReceiveTabMenuState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _SendReceiveTabMenuState extends State<SendReceiveTabMenu> {
|
|
||||||
late int _selectedIndex;
|
|
||||||
|
|
||||||
void _onChanged(int newIndex) {
|
|
||||||
if (_selectedIndex != newIndex) {
|
|
||||||
setState(() {
|
|
||||||
_selectedIndex = newIndex;
|
|
||||||
});
|
|
||||||
widget.onChanged?.call(_selectedIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
_selectedIndex = widget.initialIndex;
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: MouseRegion(
|
|
||||||
cursor: SystemMouseCursors.click,
|
|
||||||
child: GestureDetector(
|
|
||||||
onTap: () => _onChanged(0),
|
|
||||||
child: Container(
|
|
||||||
color: Colors.transparent,
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
const SizedBox(
|
|
||||||
height: 16,
|
|
||||||
),
|
|
||||||
AnimatedCrossFade(
|
|
||||||
firstChild: Text(
|
|
||||||
"Send",
|
|
||||||
style:
|
|
||||||
STextStyles.desktopTextExtraSmall(context).copyWith(
|
|
||||||
color: Theme.of(context)
|
|
||||||
.extension<StackColors>()!
|
|
||||||
.accentColorBlue,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
secondChild: Text(
|
|
||||||
"Send",
|
|
||||||
style:
|
|
||||||
STextStyles.desktopTextExtraSmall(context).copyWith(
|
|
||||||
color: Theme.of(context)
|
|
||||||
.extension<StackColors>()!
|
|
||||||
.textSubtitle1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
crossFadeState: _selectedIndex == 0
|
|
||||||
? CrossFadeState.showFirst
|
|
||||||
: CrossFadeState.showSecond,
|
|
||||||
duration: const Duration(milliseconds: 250),
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 19,
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
height: 2,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Theme.of(context)
|
|
||||||
.extension<StackColors>()!
|
|
||||||
.backgroundAppBar,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: MouseRegion(
|
|
||||||
cursor: SystemMouseCursors.click,
|
|
||||||
child: GestureDetector(
|
|
||||||
onTap: () => _onChanged(1),
|
|
||||||
child: Container(
|
|
||||||
color: Colors.transparent,
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
const SizedBox(
|
|
||||||
height: 16,
|
|
||||||
),
|
|
||||||
AnimatedCrossFade(
|
|
||||||
firstChild: Text(
|
|
||||||
"Receive",
|
|
||||||
style:
|
|
||||||
STextStyles.desktopTextExtraSmall(context).copyWith(
|
|
||||||
color: Theme.of(context)
|
|
||||||
.extension<StackColors>()!
|
|
||||||
.accentColorBlue,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
secondChild: Text(
|
|
||||||
"Receive",
|
|
||||||
style:
|
|
||||||
STextStyles.desktopTextExtraSmall(context).copyWith(
|
|
||||||
color: Theme.of(context)
|
|
||||||
.extension<StackColors>()!
|
|
||||||
.textSubtitle1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
crossFadeState: _selectedIndex == 1
|
|
||||||
? CrossFadeState.showFirst
|
|
||||||
: CrossFadeState.showSecond,
|
|
||||||
duration: const Duration(milliseconds: 250),
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 19,
|
|
||||||
),
|
|
||||||
Stack(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
height: 2,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Theme.of(context)
|
|
||||||
.extension<StackColors>()!
|
|
||||||
.backgroundAppBar,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
AnimatedSlide(
|
|
||||||
offset: Offset(_selectedIndex == 0 ? -1 : 0, 0),
|
|
||||||
duration: const Duration(milliseconds: 250),
|
|
||||||
child: Container(
|
|
||||||
height: 2,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Theme.of(context)
|
|
||||||
.extension<StackColors>()!
|
|
||||||
.accentColorBlue),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
151
lib/widgets/custom_tab_view.dart
Normal file
151
lib/widgets/custom_tab_view.dart
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
|
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
||||||
|
|
||||||
|
class CustomTabView extends StatefulWidget {
|
||||||
|
const CustomTabView({
|
||||||
|
Key? key,
|
||||||
|
required this.titles,
|
||||||
|
required this.children,
|
||||||
|
this.initialIndex = 0,
|
||||||
|
this.childPadding,
|
||||||
|
}) : assert(titles.length == children.length),
|
||||||
|
super(key: key);
|
||||||
|
|
||||||
|
final List<String> titles;
|
||||||
|
final List<Widget> children;
|
||||||
|
final int initialIndex;
|
||||||
|
final EdgeInsets? childPadding;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<CustomTabView> createState() => _CustomTabViewState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CustomTabViewState extends State<CustomTabView> {
|
||||||
|
final _key = GlobalKey();
|
||||||
|
late int _selectedIndex;
|
||||||
|
|
||||||
|
static const duration = Duration(milliseconds: 250);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
_selectedIndex = widget.initialIndex;
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return LayoutBuilder(
|
||||||
|
builder: (context, constraints) => Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
for (int i = 0; i < widget.titles.length; i++)
|
||||||
|
Expanded(
|
||||||
|
child: MouseRegion(
|
||||||
|
cursor: SystemMouseCursors.click,
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () => setState(() => _selectedIndex = i),
|
||||||
|
child: Container(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
const SizedBox(
|
||||||
|
height: 16,
|
||||||
|
),
|
||||||
|
AnimatedCrossFade(
|
||||||
|
firstChild: Text(
|
||||||
|
widget.titles[i],
|
||||||
|
style:
|
||||||
|
STextStyles.desktopTextExtraSmall(context)
|
||||||
|
.copyWith(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.accentColorBlue,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
secondChild: Text(
|
||||||
|
widget.titles[i],
|
||||||
|
style:
|
||||||
|
STextStyles.desktopTextExtraSmall(context)
|
||||||
|
.copyWith(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.textSubtitle1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
crossFadeState: _selectedIndex == i
|
||||||
|
? CrossFadeState.showFirst
|
||||||
|
: CrossFadeState.showSecond,
|
||||||
|
duration: const Duration(milliseconds: 250),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 19,
|
||||||
|
),
|
||||||
|
Stack(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
height: 2,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.backgroundAppBar,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
AnimatedSlide(
|
||||||
|
offset: Offset(_selectedIndex.toDouble(), 0),
|
||||||
|
duration: duration,
|
||||||
|
child: Container(
|
||||||
|
height: 2,
|
||||||
|
width: constraints.maxWidth / widget.titles.length,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.accentColorBlue,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
AnimatedSwitcher(
|
||||||
|
key: _key,
|
||||||
|
duration: duration,
|
||||||
|
transitionBuilder: (child, animation) {
|
||||||
|
return FadeTransition(
|
||||||
|
opacity: animation,
|
||||||
|
child: child,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
layoutBuilder: (currentChild, prevChildren) {
|
||||||
|
return Stack(
|
||||||
|
alignment: Alignment.topCenter,
|
||||||
|
children: [
|
||||||
|
...prevChildren,
|
||||||
|
if (currentChild != null) currentChild,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: AnimatedAlign(
|
||||||
|
key: Key(widget.titles[_selectedIndex]),
|
||||||
|
alignment: Alignment.topCenter,
|
||||||
|
duration: duration,
|
||||||
|
child: Padding(
|
||||||
|
padding: widget.childPadding ?? EdgeInsets.zero,
|
||||||
|
child: widget.children[_selectedIndex],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue