我要做的是用BottomNavigationBarItem移除/替換FAB(浮動(dòng)操作按鈕),并將其放在BottomNavigationBar的中心,并為其創(chuàng)建樣式。
為安州等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計(jì)制作服務(wù),及安州網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為做網(wǎng)站、網(wǎng)站制作、安州網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長期合作。這樣,我們也可以走得更遠(yuǎn)!
為了按鈕能夠根據(jù)屏幕寬度進(jìn)行延伸變寬,用了row和expanded,expanded多大面積,按鈕就有多大面積。如果不用row,expanded會(huì)向下延伸,就不是我們要的效果了。
OutlineButton控件的child和onPressed是必須的屬性,borderSide用來自定義邊框顏色和樣式。
[img]在 Flutter 里有很多的 Button,包括了:MaterialButton、RaisedButton、FloatingActionButton、FlatButton、IconButton、ButtonBar、DropdownButton 等。
一般常用的 Button 是 MaterialButton、IconButton、FloatingActionButton。
MaterialButton 是一個(gè) Materia 風(fēng)格的按鈕。
一般來說,如果需要點(diǎn)擊事件,就要嵌套一個(gè) Button,因?yàn)?Container、Text 等組件都沒有點(diǎn)擊事件。
RaisedButton 與 MaterialButton 類似。
FlatButton 與 MaterialButton 類似,不同的是它是透明背景的。如果一個(gè) Container 想要點(diǎn)擊事件時(shí),可以使用 FlatButton 包裹,而不是 MaterialButton。因?yàn)?MaterialButton 默認(rèn)帶背景,而 FlatButton 默認(rèn)不帶背景。
IconButton 顧名思義就是 Icon + Button 的復(fù)合體,當(dāng)某個(gè) Icon 需要點(diǎn)擊事件時(shí),使用 IconButton 最好不過。
其外,還有已經(jīng)定義好的 Icon Button:CloseButton、BackButton。他們都有導(dǎo)航返回的能力。
FloatingActionButton 是一個(gè)浮動(dòng)在頁面右下角的浮動(dòng)按鈕。
在 Scaffold 里使用的時(shí)候,它是一個(gè)浮動(dòng)狀態(tài)的按鈕,在其他地方使用,就不會(huì)浮動(dòng)了。
ButtonBar 是一個(gè)布局組件,可以讓 Button 排列在一行。
相對于iOS開發(fā),F(xiàn)lutter的布局更具有靈活性,每個(gè)頁面設(shè)計(jì)都不一樣,相同頁面可選擇的布局方式也不一樣,如果單純的說應(yīng)該如何去布局,我覺得不現(xiàn)實(shí),大家可以參考下 Flutter官方的布局教程 。接下來,筆者,通過項(xiàng)目中的一個(gè)頁面,來一步一步的拆解布局的流程。整個(gè)過程,基本上按照拆解、組件封裝、具體布局這三步來的。
根據(jù)設(shè)計(jì)圖,可以看出整體可以分成兩部分,上面一部分是系統(tǒng)介紹模塊,下面一部分是真正的登錄內(nèi)容,因?yàn)樯婕暗蒋B加,因此考慮用Stack;
系統(tǒng)介紹模塊部分:整體也是涉及到疊加,考慮用Stack,分為四部分。最底部漸變色背景用一個(gè)contanier,無須指定位置,全視圖擴(kuò)展;載放logo圖標(biāo)在上一層,用Image。最后兩個(gè)Text同級放在最上層。Image,Text各用Positioned包裹去指定位置。
登錄內(nèi)容模塊是最外層是一個(gè)Contanier容器,去控制背景色和圓角。然后是一個(gè)Column元素,逐行排列。
第一行為Image,
第二行為Text,
第三行可以看成一個(gè)小Column,分兩塊進(jìn)行布局
第四行可以看成一個(gè)小Column,分兩塊進(jìn)行布局
第五行可以看作一個(gè)TextButton,
第六行可以看作一個(gè)Row,分三塊進(jìn)行布局
通過上面這樣一步一步的分析后,基本上對大致的布局有了一個(gè)了解,最外層的控件大致選對(只要能實(shí)現(xiàn)的話,就是復(fù)雜度以及效率的問題),然后一步一步的拆解每一行的元素,如果有重復(fù)的或者覺得可以封裝出來的部分,則進(jìn)行下一步。
每一行的拆解,大致也是按照這個(gè)思路來進(jìn)行,因此筆者在這里就不做講解了。
在做到第三第四行的時(shí)候,發(fā)現(xiàn)這兩個(gè)很相似,而且設(shè)計(jì)到一些交互邏輯,筆者就想對第三第四行的這種展示進(jìn)行封裝,覺得今后的布局可能會(huì)用到,因此在這一步,可以先把這一塊兒抽離出一個(gè)控件。利用TextField來實(shí)現(xiàn)這種輸入操作,具體的實(shí)現(xiàn)筆者不再詳細(xì)的描述了。
經(jīng)過這一步,整體的規(guī)劃設(shè)計(jì)圖已經(jīng)有了,各個(gè)組件也都有了,接下來的工作就是組裝了。
具體布局設(shè)計(jì)到一些細(xì)節(jié)的地方,例如整體Column的居中對齊(crossAxisAlignment)、間隔(Padding或Container包裹,筆者更喜歡用SizedBox占位)、居左居右居中(Align)、點(diǎn)擊事件(GestureDetector)以及圓角(BorderRadius)等一些特殊情況。
像第六行row是放在底部的,就可以在第六行前面增加一個(gè)Spacer()去填充空白區(qū)域。
對文字顏色大小等,可以用TextStyle直接設(shè)置。
對于輸入框的刪除按鈕,可以用Offstage這種Flutter特有的控制顯示隱藏的控件。
此控件比較簡單,按鈕的功能可劃分為UI樣式與事件回調(diào)
這里將幾種不同的按鈕一起運(yùn)行,做下對比動(dòng)圖如下:
這里對五種按鈕進(jìn)行column居中排列如下
Text用于顯示簡單樣式文本,它包含一些控制文本顯示樣式的一些屬性。
TextStyle用于指定文本顯示的樣式如顏色、字體、粗細(xì)、背景等。
TextStyle更多屬性設(shè)置如下:
如果我們需要對一個(gè)Text內(nèi)容的不同部分按照不同的樣式顯示,即富文本,這時(shí)就可以使用TextSpan,它代表文本的一個(gè)“片段”。
如上述,我們當(dāng)然也可以在上述鏈接上添加手勢事件,后續(xù)會(huì)提到。
在widget樹中,文本的樣式默認(rèn)是可以被繼承的,因此,如果在widget樹的某一個(gè)節(jié)點(diǎn)處設(shè)置一個(gè)默認(rèn)的文本樣式,那么該節(jié)點(diǎn)的子樹中所有文本都會(huì)默認(rèn)使用這個(gè)樣式,而DefaultTextStyle正是用于設(shè)置默認(rèn)文本樣式的。
舉例如下: