Wallet apps are very common nowadays, as we are using more and more our phones for financial purposes.

Today we will try to replicate this design from https://dribbble.com/shots/6639981-Wallet-app

First Step: Create a new flutter project

I like using the command line this way:

flutter create financial_app code .

first statement creates our app folder in the local directory, then we open the folder in Visual Studio Code using the second statement.

Second Step: Creating home page

In my development process I like to cut my design into smaller sections and turn every section into a widget then finally combine everything into the final app.

First widget will be the custom container with rounded corners and box shadow.

class CustomContainer extends StatelessWidget { final Widget child; CustomContainer({@required this.child}); @override Widget build(BuildContext context) { return Container( padding: EdgeInsets.symmetric(vertical: 15.0, horizontal: 21), margin: EdgeInsets.all(15.0), decoration: BoxDecoration( boxShadow: [ BoxShadow( blurRadius: 5.0, color: Colors.grey[300], spreadRadius: 5.0, ), ], borderRadius: BorderRadius.circular(41), color: Colors.white, ), child: child, ); } }

Next widget is the Credit Card:

class CreditCardContainer extends StatelessWidget { const CreditCardContainer({ Key key, }) : super(key: key); @override Widget build(BuildContext context) { return Container( margin: EdgeInsets.symmetric(horizontal: 31, vertical: 21), decoration: BoxDecoration( boxShadow: [ BoxShadow( blurRadius: 5.0, color: Colors.red[200], offset: Offset(0, 5)), ], borderRadius: BorderRadius.circular(15.0), gradient: LinearGradient( colors: [ Color(0xffff8964), Color(0xffff5d6e), ], ), ), child: Padding( padding: const EdgeInsets.all(13.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Container( child: Image.asset( "assets/imgs/chip.png", width: 51, height: 51, ), ), Text( "4000 1234 5678 9010", style: TextStyle(color: Colors.white, fontSize: 25), ), SizedBox( height: 11, ), Row( children: <Widget>[ Column( children: <Widget>[ Text( "VALID FROM: ", style: TextStyle(color: Colors.white, fontSize: 11.0), ), Text( "09/21", style: TextStyle(color: Colors.white, fontSize: 17), ), ], ), SizedBox( width: 21, ), Column( children: <Widget>[ Text( "VALID THRU: ", style: TextStyle(color: Colors.white, fontSize: 11.0), ), Text( "09/23", style: TextStyle(color: Colors.white, fontSize: 17), ), ], ), ], ), SizedBox( height: 11, ), Text( "AMAZIGH HALZOUN", style: TextStyle( color: Colors.white, fontSize: 19, ), ), ], ), ), ); } }

As you can see I am using static Text, obviously this is not the final product but for speed purposes I left everything static.

Now let’s create the rounded icon buttons in the middle section:

class CustomIconButton extends StatelessWidget { final String buttonTitle, buttonImg; final GestureTapCallback onTap; final Color circleColor; const CustomIconButton({ @required this.circleColor, @required this.buttonTitle, @required this.buttonImg, @required this.onTap, Key key, }) : super(key: key); @override Widget build(BuildContext context) { return Material( color: Colors.transparent, child: InkWell( onTap: onTap, child: Container( padding: EdgeInsets.all(5.0), alignment: Alignment.center, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ CircleAvatar( radius: 20, backgroundColor: circleColor, child: Image.asset( buttonImg, height: 19, width: 19, ), ), SizedBox( height: 5.0, ), Text( buttonTitle, overflow: TextOverflow.clip, style: TextStyle(), textAlign: TextAlign.center, ), ], ), ), ), ); } }

To create the transaction list I use a ListView and a custom ListTile as follow:

class HistoryListTile extends StatelessWidget { final Color iconColor; final String transactionName, transactionType, transactionAmount, transactionIcon; final GestureTapCallback onTap; const HistoryListTile({ Key key, this.iconColor, this.transactionName, this.transactionType, this.transactionAmount, this.transactionIcon, this.onTap, }) : super(key: key); @override Widget build(BuildContext context) { return Material( color: Colors.transparent, child: ListTile( title: Text(transactionName), subtitle: Text(transactionType), trailing: Text(transactionAmount), leading: CircleAvatar( radius: 25, child: Image.asset( transactionIcon, height: 25, width: 25, ), backgroundColor: iconColor, ), enabled: true, onTap: onTap, ), ); } }

Then I put it in a ListView

ListView( shrinkWrap: true, scrollDirection: Axis.vertical, children: <Widget>[ HistoryListTile( iconColor: IconColors.transfer, onTap: () {}, transactionAmount: "+\$210.00", transactionIcon: IconImgs.transfer, transactionName: "Amazigh Halzoun", transactionType: "TRANSFER", ), HistoryListTile( iconColor: IconColors.transfer, onTap: () {}, transactionAmount: "-\$310.00", transactionIcon: IconImgs.transfer, transactionName: "Cybdom Tech", transactionType: "TRANSFER", ), HistoryListTile( iconColor: IconColors.send, onTap: () {}, transactionAmount: "-\$210.00", transactionIcon: IconImgs.send, transactionName: "Wife", transactionType: "SEND", ), ], ),

Final Result:

I guess it looks pretty much identical, except for some proportions and Icons, anyway I hope you like this post please write a comment if you have any question.

Full source code will be available on part two so keep in touch 😉