Flutter 仿微信支付界面

左側(cè)是微信支付的界面,右側(cè)是開(kāi)發(fā)完成后的效果,圖標(biāo)是從 iconfont 上下載的。首先介紹一下本篇涉及到的組件。
帶裝飾效果的 Container
實(shí)際過(guò)程中我們經(jīng)常會(huì)遇到一個(gè)容器需要額外的樣式,例如圓角,背景色等。在 Flutter 中,對(duì)于各種容器都有一個(gè) decoration 的屬性,可以用于裝飾容器。典型的用法有設(shè)置背景色、圓角、邊框和陰影等,其中背景色可以使用漸變色。decoration 是一個(gè) Decoration 對(duì)象,最常用的是 BoxDecoration,BoxDecoration 的屬性如下所示:
const BoxDecoration({
this.color,
this.image,
this.border,
this.borderRadius,
this.boxShadow,
this.gradient,
this.backgroundBlendMode,
this.shape = BoxShape.rectangle,
})
其中color為使用顏色填充容器,image 為 使用圖片作為背景,border 為邊框,borderRadius 為邊框圓角,boxShadow 為容器陰影,gradient 使用漸變色作為背景,backgroundBlendMode 是指與容器的混合模型,默認(rèn)是覆蓋,shape 是背景形狀,默認(rèn)是矩形。其中背景部分我們一般只會(huì)選擇一種。這里以上面的綠色圓弧背景為例,還加上了一點(diǎn)點(diǎn)漸變(漸變色支持多個(gè),可以根據(jù)需要調(diào)節(jié)),示例代碼如下:
return Container(
//......
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4.0),
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color(0xFF56AF6D),
Color(0xFF56AA6D),
]),
),
//...
);
這里設(shè)置了邊角為圓弧,半徑為4,使用漸變色填充,漸變方向?yàn)閺捻敳恐醒氲降撞恐醒耄瑵u變色有兩個(gè)。
Row 行布局和 Column列布局
這個(gè)在之前的第五篇列表篇介紹過(guò),其中 Row 代表行布局(即子元素按一行排布),Column 代表列布局(即子元素按一列排布)。具體可以參考Flutter 入門(mén)與實(shí)戰(zhàn)(五):來(lái)一個(gè)圖文并茂的列表。
ListView列表組件
列表視圖,和之前的一篇一樣,只是本篇的用法不同,用于實(shí)現(xiàn)整個(gè)頁(yè)面可以按列表的方式進(jìn)行滾動(dòng),直接將各個(gè)部分組件放入到列表的 children屬性中,而不是使用數(shù)組構(gòu)建列表元素,有點(diǎn)類似滾動(dòng)視圖的用法。
GridView網(wǎng)格組件
GridView 用于將一個(gè)容器按行列劃分,可以指定主軸的元素個(gè)數(shù)(根據(jù)滾動(dòng)方向定),之后自動(dòng)按總元素的個(gè)數(shù)分別填充到網(wǎng)格,例如按縱向滾動(dòng)時(shí),則可以指定行方向一行有多少個(gè)網(wǎng)格,每個(gè)網(wǎng)格一個(gè)元素。超出一行數(shù)量后會(huì)自動(dòng)換另一行。最簡(jiǎn)單的用法是使用 GridView.count 方法構(gòu)建 GridView,用法如下:
GridView.count(
crossAxisSpacing: gridSpace,
mainAxisSpacing: gridSpace,
crossAxisCount: crossAxisCount,
//設(shè)置以下兩個(gè)參數(shù),禁止GridView的滾動(dòng),防止與 ListView 沖突
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
children: buttons.map((item) {
return _getMenus(item['icon'], item['name'], color: textColor);
}).toList(),
);
這里 crossAxisSpacing 是與滾動(dòng)方向垂直的元素的間距,如按縱向(默認(rèn)值)滾動(dòng),則是橫向行元素之間的間距。mainAxisSpacing 是與滾動(dòng)方向相同的元素的間距。children 即網(wǎng)格中的元素。這里需要注意的是,由于 本例中GridView是嵌套在 ListView 里面的,兩個(gè)組件都是縱向滾動(dòng),這樣會(huì)引起沖突導(dǎo)致布局無(wú)法滿足約束。因此,在這里設(shè)置了 shrinkWrap 為 true 和 physics 為NeverScrollableScrollPhysics,以禁止 GridView 的滾動(dòng),從而滿足約束。
代碼實(shí)現(xiàn)
首先來(lái)分析布局,所有菜單按鈕其實(shí)都是一樣的布局,可以使用統(tǒng)一的列布局完成菜單按鈕,提高復(fù)用性。菜單按鈕從上到下一次為圖標(biāo)、間距(圖標(biāo)與文字之間)和菜單名稱。實(shí)現(xiàn)代碼如下:
Column _getMenus(String icon, String name, {Color color = Colors.black}) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(
child: Image.asset(icon),
width: 50,
height: 50,
),
SizedBox(
height: 5,
),
Text(name, style: TextStyle(fontSize: 14.0, color: color, height: 2)),
],
);
通過(guò)傳輸一個(gè)圖標(biāo)名稱,菜單名稱和可選的字體顏色(頂部區(qū)域和其他的文字顏色不同)來(lái)實(shí)現(xiàn)單個(gè)菜單。
其次來(lái)看頂部區(qū)域,頂部區(qū)域只有兩個(gè)按鈕,使用帶裝飾的容器實(shí)現(xiàn)背景的裝飾和圓角。再采用行布局將兩個(gè)菜單按鈕在橫向均勻排布。同時(shí),使用 Center 布局將兩個(gè)菜單保持中部居中。這里指定了容器的高度,這是因?yàn)閺拿烙^上看太矮了不太協(xié)調(diào),實(shí)際開(kāi)發(fā)要根據(jù) UI 設(shè)計(jì)稿定。
Widget _headerGridButtons() {
double height = 144;
List<Map<String, String>> buttons = GridMockData.headerGrids();
return Container(
height: height,
margin: EdgeInsets.fromLTRB(MARGIN, MARGIN, MARGIN, MARGIN / 2),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4.0),
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color(0xFF56AF6D),
Color(0xFF56AA6D),
]),
),
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: buttons
.map((item) =>
_getMenus(item['icon'], item['name'], color: Colors.white))
.toList()),
),
);
}
其他菜單布局都是一樣,只是區(qū)域標(biāo)題,菜單數(shù)量、菜單內(nèi)容不同,因此可以統(tǒng)一封裝一個(gè)通用的方法來(lái)構(gòu)建任意形式的菜單,以及設(shè)置區(qū)域標(biāo)題的字體樣式、圓角背景等屬性。菜單均使用 GridView 實(shí)現(xiàn)網(wǎng)格式布局,同時(shí)由于菜單布局相同,可以封裝一個(gè)通用的方法來(lái)指定網(wǎng)格一行按鈕的數(shù)量,按鈕字體顏色等屬性,實(shí)現(xiàn)代碼的復(fù)用。
Widget _dynamicGridButtons(List<Map<String, String>> buttons, String title,
{int crossAxisCount = 4}) {
return Container(
margin: EdgeInsets.fromLTRB(MARGIN, MARGIN, MARGIN, MARGIN / 2),
padding: EdgeInsets.all(MARGIN),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4.0),
color: Colors.white,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: TextStyle(color: Colors.grey[700]),
),
SizedBox(height: 20),
_gridButtons(buttons, crossAxisCount, textColor: Colors.black),
],
),
);
}
GridView _gridButtons(List<Map<String, String>> buttons, int crossAxisCount,
{Color textColor = Colors.white}) {
double gridSpace = 5.0;
return GridView.count(
crossAxisSpacing: gridSpace,
mainAxisSpacing: gridSpace,
crossAxisCount: crossAxisCount,
//設(shè)置以下兩個(gè)參數(shù),禁止GridView的滾動(dòng),防止與 ListView 沖突
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
children: buttons.map((item) {
return _getMenus(item['icon'], item['name'], color: textColor);
}).toList(),
);
}
}
ListView 構(gòu)建完整頁(yè)面:實(shí)際的整個(gè)頁(yè)面很簡(jiǎn)單,只需要將各個(gè)區(qū)域放入到 ListView 的 children 屬性即可,從這里也可以看出,將子組件盡可能細(xì)化,不但能夠提高代碼復(fù)用性,還可以降低嵌套層級(jí),提高代碼的可讀性和可維護(hù)性。
@override
Widget build(BuildContext context) {
return Scaffold(
body: ListView(
children: [
_headerGridButtons(),
_dynamicGridButtons(GridMockData.financeGrids(), '金融理財(cái)'),
_dynamicGridButtons(GridMockData.serviceGrids(), '生活服務(wù)'),
_dynamicGridButtons(GridMockData.thirdpartyGrids(), '購(gòu)物消費(fèi)'),
],
),
);
}
Mock 數(shù)據(jù)準(zhǔn)備
按鈕數(shù)據(jù)均使用 Mock 數(shù)據(jù),這里只是返回一個(gè) List<Map<String, String>>數(shù)組對(duì)象,對(duì)象里是每個(gè)菜單的圖標(biāo)文件名稱和菜單名稱,下面是金融服務(wù)區(qū)域的菜單 Mock方法。
static List<Map<String, String>> financeGrids() {
return [
{'name': '信用卡還款', 'icon': 'images/grid-buttons/grid-1-1.png'},
{'name': '借錢(qián)', 'icon': 'images/grid-buttons/grid-1-2.png'},
{'name': '理財(cái)', 'icon': 'images/grid-buttons/grid-1-3.png'},
{'name': '保險(xiǎn)', 'icon': 'images/grid-buttons/grid-1-4.png'},
];
}
其他待改進(jìn)的地方:從代碼中可以看出,訪問(wèn)按鈕的時(shí)候是使用 Map 對(duì)象的鍵來(lái)訪問(wèn)的,需要使用['name']或['icon']來(lái)訪問(wèn),這種方式非常不利于編碼,而且很容易拼寫(xiě)錯(cuò)誤。因此,實(shí)際使用中應(yīng)當(dāng)將 Json 對(duì)象(即 Map)轉(zhuǎn)換為實(shí)體類,這樣就可以通過(guò)訪問(wèn)實(shí)體類的屬性來(lái)設(shè)置菜單的參數(shù),實(shí)際維護(hù)起來(lái)更為方便。
結(jié)語(yǔ):
Flutter 提供的基礎(chǔ) UI 組件庫(kù)能夠滿足絕大部分復(fù)雜頁(yè)面布局,通過(guò)各種布局組件的組合即可完成。因此,熟悉基礎(chǔ)的布局組件的特性十分重要。同時(shí),需要注意組件的拆分和抽離完成子組件的封裝,提高復(fù)用性的同時(shí)也避免了嵌套層級(jí)過(guò)深的問(wèn)題。
以上就是Flutter 仿微信支付界面的實(shí)現(xiàn)的詳細(xì)內(nèi)容,更多關(guān)于Flutter 微信支付界面的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android ExpandableListView實(shí)現(xiàn)下拉刷新和加載更多效果
這篇文章主要為大家詳細(xì)介紹了Android ExpandableListView實(shí)現(xiàn)下拉刷新和加載更多效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06
Android中TextView顯示圓圈背景或設(shè)置圓角的方法
TextView顯示文本給用戶,并允許他們選擇編輯。TextView是一個(gè)完整的文本編輯器,但是其基本類配置為不允許編輯。下面這篇文章主要給大家介紹了關(guān)于Android中TextView顯示圓圈背景或設(shè)置圓角的方法,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-05-05
android studio節(jié)省C盤(pán)空間的配置方法
這篇文章主要介紹了android studio節(jié)省C盤(pán)空間的配置方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2019-07-07
Android定制RadioButton樣式三種實(shí)現(xiàn)方法
三種方法實(shí)現(xiàn)Android定制RadioButton樣式:使用XML文件進(jìn)行定義/在JAVA代碼中定義等等,感興趣的朋友可以參考下,希望可以幫助到你2013-02-02
Kotlin基礎(chǔ)學(xué)習(xí)之lambda中return語(yǔ)句詳解
這篇文章主要給大家介紹了關(guān)于Kotlin基礎(chǔ)學(xué)習(xí)之lambda中return語(yǔ)句的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或使用Kotlin具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-07-07
安卓(Android)開(kāi)發(fā)之統(tǒng)計(jì)App啟動(dòng)時(shí)間
當(dāng)大家要改善APP啟動(dòng)速度優(yōu)化的時(shí)候,首先要知道App的啟動(dòng)時(shí)間,那么改如何統(tǒng)計(jì)時(shí)間呢,下面我們一起來(lái)看看。2016-08-08
Android中SeekBar拖動(dòng)條控件使用方法詳解
這篇文章主要介紹了Android中SeekBar拖動(dòng)條控件的使用方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08
Android實(shí)現(xiàn)支付寶6位密碼輸入界面
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)支付寶6位密碼輸入界面的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12
Android編程中activity啟動(dòng)時(shí)出現(xiàn)白屏、黑屏問(wèn)題的解決方法
這篇文章主要介紹了Android編程中activity啟動(dòng)時(shí)出現(xiàn)白屏、黑屏問(wèn)題的解決方法,涉及Android針對(duì)activity啟動(dòng)設(shè)置的技巧,需要的朋友可以參考下2015-12-12
Android編程實(shí)現(xiàn)文字倒影效果的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)文字倒影效果的方法,涉及Android布局與圖形繪制相關(guān)操作技巧,需要的朋友可以參考下2017-03-03

