Flutter系列 06: 银行账户界面
本文做一个来自Dribble的银行账号界面。
image.png
开始
建立项目并切换目录
flutter create banking_app_account_ui
cd banking_app_account_ui
清空main.dart文件内容,替换为以下代码:
import 'package:flutter/material.dart';
import 'package:banking_app_account_ui/app_drawer.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Accounts',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Account(),
);
}
}
class Account extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
drawer: AppDrawer(),
appBar: AppBar(
iconTheme: IconThemeData(
color: Colors.blue,
),
backgroundColor: Colors.white,
elevation: 0.0,
title: Text(
"账户",
style: TextStyle(color: Colors.black),
),
centerTitle: true,
actions: [
IconButton(
icon: Icon(
Icons.search,
color:Colors.blue
),
onPressed: (){},
),
],
),
body: Container(color: Colors.white),
);
}
}
导入material.dart和app_drawer.dart。app_drawer.dart代码为抽屉侧边栏,建立并保存该文件到lib目录下。runApp()函数运行MyApp组件显示在屏幕上。之后定义materialApp属性。Home指定应用程序的默认路由。Home为一个无状态(stateless)组件,返回Scaffold组件。ThemeData定义应用程序的主题,参数包括指定颜色,字体和文本样式等。
增加AppBar,设置颜色主题为蓝色,背景色为白色,标题居中显示,设置elevation为0,增加搜索图标。
打开app_drawer.dart文件插入以下代码:
import 'package:flutter/material.dart';
class AppDrawer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SizedBox(
width: 160.0,
child: Drawer(),
);
}
}
AppDrawer组件仅返回宽度为160.0的SizedBox()和一个抽屉子节点。
测试
运行代码如下
image.png
顶部区域
在应用程序的方法体body里,创建顶部区域(top section),抽屉(drawer),刷新图标区,账号项和底部代码,顶部截图如下:
创建topArea()方法返回一个Card卡片,代码如下:
class topArea extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Card(
margin: EdgeInsets.all(10.0),
elevation: 1.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(50.0))),
child: Container(
decoration: BoxDecoration(
gradient: RadialGradient(
colors: [Color(0xFF015FFF), Color(0xFF015FFF)])),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
icon: Icon(
Icons.arrow_back,
color: Colors.white,
),
onPressed: () {},
),
Text(
"存款",
style: TextStyle(color: Colors.white, fontSize: 20.0),
),
IconButton(
icon: Icon(Icons.arrow_forward, color: Colors.white),
onPressed: () {},
)
],
),
Center(
child: Padding(
padding: EdgeInsets.all(5.0),
child: Text(
r"$ " "95,50.00",
style: TextStyle(color: Colors.white, fontSize: 24.0),
),
)),
SizedBox(
height: 35.0,
)
],
),
));
}
}
上述代码中,设置卡片的margin内边距,定义形状shape参数RoundedRectangleBorder组件,弧度radius设为50.0,增加一个包含有gradient的container容器,容器子组件为Column,其包含两个children:Row和Container组件用于显示箭头和金额。Row组件包含的三个子组件使用MainsAlignment.spaceBetween值设置彼此的间距。
Scaffold的body代码如下:
Container(
color: Colors.white,
child: Column(
children: <Widget>[
topArea(),
],
),
),
代码运行结果如下
image.png
侧边抽屉
打开app_drawer.dart文件,变更代码如下:
import 'package:flutter/material.dart';
class AppDrawer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SizedBox(
width: 160.0,
child: Drawer(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: EdgeInsets.only(top: 10.0),
child: FlatButton.icon(
icon: Icon(Icons.arrow_back, color: Color(0xFF015FFF)),
onPressed: null,
label: Text("返回",
style: TextStyle(
fontWeight: FontWeight.w400,
fontSize: 16.0,
color: Colors.black)),
color: Colors.black,
),
),
buildMenuItem(Icons.account_balance, "账户",
opacity: 1.0, color: Color(0xFF015FFF)),
Divider(),
buildMenuItem(Icons.compare_arrows, "转账"),
Divider(),
buildMenuItem(Icons.receipt, "结算"),
Divider(),
buildMenuItem(Icons.attach_money, "支付"),
Divider(),
buildMenuItem(Icons.sentiment_satisfied, "投资"),
Divider(),
buildMenuItem(Icons.phone, "帮助"),
Divider()
],
),
)),
);
}
Opacity buildMenuItem(IconData icon, String title,
{double opacity = 0.3, Color color = Colors.black}) {
return Opacity(
opacity: opacity,
child: Center(
child: Column(
children: <Widget>[
SizedBox(
height: 20.0,
),
Icon(
icon,
size: 50.0,
color: color,
),
SizedBox(
height: 10.0,
),
Text(title,
style: TextStyle(
fontWeight: FontWeight.w500, fontSize: 14.0, color: color)),
SizedBox(
height: 10.0,
),
],
),
),
);
}
}
AppDrawer组件返回一个宽度160.0的SizedBox组件包含抽屉Drawer组件。通过Column水平列出各项。crossAxisAlignment设置为center居中。
第一个子组件为返回箭头按钮,本例中使用FlatButton.icon。代码如下:
Padding(
padding: EdgeInsets.only(top: 10.0),
child: FlatButton.icon(
icon: Icon(
Icons.arrow_back,
color: Color(0xFF015FFF),
),
onPressed: null,
label: Text("Back",
style: TextStyle(
fontWeight: FontWeight.w400,
fontSize: 16.0,
color: Colors.black)),
color: Colors.black,
),
),
Padding组件子组件为FlatButton.icon。FlatButton.icon组件包含icon,label和onPressed()方法。设计中指定图标icon颜色设为Color(0xFF015FFF),文本颜色设为Colors.black。
余下的菜单项,通过透明度的置进行区分,活动项opacity值为1.0,其他默认0.3。因此用以下参数创建方法:IconData、title、color和opacity值,返加一个Opacity组件。代码buildMenuItem方法如下:
# Method defination
Opacity buildMenuItem(IconData icon, String title, {double opacity = 0.3, Color color = Colors.black})
# method call for active menu item
buildMenuItem(Icons.account_balance, "账户", opacity: 1.0, color: Color(0xFF015FFF)),
# method call for non active menu items
buildMenuItem(Icons.compare_arrows, "转账")
Opacity buildMenuItem(IconData icon, String title,
{double opacity = 0.3, Color color = Colors.black}) {
return Opacity(
opacity: opacity,
child: Center(
child: Column(
children: <Widget>[
SizedBox(
height: 20.0,
),
Icon(
icon,
size: 50.0,
color: color,
),
SizedBox(
height: 10.0,
),
Text(title,
style: TextStyle(
fontWeight: FontWeight.w500, fontSize: 14.0, color: color)),
SizedBox(
height: 10.0,
),
],
),
),
);
上述代码使用Center组件中间放置children。Column的children包含SizedBox()用于垂直组件间的间距,Icon和Text组件为菜单项标题。对于非活动菜单项忽略opacity和color属性。Divider()插入分割线。菜单项调用代码如下:
buildMenuItem(Icons.account_balance, "账户", opacity: 1.0, color: Color(0xFF015FFF)),
Divider(),
buildMenuItem(Icons.compare_arrows, "转账"),
Divider(),
buildMenuItem(Icons.receipt, "结算"),
Divider(),
buildMenuItem(Icons.attach_money, "支付"),
Divider(),
buildMenuItem(Icons.sentiment_satisfied, "投资"),
Divider(),
buildMenuItem(Icons.phone, "帮助"),
Divider()
运行程序如下:
image.png
刷新区域(section)
增加子组件为Icon的SizedBox组件。设置相应高度,尺寸和颜色。
SizedBox(
height: 40.0,
child: Icon(
Icons.refresh,
size: 35.0,
color: Color(0xFF015FFF),
),
)
image.png
body
增加方法displayAccountList()返回container容器。container子组件Column的children为:accountItems。
class displayAccoutList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.all(15.0),
child: Column(
children: <Widget>[
accountItems("应用开发", r"+ $ 4,946.00", "28-04-16", "credit",
oddColour: const Color(0xFFF7F7F9)),
accountItems(
"创意工作室", r"+ $ 5,428.00", "26-04-16", "credit"),
accountItems("支付宝", r"+ $ 746.00", "25-04-216", "Payment",
oddColour: const Color(0xFFF7F7F9)),
accountItems(
"创意工作室", r"+ $ 14,526.00", "16-04-16", "Payment"),
accountItems(
"书城协会", r"+ $ 2,876.00", "04-04-16", "Credit",
oddColour: const Color(0xFFF7F7F9)),
],
),
);
}
}
accountItemsContainer容器采用默认为白色,item、charge和dateString作为参数。容器padding外间距设置为EdgeInsets.only(top: 20.0,bottom:20.0,left:5.0,right:5.0),子组件Column三个children组件:两个Row和一个SizedBox()组件。Row组件mainAxisAlignment设置为MainAxisAlignment.spaceBetween
class accountItems extends StatelessWidget {
String item;
String charge;
String dateString;
String type;
Color oddColour;
accountItems(this.item, this.charge, this.dateString, this.type,
{this.oddColour = Colors.white});
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(color: oddColour),
padding: EdgeInsets.only(top: 20.0,bottom: 20.0,left: 5.0,right:5.0),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(item, style: TextStyle(fontSize: 16.0),),
Text(charge, style: TextStyle(fontSize: 16.0))
],
)
],
),
);
}
}
保存代码后重新加载如下:
image.png
底部区域(section)
Scaffold组件使用bottomNavigationBar,设置elevation为0.0,垂直容器外边界。Container容器使用有三个按钮的Row组件。
class bottomModal extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BottomAppBar(
elevation: 0.0,
child: Container(
margin: EdgeInsets.symmetric(vertical: 20.0),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
FlatButton(
padding: EdgeInsets.symmetric(vertical: 12.0, horizontal: 30.0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0.0)
),
color: Color(0xFF015FFF),
onPressed: (){},
child: Text("流水"),
),
OutlineButton(
padding: EdgeInsets.symmetric(vertical: 12.0, horizontal: 28.0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0.0)
),
borderSide: BorderSide(color: Color(0xFF015FFF),width: 1.0),
onPressed: (){},
child: Text("结算"),
),
OutlineButton(
padding: EdgeInsets.symmetric(vertical: 12.0, horizontal: 28.0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0.0)
),
borderSide: BorderSide(color: Color(0xFF015FFF), width: 1.0),
onPressed: () {},
child: Text("明细")
)
],
)
),
);
}
}
每一个按钮的shape设置为RoundedRectangleBorder(),使用BorderRadius.circular(0.0)的边框弧度。
保存并刷新页面如下图:
image.png