您好,登錄后才能下訂單哦!
這篇文章主要介紹“怎么使用Android Flutter實現創意時鐘”,在日常操作中,相信很多人在怎么使用Android Flutter實現創意時鐘問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”怎么使用Android Flutter實現創意時鐘”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
本案例使用的環境是:
Flutter (Channel stable, 2.2.3, on macOS 11.0.1 20B29 darwin-arm, locale zh-Hans-CN)
• Flutter version 2.2.3 at /Users/moon/Documents/sdk/flutter
• Framework revision f4abaa0735 (2 months ago), 2021-07-01 12:46:11 -0700
• Engine revision 241c87ad80
• Dart version 2.13.4
• Pub download mirror https://pub.flutter-io.cn
• Flutter download mirror https://storage.flutter-io.cn
一個最普通的Container 里包含一個text
_Number() { return Container( width: 40, height: 40, child: Text( "5", style: TextStyle(color: Colors.white, fontSize: 16), ), ); }
通過看上邊的gif圖就能設計出來,小格子是有狀態的,是當前的時間點數字的話背景色改變,同時也可以讓這個數字的字體變大一點,區別于其他數字,而且他會在所在的列里位于屏幕的中部。 所以先簡單封裝下這個小格子。
_Number(int number, bool isActive) { var backgroundColor; var numberSize; if (isActive) { backgroundColor = Colors.black; numberSize = 18.0; } else { backgroundColor = Colors.deepPurpleAccent; numberSize = 16.0; } return Container( alignment: Alignment.center, width: _normalSize, height: _normalSize, child: Text( "$number", style: TextStyle(color: Colors.white, fontSize: numberSize), ), );
既然是幾列數字條構成的一個時鐘,所以想下大概是繪制出一條就可以了,其他的幾個傳不同的數字和狀態就可以, Compose里用column,Flutter里同樣有這個東西,當然用listview 或其他的容器都可以。
child: Column( children: [ _Number(1 , false,), _Number(2 , false,), _Number(3 , false,), _Number(4 , false,), _Number(5 , true,), ], ))
為了美觀可以切個圓角,這點compose的modifier就體現出了優勢, 可以直接clip column,但Flutter卻沒那么強大,只能根據位置對每個小格子單獨處理了。
if (number == 0) { borderRadius = BorderRadius.only( topLeft: Radius.circular(15), topRight: Radius.circular(15)); } else if (number == (totalSize - 1)) { borderRadius = BorderRadius.only( bottomLeft: Radius.circular(15), bottomRight: Radius.circular(15)); } else { borderRadius = BorderRadius.all(Radius.zero); }
decoration: BoxDecoration( color: backgroundColor, borderRadius: borderRadius, ),
或許還有其簡單方式設置邊角,請朋友提示。
同理搞出六列格子,代表雙位的時分秒,可以用row 包裹六個 column ,設置外層container的子widget都居中,接受當前時間作為狀態,突出顯示就可以了。 比如現在是21:49:15
這樣就畫出了一個單獨的靜態時間刻度。
這個圖好像不太對,一種亂糟糟的感覺,需要能一眼看出當前時間才行,即把所有時間對齊在一條線上。
這方面Compose 發揮了優勢, modifier的 offset 可以輕松實現位移。
val mid = (range.last - range.first) / 2f val offset = 40.dp * (mid - current) Modifier .offset(y = offset)
flutter 里貌似沒這么方便了,怎么實現呢,我使用了Align組件,簡單說明下, 以下摘自官方。
Align
組件可以調整子組件的位置,并且可以根據子組件的寬高來確定自身的的寬高,定義如下:
Align({ Key key, this.alignment = Alignment.center, this.widthFactor, this.heightFactor, Widget child, })
alignment
: 需要一個AlignmentGeometry
類型的值,表示子組件在父組件中的起始位置。AlignmentGeometry
是一個抽象類,它有兩個常用的子類:Alignment
和 FractionalOffset
。
widthFactor
和heightFactor
是用于確定Align
組件本身寬高的屬性;它們是兩個縮放因子,會分別乘以子元素的寬、高,最終的結果就是Align
組件的寬高。如果值為null
,則組件的寬高將會占用盡可能多的空間。
舉例如下
Container( height: 120.0, width: 120.0, color: Colors.blue[50], child: Align( alignment: Alignment.topRight, child: FlutterLogo( size: 60, ), ), )
我顯式指定了Container
的寬、高都為120。如果我不顯式指定寬高,而通過同時指定widthFactor
和heightFactor
為2也是可以達到同樣的效果:
Align( widthFactor: 2, heightFactor: 2, alignment: Alignment.topRight, child: FlutterLogo( size: 60, ), ),
分析,Align實際上就是把原高度擴大為之前的 heightFactor 倍數,而它的子widget仍然處于Align的頂部,而當前時間點位于column頂部的距離是已知的,所以要讓當前時間點的數字定位于 Align的中間 ,需要補齊(或截掉)當前時間點的格子下邊的空間。 為了示意明確,我給總體背景和 Align 背景都加了顏色。
第一列: 小時首位,只有三個格子, 當前是2, 2位于第三個,所以需要給下邊補齊兩個格子, 第二列:小時的末位,共有10個格子,當前數字也是2 ,也位于第三個,為了讓上下相等,需要截掉4以下的數字,讓2位于中間位置。
以此類推。
這下就可以發現規律了。 高度的系數因子為 :
(current * 2 + 1)/numbers.length
numbers.length 是列的長度。 因此, 每列的函數可以寫為
_columnNumber(List<int> numbers, int current) { List<Widget> list = []; numbers.forEach((e) { list.add(_Number(e, e == current, numbers.length)); }); return Container( color: Colors.white, child: Align( alignment: Alignment.topCenter, widthFactor: 1, heightFactor: (current *2 + 1)/numbers.length, child: Container( height: numbers.length * _normalSize, margin: EdgeInsets.only(left: 5, right: 5), child: Column( children: list, )), ), ); }
到此,關于“怎么使用Android Flutter實現創意時鐘”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。