Android 開發者的 Flutter 框架:如何在 Flutter 中設計 LinearLayout?
Marvin Ronsdorf 在 Unsplash 上拍攝的照片。
這個部落格是面向 Android 開發人員的,旨在將他們現有的 Android 知識應用於使用 Flutter 構建移動應用程式。在這篇部落格中,我們將探索 Flutter 中 LinearLayout 的等效設計部件。
系列
-
如何在 Flutter 中設計 LinearLayout? (就在這裡)
先決條件
這篇部落格已假設您已經在 PC 中配置了 flutter,並且能夠執行 Hello World 應用程式。如果您尚未安裝 flutter,請點選這裡。
Dart 基於物件導向的概念,因此作為 android java 開發人員,您將能夠輕鬆地掌握 dart。
讓我們開始吧
如果您是 Android 開發人員,那麼我假設您在設計佈局時大量使用了 LinearLayout。對於那些不熟悉 LinearLayout 的人,我會給出官方定義。
LinearLayout 是一種佈局,可以將其它檢視水平排列在單個列中,也可以垂直排列在單個行中。
上面的效果展示和定義本身是一樣的,您可以確定 Flutter 中的等效小部件是什麼。是的,你是對的,它們是行列。
注意:“行/列”小部件不會滾動。如果您有一系列小部件並希望它們能夠在沒有足夠空間的情況下滾動,請考慮使用 ListView。
現在我們將介紹 LinearLayout 的一些主要屬性,它們可以轉換為 Flutter 中的等效小部件屬性。
1. 方向
在 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?
2. "match_parent" vs "wrap_content"
-
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 小部件中使用的屬性。
3. 權重
權重指定了在它自身的範圍內子 view 如何擺放位置,我們使用具有多個對齊值的 android:gravity ="center"
在 LinearLayout 佈局中定義預設權重。在使用 MainAxisAlignment
和 CrossAxisAlignment
屬性的 Row/Column 小部件中可以實現相同的功能。
1. 主軸對齊:
這個屬性定義了子 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 中使用的垂直/水平鏈相同。
2. 交叉軸對齊 :
這個屬性定義了子 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
。
3. 佈局權重
要建立一個線性佈局,其中每個子 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、前端、後端、區塊鏈、產品、設計、人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。