本文,從最簡單的例子開始笨忌,然后就是經常一起出現(xiàn)的MaterialApp蓝仲、Scaffold,最后具有繪制官疲、定位袱结、調整大小功能的Container。
一途凫、一個最簡單的實例
一個簡單的添加控件的例子
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
void main() {
runApp(
Center(
child: Text(
'Hello, world!',
textDirection: TextDirection.ltr,
),
),
);
}
是啊垢夹,一個HelloWorld居中了。
Center就是居中效果
效果圖
再维费,簡單一點點
不帶居中了果元,textDirection: TextDirection.ltr,
需要設定下。不然報錯犀盟、大概就是靠做的意思而晒。l是left的縮寫。
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
void main() {
runApp(
Text("普通文本",
textDirection: TextDirection.ltr,
)
);
}
核心點
.
.
.
二、MaterialApp 組件
Flutter的wdiget里,MaterialApp 代表使用(Material Design)風格的應用监署。里面包含了紙墨設計風格應用所需要的基本控件颤专。
其實,這個第二大點钠乏,內容稍微有點長栖秕,簡單來說,就是大概說了MaterialApp和Scaffold晓避。要是覺得太長簇捍,完全是可以直接看第三大點的。
二.1够滑、MaterialApp 簡單例子
先來看看大概的 MaterialApp 示例代碼
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
title: 'Flutter Tutorial',
home: TutorialHome(),
));
}
class TutorialHome extends StatelessWidget {
@override
Widget build(BuildContext context) {
// Scaffold is a layout for the major Material Components.
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.menu),
tooltip: 'Navigation menu',
onPressed: null,
),
title: Text('Example title'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.search),
tooltip: 'Search',
onPressed: null,
),
],
),
// body is the majority of the screen.
body: Center(
child: Text('Hello, world!'),
),
floatingActionButton: FloatingActionButton(
tooltip: 'Add', // used by assistive technologies
child: Icon(Icons.add),
onPressed: null,
),
);
}
}
代碼來源: https://flutter-io.cn/docs/development/ui/widgets-intro
突然冒出很多新東西
StatelessWidget是什么轻姿?Scaffold是什么穿铆?floatingActionButton干嘛的?
沒關系塞绿,忽略忽略命辖,先來看看MaterialApp有什么屬性况毅。
效果圖
核心結構
二.2、MaterialApp 屬性如下
主要屬性
-
title
: 在任務管理窗口中所顯示的應用名字 -
theme
: 應用各種 UI 所使用的主題顏色 -
color
: 應用的主要顏色值(primary color)尔艇,也就是安卓任務管理窗口中所顯示的應用顏色 -
home
: 應用默認所顯示的界面 Widget -
routes
: 應用的頂級導航表格尔许,這個是多頁面應用用來控制頁面跳轉的,類似于網頁的網址 -
initialRoute
:第一個顯示的路由名字终娃,默認值為 Window.defaultRouteName -
onGenerateRoute
: 生成路由的回調函數(shù)味廊,當導航的命名路由的時候,會使用這個來生成界面 -
onLocaleChanged
: 當系統(tǒng)修改語言的時候棠耕,會觸發(fā)?這個回調 -
navigatorObservers
: 應用 Navigator 的監(jiān)聽器 -
debugShowMaterialGrid
: 是否顯示 紙墨設計 基礎布局網格余佛,用來調試 UI 的工具 -
showPerformanceOverlay
: 顯示性能標簽,https://flutter.io/debugging/#performanceoverlay -
checkerboardRasterCacheImages 窍荧、showSemanticsDebugger辉巡、debugShowCheckedModeBanner
各種調試開關
全部屬性
字段 | 類型 |
---|---|
navigatorKey | (導航鍵) GlobalKey<NavigatorState> |
home(主頁) | Widget |
routes(路由) | Map<String, WidgetBuilder> |
initialRoute(初始路由) | String |
onGenerateRoute(生成路由) | RouteFactory |
onUnknownRoute(未知路由) | RouteFactory |
navigatorObservers(導航觀察器) | List<NavigatorObserver> |
builder(建造者) | TransitionBuilder |
title(標題) | String |
onGenerateTitle(生成標題) | GenerateAppTitle |
color(顏色) | Color |
theme(主題) | ThemeData |
locale(地點) | Locale |
localizationsDelegates(本地化委托) | Iterable<LocalizationsDelegate<dynamic>> |
localeResolutionCallback(區(qū)域分辨回調) | LocaleResolutionCallback |
supportedLocales(支持區(qū)域) | Iterable<Locale> |
debugShowMaterialGrid(調試顯示材質網格) | bool |
showPerformanceOverlay(顯示性能疊加) | bool |
checkerboardRasterCacheImages(棋盤格光柵緩存圖像) | bool |
checkerboardOffscreenLayers(棋盤格層) | bool |
showSemanticsDebugger(顯示語義調試器) | bool |
debugShowCheckedModeBanner(調試顯示檢查模式橫幅) | bool |
.
.
1. navigatorKey
navigatorKey.currentState
相當于
Navigator.of(context)
使用
GlobalKey<NavigatorState> _navigatorKey=new GlobalKey();
new MaterialApp(
navigatorKey: _navigatorKey,
);
2. home
進入程序后顯示的第一個頁面,傳入的是一個Widget,但實際上這個Widget需要包裹一個Scaffold以顯示該程序使用Material Design風格
使用
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new MyHomePage(),
);
}
}
//這是一個可改變的Widget
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: Text('Title'),
),
body: Center(
child: Text('Home'),
),
);
}
}
3. routes
聲明程序中有哪個通過Navigation.of(context).pushNamed跳轉的路由
參數(shù)以鍵值對的形式傳遞
key:路由名字
value:對應的Widget
使用
new MaterialApp(
routes: {
'/home':(BuildContext context) => HomePage(),
'/home/one':(BuildContext context) => OnePage(),
//....
},
);
4 . initialRoute
初始路由蕊退,當用戶進入程序時郊楣,自動打開對應的路由。
(home還是位于一級)
傳入的是上面routes的key
跳轉的是對應的Widget(如果該Widget有Scaffold.AppBar,并不做任何修改瓤荔,左上角有返回鍵)
使用
new MaterialApp(
routes: {
'/home':(BuildContext context) => HomePage(),
'/home/one':(BuildContext context) => OnePage(),
//....
},
initialRoute: '/home/one',
);
5 . onGenerateRoute
當通過Navigation.of(context).pushNamed跳轉路由時净蚤,
在routes查找不到時,會調用該方法
使用
new MaterialApp(
routes: {
'/home':(BuildContext context) => HomePage(),
'/home/one':(BuildContext context) => OnePage(),
//....
},
onGenerateRoute: (setting){
//setting.isInitialRoute; bool類型 是否初始路由
//setting.name; 要跳轉的路由名key
return new PageRouteBuilder(
pageBuilder: (BuildContext context, _, __) {
//這里為返回的Widget
return HomePage();
},
opaque: false,
//跳轉動畫
transitionDuration: new Duration(milliseconds: 200),
transitionsBuilder:
(___, Animation<double> animation, ____, Widget child) {
return new FadeTransition(
opacity: animation,
child: new ScaleTransition(
scale: new Tween<double>(begin: 0.5, end: 1.0)
.animate(animation),
child: child,
),
);
});
}
);
6 . onUnknownRoute
效果跟onGenerateRoute一樣
調用順序為onGenerateRoute ==> onUnknownRoute
7 . navigatorObservers
路由觀察器输硝,當調用Navigator的相關方法時今瀑,會回調相關的操作
使用
new MaterialApp(
navigatorObservers: [
MyObserver(),
],
);
//繼承NavigatorObserver
class MyObserver extends NavigatorObserver{
@override
void didPush(Route route, Route previousRoute) {
// 當調用Navigator.push時回調
super.didPush(route, previousRoute);
//可通過route.settings獲取路由相關內容
//route.currentResult獲取返回內容
//....等等
print(route.settings.name);
}
}
8 . builder
當構建一個Widget前調用
一般做字體大小,方向,主題顏色等配置
使用
new MaterialApp(
builder: (BuildContext context, Widget child) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
//字體大小
textScaleFactor: 1.4,
),
child: child,
);
},
);
9 . title
該標題出現(xiàn)在
Android:任務管理器的程序快照之上
IOS: 程序切換管理器中
使用
new MaterialApp(
title: 'Flutter應用',
);
10 . onGenerateTitle
跟上面的tiitle一樣放椰,但含有一個context參數(shù)
用于做本地化
new MaterialApp(
onGenerateTitle: (context){
return 'Flutter應用';
},
);
11 . color
該顏色為Android中程序切換中應用圖標背景的顏色作烟,當應用圖標背景為透明時
使用
new MaterialApp(
color: Colors.blue,
)
12 . theme
應用程序的主題,各種的定制顏色都可以設置砾医,用于程序主題切換
使用
new MaterialApp(
theme: new ThemeData(
//主題色
primarySwatch: Colors.blue,
),
);
13 . locale
當前區(qū)域拿撩,如果為null則使用系統(tǒng)區(qū)域
一般用于語言切換
使用
//傳入兩個參數(shù),語言代碼如蚜,國家代碼
new MaterialApp(
Locale('yy','zh')压恒,
);
//源碼糾正,一些曾經用過的代碼(注釋后面的日期為不再使用的日期)错邦,源碼會自動糾正
//來看一下源碼
//languageCode 第一個參數(shù)
switch (languageCode) {
case 'in': return 'id'; // Indonesian; deprecated 1989-01-01
case 'iw': return 'he'; // Hebrew; deprecated 1989-01-01
case 'ji': return 'yi'; // Yiddish; deprecated 1989-01-01
case 'jw': return 'jv'; // Javanese; deprecated 2001-08-13
case 'mo': return 'ro'; // Moldavian, Moldovan; deprecated 2008-11-22
case 'aam': return 'aas'; // Aramanik; deprecated 2015-02-12
case 'adp': return 'dz'; // Adap; deprecated 2015-02-12
case 'aue': return 'ktz'; // =/Kx'au//'ein; deprecated 2015-02-12
case 'ayx': return 'nun'; // Ayi (China); deprecated 2011-08-16
case 'bgm': return 'bcg'; // Baga Mboteni; deprecated 2016-05-30
case 'bjd': return 'drl'; // Bandjigali; deprecated 2012-08-12
case 'ccq': return 'rki'; // Chaungtha; deprecated 2012-08-12
case 'cjr': return 'mom'; // Chorotega; deprecated 2010-03-11
case 'cka': return 'cmr'; // Khumi Awa Chin; deprecated 2012-08-12
case 'cmk': return 'xch'; // Chimakum; deprecated 2010-03-11
case 'coy': return 'pij'; // Coyaima; deprecated 2016-05-30
case 'cqu': return 'quh'; // Chilean Quechua; deprecated 2016-05-30
case 'drh': return 'khk'; // Darkhat; deprecated 2010-03-11
case 'drw': return 'prs'; // Darwazi; deprecated 2010-03-11
case 'gav': return 'dev'; // Gabutamon; deprecated 2010-03-11
case 'gfx': return 'vaj'; // Mangetti Dune !Xung; deprecated 2015-02-12
case 'ggn': return 'gvr'; // Eastern Gurung; deprecated 2016-05-30
case 'gti': return 'nyc'; // Gbati-ri; deprecated 2015-02-12
case 'guv': return 'duz'; // Gey; deprecated 2016-05-30
case 'hrr': return 'jal'; // Horuru; deprecated 2012-08-12
case 'ibi': return 'opa'; // Ibilo; deprecated 2012-08-12
case 'ilw': return 'gal'; // Talur; deprecated 2013-09-10
case 'jeg': return 'oyb'; // Jeng; deprecated 2017-02-23
case 'kgc': return 'tdf'; // Kasseng; deprecated 2016-05-30
case 'kgh': return 'kml'; // Upper Tanudan Kalinga; deprecated 2012-08-12
case 'koj': return 'kwv'; // Sara Dunjo; deprecated 2015-02-12
case 'krm': return 'bmf'; // Krim; deprecated 2017-02-23
case 'ktr': return 'dtp'; // Kota Marudu Tinagas; deprecated 2016-05-30
case 'kvs': return 'gdj'; // Kunggara; deprecated 2016-05-30
case 'kwq': return 'yam'; // Kwak; deprecated 2015-02-12
case 'kxe': return 'tvd'; // Kakihum; deprecated 2015-02-12
case 'kzj': return 'dtp'; // Coastal Kadazan; deprecated 2016-05-30
case 'kzt': return 'dtp'; // Tambunan Dusun; deprecated 2016-05-30
case 'lii': return 'raq'; // Lingkhim; deprecated 2015-02-12
case 'lmm': return 'rmx'; // Lamam; deprecated 2014-02-28
case 'meg': return 'cir'; // Mea; deprecated 2013-09-10
case 'mst': return 'mry'; // Cataelano Mandaya; deprecated 2010-03-11
case 'mwj': return 'vaj'; // Maligo; deprecated 2015-02-12
case 'myt': return 'mry'; // Sangab Mandaya; deprecated 2010-03-11
case 'nad': return 'xny'; // Nijadali; deprecated 2016-05-30
case 'nnx': return 'ngv'; // Ngong; deprecated 2015-02-12
case 'nts': return 'pij'; // Natagaimas; deprecated 2016-05-30
case 'oun': return 'vaj'; // !O!ung; deprecated 2015-02-12
case 'pcr': return 'adx'; // Panang; deprecated 2013-09-10
case 'pmc': return 'huw'; // Palumata; deprecated 2016-05-30
case 'pmu': return 'phr'; // Mirpur Panjabi; deprecated 2015-02-12
case 'ppa': return 'bfy'; // Pao; deprecated 2016-05-30
case 'ppr': return 'lcq'; // Piru; deprecated 2013-09-10
case 'pry': return 'prt'; // Pray 3; deprecated 2016-05-30
case 'puz': return 'pub'; // Purum Naga; deprecated 2014-02-28
case 'sca': return 'hle'; // Sansu; deprecated 2012-08-12
case 'skk': return 'oyb'; // Sok; deprecated 2017-02-23
case 'tdu': return 'dtp'; // Tempasuk Dusun; deprecated 2016-05-30
case 'thc': return 'tpo'; // Tai Hang Tong; deprecated 2016-05-30
case 'thx': return 'oyb'; // The; deprecated 2015-02-12
case 'tie': return 'ras'; // Tingal; deprecated 2011-08-16
case 'tkk': return 'twm'; // Takpa; deprecated 2011-08-16
case 'tlw': return 'weo'; // South Wemale; deprecated 2012-08-12
case 'tmp': return 'tyj'; // Tai Mène; deprecated 2016-05-30
case 'tne': return 'kak'; // Tinoc Kallahan; deprecated 2016-05-30
case 'tnf': return 'prs'; // Tangshewi; deprecated 2010-03-11
case 'tsf': return 'taj'; // Southwestern Tamang; deprecated 2015-02-12
case 'uok': return 'ema'; // Uokha; deprecated 2015-02-12
case 'xba': return 'cax'; // Kamba (Brazil); deprecated 2016-05-30
case 'xia': return 'acn'; // Xiandao; deprecated 2013-09-10
case 'xkh': return 'waw'; // Karahawyana; deprecated 2016-05-30
case 'xsj': return 'suj'; // Subi; deprecated 2015-02-12
case 'ybd': return 'rki'; // Yangbye; deprecated 2012-08-12
case 'yma': return 'lrr'; // Yamphe; deprecated 2012-08-12
case 'ymt': return 'mtm'; // Mator-Taygi-Karagas; deprecated 2015-02-12
case 'yos': return 'zom'; // Yos; deprecated 2013-09-10
case 'yuu': return 'yug'; // Yugh; deprecated 2014-02-28
default: return languageCode;
}
//_countryCode 第二個參數(shù)
switch (_countryCode) {
case 'BU': return 'MM'; // Burma; deprecated 1989-12-05
case 'DD': return 'DE'; // German Democratic Republic; deprecated 1990-10-30
case 'FX': return 'FR'; // Metropolitan France; deprecated 1997-07-14
case 'TP': return 'TL'; // East Timor; deprecated 2002-05-20
case 'YD': return 'YE'; // Democratic Yemen; deprecated 1990-08-14
case 'ZR': return 'CD'; // Zaire; deprecated 1997-07-14
default: return regionCode;
}
14 . localizationsDelegates
本地化委托探赫,用于更改Flutter Widget默認的提示語,按鈕text等
使用
new MaterialApp(
localizationsDelegates: [
MyLocalizationsDelegates(),
],
locale: Locale('zh','cn'),
);
class MyLocalizationsDelegates extends LocalizationsDelegate
<MaterialLocalizations>{
@override
bool isSupported(Locale locale) {
//是否支持該locale撬呢,如果不支持會報異常
if(locale == const Locale('zh','cn')){
return true;
}
return false;
}
@override//是否需要重載
bool shouldReload(LocalizationsDelegate old) => false;
@override
Future<MaterialLocalizations> load(Locale locale) {
//加載本地化
return new SynchronousFuture(new MyLocalizations(locale));
}
}
//本地化實現(xiàn)伦吠,繼承DefaultMaterialLocalizations
class MyLocalizations extends DefaultMaterialLocalizations{
final Locale locale;
MyLocalizations(this.locale, );
@override
String get okButtonLabel {
if(locale == const Locale('zh','cn')){
return '好的';
}else{
return super.okButtonLabel;
}
}
@override
String get backButtonTooltip {
if(locale == const Locale('zh','cn')){
return '返回';
}else{
return super.okButtonLabel;
}
}
}
15 . localeResolutionCallback
當傳入的是不支持的語種,可以根據(jù)這個回調魂拦,返回相近,并且支持的語種
使用
new MaterialApp(
localeResolutionCallback: (local,support){
if(support.contains(support)){
print('support');
return local;
}
print('no_support');
return const Locale('us','uk');
},
//這個代碼是隨便填的毛仪,有可能出錯
locale: Locale('ze','cn'),
);
16 . supportedLocales
傳入支持的語種數(shù)組
new MaterialApp(
supportedLocales: [
const Locale('uok'),
const Locale('meg'),
],
);
17 . debugShowMaterialGrid
debug模式下是否顯示材質網格,傳入bool類型芯勘,使用就不寫了
18 . showPerformanceOverlay
當為true時應用程序頂部覆蓋一層GPU和UI曲線圖箱靴,可即時查看當前流暢度情況
19 . checkerboardRasterCacheImages
當為true時,打開光柵緩存圖像的棋盤格
20 . checkerboardOffscreenLayers
當為true時荷愕,打開呈現(xiàn)到屏幕位圖的層的棋盤格
21 . showSemanticsDebugger
當為true時衡怀,打開Widget邊框,類似Android開發(fā)者模式中顯示布局邊界
22 . debugShowCheckedModeBanner
當為true時安疗,在debug模式下顯示右上角的debug字樣的橫幅抛杨,false即為不顯示
看了之后,屬性好多茂契,沒關系關系蝶桶,大概看看就好。
參考:
http://www.reibang.com/p/db27e17ecea0
http://www.reibang.com/p/1d44ae246652
二.3掉冶、Scaffold和MaterialApp更配噢
Scaffold
呢真竖,本身是腳手架的意思。
MaterialApp經常和Scaffold一起搭配使用厌小。
- MaterialApp是一個方便的Widget恢共,它封裝了應用程序實現(xiàn)Material Design所需要的一些Widget。
- Scaffold組件是Material Design布局結構的基本實現(xiàn)璧亚。此類提供了用于顯示drawer讨韭、snackbar和底部sheet的API。
示例一下,再來貼一下代碼透硝,雖然上面以上出現(xiàn)過狰闪。
經常比如這樣子出現(xiàn):
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
title: 'Flutter Tutorial',
home: TutorialHome(),
));
}
class TutorialHome extends StatelessWidget {
@override
Widget build(BuildContext context) {
// Scaffold is a layout for the major Material Components.
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.menu),
tooltip: 'Navigation menu',
onPressed: null,
),
title: Text('Example title'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.search),
tooltip: 'Search',
onPressed: null,
),
],
),
// body is the majority of the screen.
body: Center(
child: Text('Hello, world!'),
),
floatingActionButton: FloatingActionButton(
tooltip: 'Add', // used by assistive technologies
child: Icon(Icons.add),
onPressed: null,
),
);
}
}
.又比如這樣子:
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
title: 'Flutter Tutorial',
home: MyHomePage(),
));
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new MyHomePage(),
);
}
}
//這是一個可改變的Widget
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: Text('Title'),
),
body: Center(
child: Text('Home'),
),
);
}
}
二.3.1、Scaffold 的屬性
屬性 | 說明 |
---|---|
appBar |
顯示在Scaffold 頂部 |
body |
位置如下圖 |
floatingActionButton |
默認右下角的懸浮按鈕 |
floatingActionButtonLocation |
懸浮按鈕位置濒生,默認右下角 |
floatingActionButtonAnimator |
懸浮按鈕位置位置變換動畫 |
persistentFooterButtons |
位置如下圖 |
bottomNavigationBar |
位置如下圖 |
bottomSheet |
位置如下圖 |
————————————————
抽屜效果圖:
參考:
https://blog.csdn.net/mengks1987/article/details/84980059
https://juejin.im/post/5cc174def265da036207adf4
二.3.2埋泵、Scaffold 的 demo
https://juejin.im/post/5cc174def265da036207adf4
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: ScaffoldDemo(),
);
}
}
class ScaffoldDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: _appBar(),
body: _body(),
floatingActionButton: new FloatingActionButton(
tooltip: 'Add', // used by assistive technologies
child: new Icon(Icons.add),
onPressed: null,
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
floatingActionButtonAnimator: FloatingActionButtonAnimator.scaling,
drawer: _drawer(context),
endDrawer: Drawer(child: Text("右抽屜")),
bottomNavigationBar: _BottomNavigationBar(),
);
}
AppBar _appBar() {
return new AppBar(
// 如果有 側邊欄 右邊是默認的事條目,點擊默認打開 左側邊欄罪治。 如果沒有側邊欄丽声,就顯示返回箭頭
title: new Text('Example title'),
actions: <Widget>[
new IconButton(
icon: new Icon(Icons.search),
tooltip: 'Search', // 長按的一個提示
onPressed: null,
),
new IconButton(
icon: new Icon(Icons.access_time),
tooltip: 'time',
onPressed: null,
),
],
);
}
Drawer _drawer(BuildContext context) {
return Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
decoration: BoxDecoration(
color: Colors.lightBlueAccent,
),
child: Center(
child: SizedBox(
width: 60.0,
height: 60.0,
child: CircleAvatar(
child: Text('頭像'),
),
),
),
),
ListTile(
title: Text('Item 1'),
leading: new CircleAvatar(
child: new Icon(Icons.school),
),
onTap: () {
Navigator.pop(context);
},
),
ListTile(
title: Text('Item 2'),
leading: new CircleAvatar(
child: new Text('B2'),
),
onTap: () {
Navigator.pop(context);
},
),
ListTile(
title: Text('Item 3'),
leading: new CircleAvatar(
child: new Icon(Icons.list),
),
onTap: () {
Navigator.pop(context);
},
),
],
),
);
}
Builder _body() {
return Builder(builder: (BuildContext context) {
return Center(
child: Column(
children: <Widget>[
RaisedButton(
child: Text('顯示snackbar (Text 沒有 onPressed 屬性)'),
onPressed: () {
Scaffold.of(context).showSnackBar(SnackBar(
content: Text('我是snackbar'),
));
},
),
RaisedButton(
child: Text('顯示BottomSheet (Text 沒有 onPressed 屬性)'),
onPressed: () {
Scaffold.of(context).showBottomSheet((BuildContext context) {
return ListView(
padding: EdgeInsets.zero,
children: <Widget>[
ListTile(
title: Text('Item 1'),
leading: new CircleAvatar(
child: new Icon(Icons.school),
),
onTap: () {
Navigator.pop(context);
},
),
ListTile(
title: Text('Item 2'),
leading: new CircleAvatar(
child: new Text('B2'),
),
onTap: () {
Navigator.pop(context);
},
),
ListTile(
title: Text('Item 3'),
leading: new CircleAvatar(
child: new Icon(Icons.list),
),
onTap: () {
Navigator.pop(context);
},
),
],
);
});
},
),
],
),
);
});
}
}
// BottomNavigationBar 默認的實例
class _BottomNavigationBar extends StatefulWidget {
const _BottomNavigationBar() : super();
@override
State<StatefulWidget> createState() => _BottomNavigationBarFullDefault();
}
// BottomNavigationBar 默認的實例,有狀態(tài)
class _BottomNavigationBarFullDefault extends State {
int _currentIndex = 1;
void _onItemTapped(int index) {
if(mounted) {
setState(() {
_currentIndex = index;
});
}
}
@override
Widget build(BuildContext context) {
return BottomNavigationBar(
type: BottomNavigationBarType.fixed, // BottomNavigationBarType 中定義的類型,有 fixed 和 shifting 兩種類型
iconSize: 24.0, // BottomNavigationBarItem 中 icon 的大小
currentIndex: _currentIndex, // 當前所高亮的按鈕index
onTap: _onItemTapped, // 點擊里面的按鈕的回調函數(shù)觉义,參數(shù)為當前點擊的按鈕 index
fixedColor: Colors.blue, // 如果 type 類型為 fixed雁社,則通過 fixedColor 設置選中 item 的顏色
items: <BottomNavigationBarItem> [
BottomNavigationBarItem(
title: Text("主頁"), icon: Icon(Icons.home)),
BottomNavigationBarItem(
title: Text("發(fā)現(xiàn)"), icon: Icon(Icons.search)),
BottomNavigationBarItem(
title: Text("我的"), icon: Icon(Icons.image)),
],
);
}
}
另外,附上晒骇,一個不錯的練手項目:https://juejin.im/post/5cde5870f265da1baa1e4284
.
.
.
三霉撵、Container 容器類
Container,本身是容器的意思厉碟。
核心點:
Container具有繪制喊巍、定位、調整大小功能箍鼓。
-
通常用來裝載其它子控件,假如Container沒有子控件呵曹,它將自動填充整個屏幕款咖;反之,會根據(jù)子控件大小奄喂,調整自身大小铐殃,從而達到自適應效果。
- Container只能容納一個子控件跨新,如果想容納更多的子控件,可以將子控件設置為Row富腊、Column、Stack(這三個子控件都有一個children屬性)
使用Container時域帐,通常要有一個父控件赘被,常用的父控件有Center、Padding肖揣、Column民假、Row、Scaffold龙优。
屬性 | 作用 |
---|---|
- Color Property | Container的背景顏色 |
- Child Property | 設置子控件羊异,如果Container里面沒有子控件,它就會填充整個屏幕;如果有子控件野舶,Container就會自動適應子控件大小易迹。 |
- Alignment Property | 控制child的對齊方式,針對于Container內部的子控件布局平道。主要有以下幾個屬性:Alignment睹欲、FractionalOffset、AlignmentDirectional |
- Constraints Property | 添加到child上額外的約束條件巢掺。其中經常使用的就是BoxConstraint句伶。BoxConstraint包含minWidth、maxWidth陆淀、minHeight考余、maxHeight |
- Margin Property | 圍繞在decoration和child之外的空白區(qū)域,不屬于內容區(qū)域轧苫。 |
- Padding Property | decoration內部的空白區(qū)域楚堤,如果有child的話,child位于padding內部含懊。padding與margin的不同之處在于身冬,padding是包含在content內,而margin則是外部邊界岔乔,設置點擊事件的話酥筝,padding區(qū)域會響應,而margin區(qū)域不會響應雏门。 |
- Decoration Property | 繪制在child后面的裝飾嘿歌,設置了decoration的話,就不能設置color屬性茁影,否則會報錯宙帝,此時應該在decoration中進行顏色的設置。 |
- ForegroundDecoration Property | 繪制在child前面的裝飾募闲。 |
- Transform Property | 設置container的變換矩陣步脓,類型為Matrix4。 |
.
.
1浩螺、color
用于設置Container的背景顏色
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Color_Property_Colors(),
);
}
}
//Container顏色屬性之Colors
class Color_Property_Colors extends StatelessWidget{
@override
Widget build(BuildContext context) {
return Center(
child: Container(
//color: Colors.green,//正常顏色
//color:Colors.green[200],//帶有陰影(相當于是透明度)
color: Colors.green.shade200,//同上
),
);
}
}
2靴患、child
如前言所述,如果Container里面沒有子控件年扩,它就會填充整個屏幕蚁廓;如果有子控件,Container就會自動適應子控件大小厨幻。
另外相嵌,Container只能容納一個子控件腿时,如果想容納更多的子控件,可以將子控件設置為Row、Column饭宾、Stack(這三個子控件都有一個children屬性)
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: ChildProperty(),
);
}
}
class ChildProperty extends StatelessWidget{
@override
Widget build(BuildContext context) {
return Center(
child: Container(
color:Color(0xFF00FF00),
child: Text("Flutter 的一個文本"),
),
);
}
}
效果圖
3批糟、alignment
Alignment屬性主要是針對于Container內部的子控件布局。
主要有以下幾個屬性:Alignment看铆、FractionalOffset徽鼎、AlignmentDirectional
Alignment
常用等價屬性:
Alignment.bottomCenter 對應 Alignment(0.0, 1.0)
Alignment.bottomLeft 對應 Alignment(-1.0, 1.0)
Alignment.bottomRight 對應 Alignment(1.0, 1.0)
Alignment.center 對應 Alignment(0.0, 0.0)
Alignment.centerLeft 對應 Alignment(-1.0, 0.0)
Alignment.centerRight 對應 Alignment(1.0, 0.0)
Alignment.topCenter 對應 Alignment(0.0, -1.0)
Alignment.topLeft 對應 Alignment(-1.0, -1.0)
Alignment.topRight 對應 Alignment(1.0, -1.0)
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: new Scaffold(
appBar: AppBar(
title: Text("Alignment測試"),
),
body: AlignmentProperty(),
)
);
}
}
class AlignmentProperty extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
return Center(
child: Container(
color: Color.fromARGB(255, 66, 165, 245),
child: Text("Flutter 的一個文本",
style: TextStyle(
fontSize: 30.0
),
),
//不加這句話,Container會自適應child大小;加上以后會充滿屏幕
//alignment: Alignment(0.0, 0.0),
// 加上以后會充滿屏幕
alignment: Alignment.center,//等價于上面
),
);
}
}
效果圖
如果把alignment: Alignment.center,//等價于上面
備注掉
備注掉的效果
.
.
如果設置成為alignment: Alignment.bottomLeft,
FractionalOffset
常用等價屬性如下
FractionalOffset.bottomCenter 對應 FractionalOffset(0.5, 1.0)
FractionalOffset.bottomLeft 對應 FractionalOffset(0.0, 1.0)
FractionalOffset.bottomRight 對應 FractionalOffset(1.0, 1.0)
FractionalOffset.center 對應 FractionalOffset(0.5, 0.5)
FractionalOffset.centerLeft 對應 FractionalOffset(0.0, 0.5)
FractionalOffset.centerRight 對應 FractionalOffset(1.0, 0.5)
FractionalOffset.topCenter 對應 FractionalOffset(0.5, 0.0)
FractionalOffset.topLeft 對應 FractionalOffset(0.0, 0.0)
FractionalOffset.topRight 對應 FractionalOffset(1.0, 0.0)
對比 坐標系
Alignment坐標系是X:-1.0--1.0;Y:-1.0--1.0弹惦,
FractionalOffset坐標系是X:0.0--1.0否淤,Y:0.0--1.0。
Alignment坐標系圖如下
FractionalOffset坐標系圖如下:
4棠隐、constraints
布局屬性石抡,主要講的是怎么確定控件的大小助泽;其中經常使用的就是BoxConstraint啰扛。BoxConstraint包含minWidth、maxWidth嗡贺、minHeight隐解、maxHeight,詳細介紹如下:
場景一:無子控件
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: new Scaffold(
appBar: AppBar(
title: Text("測試"),
),
body: ConstraintsProperty(),
)
);
}
}
class ConstraintsProperty extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
return new Center(
child: new Container(
color: Color.fromARGB(255, 66, 165, 245),
alignment: AlignmentDirectional(0.0, 0.0),
child: Container(
color: Colors.green,
constraints: BoxConstraints(
maxHeight: 300,
maxWidth: 200,
minWidth: 150,
minHeight: 150,
),
),
),
);
}
}
前面說過如果Container沒有子控件诫睬,Container將填充整個屏幕煞茫,但是這里設置maxHeight、maxWidth摄凡。
.
.
Container有子控件(場景2)
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: new Scaffold(
appBar: AppBar(
title: Text("測試"),
),
body: ConstraintsPropertyHasChild(),
)
);
}
}
//Container屬性之Constraints(有子控件)
class ConstraintsPropertyHasChild extends StatelessWidget{
@override
Widget build(BuildContext context) {
return Center(
child: Container(
color: Color.fromARGB(255, 66, 165, 245),
alignment: AlignmentDirectional(0.0, 0.0),
child: Container(
color: Colors.green,
child: Text("Flutter"),
constraints: BoxConstraints(
maxHeight: 300,
maxWidth: 200,
minWidth: 150,
minHeight: 150,
),
),
),
);
}
}
這里雖然有一個子控件溜嗜,Container會調整自身大小來適應內部子控件,但是由于設置了min-width和min-height架谎。所以Container不會完全和子控件一樣大,除非子控件尺寸大于min-width和min-height辟躏。
嘗試更改子控件大小谷扣,代碼如下:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: new Scaffold(
appBar: AppBar(
title: Text("測試"),
),
body: Constraints_Property_HasChild(),
)
);
}
}
//Container屬性之Constraints(有子控件)
class Constraints_Property_HasChild extends StatelessWidget{
@override
Widget build(BuildContext context) {
return Center(
child: Container(
color: Color.fromARGB(255, 66, 165, 245),
alignment: AlignmentDirectional(0.0, 0.0),
child: Container(
color: Colors.green,
//child: Text("Flutter"),
child: Text("Flutter Cheatsheet Flutter Cheatsheet",
style: TextStyle(
fontSize: 60.0
),),
constraints: BoxConstraints(
maxHeight: 300,
maxWidth: 200,
minWidth: 150,
minHeight: 150,
),
),
),
);
}
}
從上面這張圖可以看出Container不能超出max-width和max-height。
Container有子控件(場景3)
當Container有子控件捎琐,我們想讓Container不去適應子控件会涎,而是充滿整個屏幕或父控件,怎么辦瑞凑?
答案就是使用BoxConstraints.expand()末秃。
代碼如下
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: new Scaffold(
appBar: AppBar(
title: Text("測試"),
),
body: Constraints_Property_HasChild_AllScreen(),
)
);
}
}
//Container屬性之Constraints(有子控件、充滿整個屏幕)
class Constraints_Property_HasChild_AllScreen extends StatelessWidget{
@override
Widget build(BuildContext context) {
return Center(
child: Container(
color: Color.fromARGB(255, 66, 165, 245),
alignment: AlignmentDirectional(0.0, 0.0),
child: Container(
color: Colors.green,
//child: Text("Flutter"),
child: Text("Flutter"),
constraints: BoxConstraints.expand(),
),
),
);
}
}
此時發(fā)現(xiàn)Container是充滿整個屏幕的籽御,我們也可以限制充滿屏幕大小练慕,比如說1/2寬惰匙、1/3高等。
5铃将、margin
EdgeInsets.all()
代碼如下:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: new Scaffold(
appBar: AppBar(
title: Text("測試"),
),
body: Margin_Property_EdgeInsets_all(),
)
);
}
}
//EdgeInsets.all()
class Margin_Property_EdgeInsets_all extends StatelessWidget{
@override
Widget build(BuildContext context) {
return Center(
child: Container(
color: Color.fromARGB(255, 66, 165, 245),
alignment: AlignmentDirectional(0.0, 0.0),
child: Container(
color: Colors.green,
margin: EdgeInsets.all(20.0),
),
),
);
}
}
EdgeInsets.symmetric()
這個主要用于添加垂直和水平方向上的約束项鬼。
類似于水平和垂直的margin
代碼如下:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: new Scaffold(
appBar: AppBar(
title: Text("測試"),
),
body: Margin_Property_EdgeInsets_symmetric(),
)
);
}
}
//EdgeInsets.symmetric()
class Margin_Property_EdgeInsets_symmetric extends StatelessWidget{
@override
Widget build(BuildContext context) {
return Center(
child: Container(
color: Color.fromARGB(255, 66, 165, 245),
alignment: AlignmentDirectional(0.0, 0.0),
child: Container(
color: Colors.green,
margin: EdgeInsets.symmetric(
vertical: 20.0,
horizontal: 50.0,
),
),
),
);
}
}
EdgeInsets.fromLTRB()
這個主要設置left, top, right,bottom邊距。
代碼如下:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: new Scaffold(
appBar: AppBar(
title: Text("測試"),
),
body: Margin_Property_EdgeInsets_fromLTRB(),
)
);
}
}
//EdgeInsets.fromLTRB()
class Margin_Property_EdgeInsets_fromLTRB extends StatelessWidget{
@override
Widget build(BuildContext context) {
return Center(
child: Container(
color: Color.fromARGB(255, 66, 165, 245),
alignment: AlignmentDirectional(0.0, 0.0),
child: Container(
color: Colors.green,
margin: EdgeInsets.fromLTRB(20.0, 30.0, 40.0, 50.0)
),
),
);
}
}
EdgeInsets.only()
用于設置哪些是非零的劲阎,不設置默認是零绘盟。
代碼如下:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: new Scaffold(
appBar: AppBar(
title: Text("測試"),
),
body: Margin_Property_EdgeInsets_only(),
)
);
}
}
//EdgeInsets.only()
class Margin_Property_EdgeInsets_only extends StatelessWidget{
@override
Widget build(BuildContext context) {
return Center(
child: Container(
color: Color.fromARGB(255, 66, 165, 245),
alignment: AlignmentDirectional(0.0, 0.0),
child: Container(
color: Colors.green,
margin: EdgeInsets.only(
left: 20.0,
bottom: 40.0,
top: 50.0,
)
),
),
);
}
}
6、padding
這個用于設置主控件內部子控件之間的間距悯仙。和Margin一樣龄毡,利用到EdgeInsets。
7锡垄、decoration
- BoxDecoration Class
- FlutterLogoDecoration Class
- ShapeDecoration Class
- UnderlineTabIndicator Class
8沦零、foregroundDecoration
- BoxDecoration Class
- FlutterLogoDecoration Class
- ShapeDecoration Class
- UnderlineTabIndicator Class
9、transform
在Container屬性中添加transform屬性偎捎,并使用Matrix類設置transform的值蠢终,即可達到各種變換效果,代碼如下:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: new Scaffold(
appBar: AppBar(
title: Text("測試"),
),
body: Transform_Property(),
)
);
}
}
//Transform Property
class Transform_Property extends StatelessWidget{
@override
Widget build(BuildContext context) {
return Container(
color: Color.fromARGB(255, 66, 165, 245),
alignment: AlignmentDirectional(0.0, 0.0),
child: Container(
padding: EdgeInsets.all(40.0),
color: Colors.green,
child: Text("Flutter Cheatsheet"),
transform: Matrix4.rotationZ(0.5),
),
);
}
}