Flutter系列 06: 银行账户界面

2020-08-27  本文已影响0人  渣渣曦

本文做一个来自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.dartapp_drawer.dartapp_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),刷新图标区,账号项和底部代码,顶部截图如下:

image.png
创建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:RowContainer组件用于显示箭头和金额。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组件包含iconlabelonPressed()方法。设计中指定图标icon颜色设为Color(0xFF015FFF),文本颜色设为Colors.black。
余下的菜单项,通过透明度的置进行区分,活动项opacity值为1.0,其他默认0.3。因此用以下参数创建方法:IconDatatitlecoloropacity值,返加一个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()用于垂直组件间的间距,IconText组件为菜单项标题。对于非活动菜单项忽略opacitycolor属性。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容器采用默认为白色,itemchargedateString作为参数。容器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
image.png
上一篇下一篇

猜你喜欢

热点阅读