Marvin Ronsdorf 在 Unsplash 上拍攝的照片。html
這個博客是面向 Android 開發人員的,旨在將他們現有的 Android 知識應用於使用 Flutter 構建移動應用程序。在這篇博客中,咱們將探索 Flutter 中 LinearLayout 的等效設計部件。前端
如何在 Flutter 中設計 LinearLayout? (就在這裏)android
這篇博客已假設您已經在 PC 中配置了 flutter,而且可以運行 Hello World 應用程序。若是您還沒有安裝 flutter,請點擊這裏。ios
Dart 基於面向對象的概念,所以做爲 android java 開發人員,您將可以輕鬆地掌握 dart。git
若是您是 Android 開發人員,那麼我假設您在設計佈局時大量使用了 LinearLayout。對於那些不熟悉 LinearLayout 的人,我會給出官方定義。github
LinearLayout 是一種佈局,能夠將其它視圖水平排列在單個列中,也能夠垂直排列在單個行中。後端
上面的效果展現和定義自己是同樣的,您能夠肯定 Flutter 中的等效小部件是什麼。是的,你是對的,它們是行列。bash
注意:「行/列」小部件不會滾動。若是您有一系列小部件並但願它們可以在沒有足夠空間的狀況下滾動,請考慮使用 ListView。app
如今咱們將介紹 LinearLayout 的一些主要屬性,它們能夠轉換爲 Flutter 中的等效小部件屬性。
在 LinearLayout 中,您可使用 android:orientation ="horizontal" 屬性定義其子項的方向,該屬性將水平/垂直做爲與 Flutter 中的行/列小部件相似的值。
在 Android 中,LinearLayout 是 ViewGroup,能夠向裏面添加子 View。您能夠在 </ LinearLayout> 標籤內設置全部子 View。所以,爲了在咱們的 Row/Column 小部件中設置子小部件,咱們須要使用 Row/Column.children 屬性,該屬性接受 List。請參閱下面的代碼片斷。
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: new Text("LinearLayout Example"),
),
body: new Container(
color: Colors.yellowAccent,
child: new Row(
children: [
new Icon(
Icons.access_time,
size: 50.0,
),
new Icon(
Icons.pie_chart,
size: 100.0,
),
new Icon(
Icons.email,
size: 50.0,
)
],
),
),
),
);
}
}
複製代碼
在這個例子中,咱們使用了 LinearLayout 的 android:orientation ="horizontal" 屬性的 Row 小部件。咱們使用 Column 做爲垂直值。若是你想知道 Scaffold 在這裏作什麼,你能夠閱讀我以前的文章如何在 Flutter 中使用 Scaffold 設計 activity UI?
MATCH_PARENT: 這意味着視圖但願與其父視圖同樣大,若是您的視圖是頂級根視圖,那麼它將與設備屏幕同樣大。
WRAP_CONTENT: 這意味着該視圖要足夠大以包含其內容。
爲了得到 match_parent
和 wrap_content
的行爲,咱們須要在 Row/Column 小部件中使用 mainAxisSize
屬性,mainAxisSize
屬性採用 MainAxisSize 枚舉,其中有兩個值,即 MainAxisSize.min
和 MainAxisSize.max
,的行爲對應 wrap_content
和 match_parent
。
在上面的例子中,咱們沒有爲 Row 部件定義任何 mainAxisSize 屬性,因此默認狀況下它的 mainAxisSize 屬性設置爲 MainAxisSize.max
,它是 match_parent
。容器的黃色背景表明了自由空間的覆蓋方式。這就是咱們在上面的例子中定義這個屬性的方法,並檢查具備不一樣屬性值的輸出。
....
body: new Container(
color: Colors.yellowAccent,
child: new Row(
mainAxisSize: MainAxisSize.min,
children: [...],
),
)
...
複製代碼
這就是咱們如何在視覺上區分 Row/Column 小部件中使用的屬性。
權重指定了在它自身的範圍內子 view 如何擺放位置,咱們使用具備多個對齊值的 android:gravity ="center"
在 LinearLayout 佈局中定義默認權重。在使用 MainAxisAlignment
和 CrossAxisAlignment
屬性的 Row/Column 小部件中能夠實現相同的功能。
這個屬性定義了子 view 應該如何沿着主軸(行/列)放置。爲了使這個有效,若是將值設置爲 MainAxisSize.min
,則應在 Row/Column 小部件中提供一些空間,即因爲沒有可用空間,wrap_content
設置 MainAxisAlignment 對小部件沒有任何影響。
....
body: new Container(
color: Colors.yellowAccent,
child: new Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [...],
),
)
...
複製代碼
一張圖片賽過千言萬語,我更喜歡視覺展現而不是描述每個屬性。
所以在此輸出的狀況下將 LinearLayout 屬性與 Row Widget 中的 MainAxisAlignment 屬性進行比較。
如今,讓咱們將它與列控件進行比較。
練習:您能夠嘗試其它枚舉值,即
spaceEvenly
,spaceAround
,spaceBetween
,其行爲與咱們在 ConstraintLayout 中使用的垂直/水平鏈相同。
這個屬性定義了子 view 應該如何沿橫軸放置。這意味着若是咱們使用 Row 小部件,則子 view 的權重將基於垂直線。若是咱們使用 Column 小部件,那麼子 view 將以水平線爲基準。
這聽起來很混亂吧!不要擔憂,隨着閱讀的進一步深刻,你會理解得更透徹。
爲了更好地理解,咱們使它成爲 wrap_content
,即 MainAxisSize.min
。你能夠像下面的代碼同樣定義一個 CrossAxisAlignment. start
屬性。
....
body: new Container(
color: Colors.yellowAccent,
child: new Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [...],
),
)
...
複製代碼
所以,在此下面輸出將 LinearLayout 屬性與 Row Widget 中的 CrossAxisAlignment 屬性進行比較。
如今,讓咱們將它與列控件進行比較。
拉伸行爲有點不一樣,它將小部件伸展到最大可用空間,即與其交叉軸 match_parent
。
要建立一個線性佈局,其中每一個子 view 使用相同的空間或在屏幕上以特定比例劃分空間,咱們將每一個視圖的 android:layout_height
設置爲 "0dp"
(對於垂直佈局)或將每一個視圖的 android:layout_width
設置爲 "0dp"
(對於水平佈局)。而後將每一個視圖的 android:layout_weight
設置爲 "1"
或根據要劃分的空間設置其它任何值。
爲了在 flutter Row/Column 小部件中實現一樣的功能,咱們將每一個子 view 包裝到一個 Expanded
小部件中,該小部件的 flex 屬性等同於咱們的 android:layout_weight
,所以經過定義 flex 值咱們定義該應用特定子元素的空間量。
這就是你如何爲每一個孩子定義權重/彈性。
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: new Text("LinearLayout Example"),
),
body: new Container(
color: Colors.yellowAccent,
child: new Container(
child: new Row(
children: [
new Expanded(
child: new Container(
child: new Icon(
Icons.access_time,
size: 50.0,
),
color: Colors.red,
),
flex: 2,
),
new Expanded(
child: new Container(
child: new Icon(
Icons.pie_chart,
size: 100.0,
),
color: Colors.blue,
),
flex: 4,
),
new Expanded(
child: new Container(
child: new Icon(
Icons.email,
size: 50.0,
),
color: Colors.green,
),
flex: 6,
),
],
),
),
),
),
);
}
}
複製代碼
爲了更好地理解,咱們將每一個圖標包裝在具備背景顏色的容器中,以便輕鬆識別窗口小部件已覆蓋的空間。
LinearLayout 在 Android 中大量使用,與 Row/Column 小部件相同。但願在即將到來的博客中涵蓋更多主題。我已經建立了一個示例應用程序來演示 Row/Column 屬性以及這些屬性在組合時如何工做。
看看這裏的 android 例子。
burhanrashid52 / FlutterForAndroidExample:經過在GitHub上建立一個賬戶,爲 FlutterForAndroidExample 開發作出貢獻。
謝謝 !!!
若是您以爲這篇文章有幫助。請收藏,分享和拍手,這樣其餘人會在中看到這一點。若是您有任何問題或建議,請在博客上自由發表評論,或在 Twitter,Github 或 Reddit 上給我點贊。
要獲取我即將發佈的博客的最新更新,請在 Medium,Twitter,Github 或Reddit 上關注我。
若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。
掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。