Flutter開發(fā)實戰(zhàn) 高仿微信(2)發(fā)現(xiàn)頁

Flutter開發(fā)實戰(zhàn) 高仿微信(2)發(fā)現(xiàn)頁

1.項目代碼

1.1 微信發(fā)現(xiàn)頁面簡述

  1. 在上一篇《flutter開發(fā)微信之一》中講解了項目框架的簡單搭建应媚,整個APP分為四個tabbar:微信乐疆,通訊錄孙蒙,發(fā)現(xiàn)义黎,我悠垛。其中發(fā)現(xiàn)是最簡單一個頁面油航,先從最容易的頁面入手啥箭,實現(xiàn)發(fā)現(xiàn)頁面主頁搭建。

1.2 APP框架優(yōu)化

1.2.1 配置APP Logo和啟動圖片

  1. IOS 啟動圖片配置


    在這里插入圖片描述
  2. Android啟動圖片配置


    在這里插入圖片描述

1.2.2 配置資源圖片

  1. flutter 項目資源在pubspec.yaml中配置


    在這里插入圖片描述
  2. 在代碼中使用圖片資源的方式:

  3. 不同分辨率的圖片使用
    跟Android的多圖片適配相同爹梁,將不同分辨率下的圖片放到對應(yīng)的目錄即可右犹,如下:


    在這里插入圖片描述

    使用代碼:

new Image.asset("assets/images/a.png");
  1. flutter 在項目中加載資源的兩種方式:

  • 通過rootBundle對象來加載(每個Flutter應(yīng)用都有一個rootBundle對象,可以訪問主asset bundle) . 如果你所在的業(yè)務(wù)場景下姚垃,拿不到context(不在widget中)念链,那就使用這個吧,否則使用下面的方式积糯。
import 'package:flutter/services.dart';
Widget _createBody() {
    return new FutureBuilder(
    future: rootBundle.loadString('assets/a.json'),
    builder: (context,snapshot){
        if(snapshot.hasData) {
        return new Text(snapshot.data.toString());
        }
    },
    );
  • 通過DefaultAssetBundle 來獲取當(dāng)前BuildContext 的 AssetBundle掂墓,推薦使用。比方法一要靈活看成【啵可以自己制定。
import 'package:flutter/services.dart';
Widget _createBody() {
    return new FutureBuilder(
    future: DefaultAssetBundle.of(context).loadString('assets/a.json'),
    builder: (context,snapshot){
        if(snapshot.hasData) {
        return new Text(snapshot.data.toString());
        }
    },
    );

1.2.3 配置其他資源

1.2.3.1 String 資源配置

新建一個.dart文件川慌,比如uidata.dart:

import 'package:flutter/material.dart';

class UIData {
  //routes  頁面路徑
  static const String homeRoute = "/home";
  static const String profileOneRoute = "/View Profile";
  static const String profileTwoRoute = "/Profile 2";

  //strings
  static const String appName = "Flutter UIKit";

  //fonts  字體相關(guān)
  static const String quickFont = "Quicksand";
  static const String ralewayFont = "Raleway";
  static const String quickBoldFont = "Quicksand_Bold.otf";
  static const String quickNormalFont = "Quicksand_Book.otf";
  static const String quickLightFont = "Quicksand_Light.otf";

  //images
  static const String imageDir = "assets/images";
  static const String pkImage = "$imageDir/pk.jpg";

  //login  比如登錄頁面用到的文本
  static const String enter_code_label = "Phone Number";
  static const String enter_code_hint = "10 Digit Phone Number";

  //gneric 通用的文本
  static const String error = "Error";
  static const String success = "Success";

  static const MaterialColor ui_kit_color = Colors.grey;

//colors
  static List<Color> kitGradients = [
    // new Color.fromRGBO(103, 218, 255, 1.0),
    // new Color.fromRGBO(3, 169, 244, 1.0),
    // new Color.fromRGBO(0, 122, 193, 1.0),
    Colors.blueGrey.shade800,
    Colors.black87,
  ];
  static List<Color> kitGradients2 = [
    Colors.cyan.shade600,
    Colors.blue.shade900
  ];

  //randomcolor
  static final Random _random = new Random();

  /// Returns a random color.
  static Color next() {
    return new Color(0xFF000000 + _random.nextInt(0x00FFFFFF));
  }
}

1.2.3.2 國際化

詳情參考:國際化官方教程

在這里插入圖片描述

1.2.4 添加依賴

在pubspec.yaml 中添加依賴
注意吃嘿,只有在添加平臺所需相關(guān)依賴時,才需要去Android 工程中的gradle中添加依賴梦重。

1.2.5 新建四個主頁對應(yīng)四個tabbar

1.3 發(fā)現(xiàn)頁面布局

2.知識點

2.1 flutter布局

2.1.1 Row 水平布局

  1. 簡介

flex水平布局控件兑燥,能夠?qū)⒆涌丶脚帕斜睹眨腔赪eb的flexbox的布局模式設(shè)計的嫂粟。
Row子控件有靈活與不靈活的兩種,Row首先列出不靈活的子控件决帖,減去它們的總寬度蚓胸,計算還有多少可用的空間力崇。然后Row按照Flexible.flex屬性確定的比例在可用空間中列出靈活的子控件斗塘。要控制靈活子控件,需要使用Expanded控件亮靴。
注意該控件不支持滑動馍盟,如果子控件超過剩余空間,會報錯茧吊,如果想支持水平滑動贞岭,考慮使用ListView。
如果只有一個子控件搓侄,可以使用 Align or Center控件定義該子控件位置瞄桨。

  1. 實例
 1 new Row(
 2   children: <Widget>[
 3     new Expanded(
 4       child: new Text('Deliver features faster', textAlign: TextAlign.center),
 5     ),
 6     new Expanded(
 7       child: new Text('Craft beautiful UIs', textAlign: TextAlign.center),
 8     ),
 9     new Expanded(
10       child: new FittedBox(
11         fit: BoxFit.contain, // otherwise the logo will be tiny
12         child: const FlutterLogo(),
13       ),
14     ),
15   ],
16 )
  1. 用法

2.1.2 Column 垂直布局

  1. 簡介
    flex垂直布局控件,能夠?qū)⒆涌丶怪迸帕小?br> 用法與Row控件一樣讶踪。
  2. 實例
new Column(
 2   crossAxisAlignment: CrossAxisAlignment.start,
 3   mainAxisSize: MainAxisSize.min,
 4   children: <Widget>[
 5     new Text('We move under cover and we move as one'),
 6     new Text('Through the night, we have one shot to live another day'),
 7     new Text('We cannot let a stray gunshot give us away'),
 8     new Text('We will fight up close, seize the moment and stay in it'),
 9     new Text('It’s either that or meet the business end of a bayonet'),
10     new Text('The code word is ‘Rochambeau,’ dig me?'),
11     new Text('Rochambeau!', style: DefaultTextStyle.of(context).style.apply(fontSizeFactor: 2.0)),
12   ],
13 )
  1. 用法

2.1.3 Stack 層布局

  1. 簡介

  2. 實例

  3. 用法

2.1.4 主軸

  1. 簡介

  2. 實例

  3. 用法

2.1.5

  1. 簡介

  2. 實例

  3. 用法

2.2 flutter基本組件

Flutter控件本身通常由許多小型芯侥、單用途的控件組成,結(jié)合起來產(chǎn)生強大的效果乳讥,例如柱查,Container是一種常用的控件,由負(fù)責(zé)布局云石、繪畫唉工、定位和大小調(diào)整的幾個控件組成,具體來說淋硝,Container是由LimitedBox、ConstrainedBox宽菜、 Align谣膳、Padding、DecoratedBox和Transform控件組成铅乡,而不是將Container子類化來產(chǎn)生自定義效果继谚,您可以用這種新穎的方式組合這些以及其他簡單的控件。

類的層次結(jié)構(gòu)是扁平的隆判,以最大化可能的組合數(shù)量犬庇。

在這里插入圖片描述

在寫應(yīng)用程序時僧界,經(jīng)常會使用StatelessWidget和StatefulWidget編寫新控件侨嘀,兩者的差別在于你是否要管理控件的狀態(tài)。一個控件的主要任務(wù)是實現(xiàn)build函數(shù)捂襟,定義控件中其他較低層次的控件咬腕。build函數(shù)將依次構(gòu)建這些控件,直到底層渲染對象葬荷。

  • Flutter控件和Android涨共,IOS原生控件比較
Flutter控件 Android控件 IOS控件
AppBar ActionBar/ToolBar UINavgationBar
ListView ListView/RecyclerView UITableView
ListView ListView/RecyclerView UITableView
Text TextView UILabel
Center ViewGroup ---
Container RelativeLayout --
FloatingActionButton FloatingActionButton(design庫里面的) ---
BottomNavigationBar BottomNavigation(design庫里面的) ---
RaisedButton/Button Button --
Column LinearLayout的android:orientation="vertical" --
Row android:orientation="horizontal" --
DecorationImage ImageView --
Image ImageView UIImageView
Stack FrameLayout/RelativeLayout --
Algin alginParentXXX屬性 --
resizeToAvoidBottomPadding android:windowSoftInputMode=” adjustResize屬性 --
SingleChildScrollView ScrollView UIScrollView
CustomScrollerView Recyclerview --

2.2.1 Container

  1. 簡介

容器纽帖,一個常用的控件,由基本的繪制举反、位置和大小控件組成懊直。負(fù)責(zé)創(chuàng)建矩形的可視元素,可以用BoxDecoration來設(shè)計樣式火鼻,比如背景室囊、邊框和陰影,Container也有邊距魁索、填充和大小限制融撞,另外,還可以在三維空間利用矩陣進行變換粗蔚。
沒有子控件的容器盡可能大尝偎,除非傳入的大小約束是無限的,在這種情況下鹏控,它們盡可能小致扯。有子控件的容器將自己的尺寸給他們的孩子。我們可以通過width牧挣、height和 constraints屬性控制size急前。

  1. 實例
new Container(
   constraints: new BoxConstraints.expand(
    height: Theme.of(context).textTheme.display1.fontSize * 1.1 + 200.0,
  ),
  padding: const EdgeInsets.all(8.0),
  color: Colors.teal.shade700,
   alignment: Alignment.center,
   child: new Text('Hello World', style: Theme.of(context).textTheme.display1.copyWith(color: Colors.white)),
   foregroundDecoration: new BoxDecoration(
     image: new DecorationImage(
       image: new NetworkImage('https://www.example.com/images/frame.png'),
       centerSlice: new Rect.fromLTRB(270.0, 180.0, 1360.0, 730.0),
     ),
   ),
   transform: new Matrix4.rotationZ(0.1),
 )
  1. 用法

2.2.2 Image

  1. 簡介

顯示圖像的控件,Image控件有多種構(gòu)造函數(shù):
new Image瀑构,用于從ImageProvider獲取圖像裆针。
new Image.asset,用于使用key從AssetBundle獲取圖像寺晌。
new Image.network世吨,用于從URL地址獲取圖像。
new Image.file呻征,用于從File獲取圖像耘婚。

為了自動執(zhí)行像素密度感知資源分辨率,使用AssetImage指定圖像陆赋,需要確保在控件樹中的圖片控件上方存在MaterialApp沐祷、WidgetsApp和MediaQuery控件。

不同的手機有不同的像素比率攒岛,這時就需要根據(jù)手機的像素比率來加載不同圖片赖临,做法很簡單,只需要在圖片同級目錄下創(chuàng)建2.0x/…和3.0x/…的目錄就可以了灾锯。

我們在pubspec.yaml這個文件里指定本地圖片路徑

# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
  1. 實例

  2. 用法

2.2.3 Text

  1. 簡介

  2. 實例
    下面的實例有7個不同樣式的文本控件:

1 import 'package:flutter/material.dart';
 2 class TextDemo extends StatelessWidget {
 3   @override
 4   Widget build(BuildContext context) {
 5     return new Scaffold(
 6       appBar: new AppBar(
 7         title: new Text('文本控件'),
 8       ),
 9       body: new Column(
10         children: <Widget>[
11           new Text(
12             '紅色+黑色刪除線+25號',
13             style: new TextStyle(
14               color: const Color(0xffff0000),
15               decoration: TextDecoration.lineThrough,
16               decorationColor: const Color(0xff000000),
17               fontSize: 25.0,
18             ),
19           ),
20           new Text(
21             '橙色+下劃線+24號',
22             style: new TextStyle(
23               color: const Color(0xffff9900),
24               decoration: TextDecoration.underline,
25               fontSize: 24.0,
26             ),
27           ),
28           new Text(
29             '虛線上劃線+23號+傾斜',
30             style: new TextStyle(
31               decoration: TextDecoration.overline,
32               decorationStyle: TextDecorationStyle.dashed,
33               fontSize: 23.0,
34               fontStyle: FontStyle.italic,
35             ),
36           ),
37           new Text(
38             'serif字體+24號',
39             style: new TextStyle(
40               fontFamily: 'serif',
41               fontSize: 26.0,
42             ),
43           ),
44           new Text(
45             'monospace字體+24號+加粗',
46             style: new TextStyle(
47               fontFamily: 'monospace',
48               fontSize: 24.0,
49               fontWeight: FontWeight.bold,
50             ),
51           ),
52           new Text(
53             '天藍色+25號+2行跨度',
54             style: new TextStyle(
55               color: const Color(0xff4a86e8),
56               fontSize: 25.0,
57               height: 2.0,
58             ),
59           ),
60           new Text(
61             '24號+2個字母間隔',
62             style: new TextStyle(
63               fontSize: 24.0,
64               letterSpacing: 2.0,
65             ),
66           ),
67         ]
68       ),
69     );
70   }
71 }
72 void main() {
73   runApp(
74     new MaterialApp(
75       title: 'Flutter教程',
76       home: new TextDemo(),
77     ),
78   );
79 }

運行效果:


在這里插入圖片描述
  1. 用法

2.2.4 Icon

  1. 簡介

圖標(biāo)控件兢榨,按照IconData中所描述的規(guī)則繪制,如Material中預(yù)定義的IconDatas。
該控件不可交互吵聪,要實現(xiàn)可交互的圖標(biāo)凌那,可以考慮使用Material中的 IconButton。
該控件必須在 Directionality控件里使用吟逝,通常這是由WidgetsApp或 MaterialApp自動引入的帽蝶。詳見:https://docs.flutter.io/flutter/widgets/Icon-class.html

  1. 實例

  2. 用法

2.2.5 RaisedButton

  1. 簡介

Material Design 風(fēng)格的浮動按鈕,以方形紙片樣式懸停在界面上块攒,點擊后會產(chǎn)生墨水?dāng)U散效果嘲碱。
避免在dialog和card控件里使用,一般彈出式的控件建議使用扁平化按鈕局蚀,減少布局層次疊加麦锯。詳見:https://docs.flutter.io/flutter/material/RaisedButton-class.html

  1. 實例

  2. 用法
    使用時,要實現(xiàn)onPressed回調(diào)方法琅绅,否則按鈕處于禁用狀態(tài)扶欣,默認(rèn)顯示disabledColor樣式的扁平化按鈕,并且此時更改按鈕的顏色不會生效千扶。
    注意該控件的父控件必須是Material控件料祠。
    如果你只需要點擊后產(chǎn)生墨水?dāng)U散效果,但不想使用按鈕澎羞,請考慮直接使用InkWell控件髓绽。
    如有必要,該按鈕將拉伸以適應(yīng)子控件大小妆绞。

2.2.6 Scaffold

  1. 簡介

Scaffold 實現(xiàn)了基本的Material Design布局結(jié)構(gòu)顺呕。也就是說, MaterialApp 的 child 是 Scaffold Widget括饶。
在Material設(shè)計中定義的單個界面上的各種布局元素株茶,在 Scaffold 中都有支持,比如 左邊欄(Drawers)图焰、snack bars启盛、以及 bottom sheets。

Scaffold 有下面幾個主要屬性:

  • appBar:顯示在界面頂部的一個 AppBar技羔,也就是 Android 中的 ActionBar 僵闯、Toolbar

  • body:當(dāng)前界面所顯示的主要內(nèi)容 Widget

  • floatingActionButton:Material設(shè)計中所定義的 FAB,界面的主要功能按鈕

  • persistentFooterButtons:固定在下方顯示的按鈕藤滥,比如對話框下方的確定鳖粟、取消按鈕

  • drawer:側(cè)邊欄控件

  • backgroundColor: 內(nèi)容的背景顏色,默認(rèn)使用的是 ThemeData.scaffoldBackgroundColor 的值

  • bottomNavigationBar: 顯示在頁面底部的導(dǎo)航欄

  • resizeToAvoidBottomPadding:類似于 Android 中的 android:windowSoftInputMode=”adjustResize”超陆,控制界面內(nèi)容 body 是否重新布局來避免底部被覆蓋了牺弹,比如當(dāng)鍵盤顯示的時候,重新布局避免被鍵盤蓋住內(nèi)容时呀。默認(rèn)值為 true张漂。

顯示 snackbar 或者 bottom sheet 的時候,需要使用當(dāng)前的 BuildContext 參數(shù)調(diào)用 Scaffold.of 函數(shù)來獲取 ScaffoldState 對象谨娜,然后使用 ScaffoldState.showSnackBar 和 ScaffoldState.showBottomSheet 函數(shù)來顯示航攒。

要特別注意 Scaffold.of 的參數(shù) BuildContext, 如果包含該 BuildContext 的 Widget 是 Scaffold 的父 Widget趴梢,則 Scaffold.of 是無法查找到對應(yīng)的 ScaffoldState 對象的漠畜,Scaffold.of 返回的是父對象中最近的 Scaffold 中的 ScaffoldState 對象。 比如坞靶,如果在 Scaffold 的 build 函數(shù)中憔狞,使用 build 的 BuildContext 參數(shù)是可以的:

 1 @override
 2 Widget build(BuildContext context) {
 3   return new RaisedButton(
 4     child: new Text('SHOW A SNACKBAR'),
 5     onPressed: () {
 6       Scaffold.of(context).showSnackBar(new SnackBar(
 7         content: new Text('Hello!'),
 8       ));
 9     },
10   );
11 }
  1. 實例
    如果 build 函數(shù)返回一個 Scaffold 對象,則由于 Scaffold 對象是這個 Widget 的子對象彰阴,所以使用這個 build 的 BuildContext 參數(shù)是不能查找到 ScaffoldState 對象的瘾敢,這個時候,通過在 Scaffold 中使用一個 Builder 來提供一個新的 BuildConext :
@override
 2 Widget build(BuildContext context) {
 3   return new Scaffold(
 4     appBar: new AppBar(
 5       title: new Text('Demo')
 6     ),
 7     body: new Builder(
 8       // Create an inner BuildContext so that the onPressed methods
 9       // can refer to the Scaffold with Scaffold.of().
10       builder: (BuildContext context) {
11         return new Center(
12           child: new RaisedButton(
13             child: new Text('SHOW A SNACKBAR'),
14             onPressed: () {
15               Scaffold.of(context).showSnackBar(new SnackBar(
16                 content: new Text('Hello!'),
17               ));
18             },
19           ),
20         );
21       },
22     ),
23   );
24 }

另外還可以把 build 函數(shù)中的 Widget 分別創(chuàng)建尿这,分別引入新的 BuildContext 來獲取 Scaffold簇抵。

  1. 用法

2.2.7 Appbar

  1. 簡介

AppBar 和 SliverAppBar 是Material Design中的 App Bar,也就是 Android 中的 Toolbar射众,關(guān)于 Toolbar 的設(shè)計指南請參考Material Design中 Toolbar 的內(nèi)容碟摆。
AppBar 和 SliverAppBar 都是繼承StatefulWidget 類,都代表 Toobar叨橱,二者的區(qū)別在于 AppBar 位置的固定的應(yīng)用最上面的典蜕;而 SliverAppBar 是可以跟隨內(nèi)容滾動的。

他們的主要屬性如下:

  • leading:在標(biāo)題前面顯示的一個控件罗洗,在首頁通常顯示應(yīng)用的 logo嘉裤;在其他界面通常顯示為返回按鈕

  • title: Toolbar 中主要內(nèi)容,通常顯示為當(dāng)前界面的標(biāo)題文字

  • actions:一個 Widget 列表栖博,代表 Toolbar 中所顯示的菜單屑宠,對于常用的菜單,通常使用 IconButton 來表示仇让;對于不常用的菜單通常使用 PopupMenuButton 來顯示為三個點典奉,點擊后彈出二級菜單

  • bottom:一個 AppBarBottomWidget 對象,通常是 TabBar丧叽。用來在 Toolbar 標(biāo)題下面顯示一個 Tab 導(dǎo)航欄

  • elevation:紙墨設(shè)計中控件的 z 坐標(biāo)順序卫玖,默認(rèn)值為 4,對于可滾動的 SliverAppBar踊淳,當(dāng) SliverAppBar 和內(nèi)容同級的時候假瞬,該值為 0陕靠, 當(dāng)內(nèi)容滾動 SliverAppBar 變?yōu)?Toolbar 的時候,修改 elevation 的值

  • flexibleSpace:一個顯示在 AppBar 下方的控件脱茉,高度和 AppBar 高度一樣剪芥,可以實現(xiàn)一些特殊的效果,該屬性通常在 SliverAppBar 中使用

  • backgroundColor:APP bar 的顏色琴许,默認(rèn)值為 ThemeData.primaryColor税肪。改值通常和下面的三個屬性一起使用

  • brightness:App bar 的亮度,有白色和黑色兩種主題榜田,默認(rèn)值為 ThemeData.primaryColorBrightness

  • iconTheme:App bar 上圖標(biāo)的顏色益兄、透明度、和尺寸信息箭券。默認(rèn)值為 ThemeData.primaryIconTheme

  • textTheme: App bar 上的文字樣式净捅。默認(rèn)值為 ThemeData.primaryTextTheme

  • centerTitle: 標(biāo)題是否居中顯示,默認(rèn)值根據(jù)不同的操作系統(tǒng)辩块,顯示方式不一樣

  1. 實例
import 'package:flutter/material.dart';
  2 
  3 class AppBarBottomSample extends StatefulWidget {
  4   @override
  5   _AppBarBottomSampleState createState() => new _AppBarBottomSampleState();
  6 }
  7 
  8 class _AppBarBottomSampleState extends State<AppBarBottomSample> with SingleTickerProviderStateMixin {
  9   TabController _tabController;
 10 
 11   @override
 12   void initState() {
 13     super.initState();
 14     _tabController = new TabController(vsync: this, length: choices.length);
 15   }
 16 
 17   @override
 18   void dispose() {
 19     _tabController.dispose();
 20     super.dispose();
 21   }
 22 
 23   void _nextPage(int delta) {
 24     final int newIndex = _tabController.index + delta;
 25     if (newIndex < 0 || newIndex >= _tabController.length)
 26       return;
 27     _tabController.animateTo(newIndex);
 28   }
 29 
 30   @override
 31   Widget build(BuildContext context) {
 32     return new MaterialApp(
 33       home: new Scaffold(
 34         appBar: new AppBar(
 35           title: const Text('AppBar Bottom Widget'),
 36           leading: new IconButton(
 37             tooltip: 'Previous choice',
 38             icon: const Icon(Icons.arrow_back),
 39             onPressed: () { _nextPage(-1); },
 40           ),
 41           actions: <Widget>[
 42             new IconButton(
 43               icon: const Icon(Icons.arrow_forward),
 44               tooltip: 'Next choice',
 45               onPressed: () { _nextPage(1); },
 46             ),
 47           ],
 48           bottom: new PreferredSize(
 49             preferredSize: const Size.fromHeight(48.0),
 50             child: new Theme(
 51               data: Theme.of(context).copyWith(accentColor: Colors.white),
 52               child: new Container(
 53                 height: 48.0,
 54                 alignment: Alignment.center,
 55                 child: new TabPageSelector(controller: _tabController),
 56               ),
 57             ),
 58           ),
 59         ),
 60         body: new TabBarView(
 61           controller: _tabController,
 62           children: choices.map((Choice choice) {
 63             return new Padding(
 64               padding: const EdgeInsets.all(16.0),
 65               child: new ChoiceCard(choice: choice),
 66             );
 67           }).toList(),
 68         ),
 69       ),
 70     );
 71   }
 72 }
 73 
 74 class Choice {
 75   const Choice({ this.title, this.icon });
 76   final String title;
 77   final IconData icon;
 78 }
 79 
 80 const List<Choice> choices = const <Choice>[
 81   const Choice(title: 'CAR', icon: Icons.directions_car),
 82   const Choice(title: 'BICYCLE', icon: Icons.directions_bike),
 83   const Choice(title: 'BOAT', icon: Icons.directions_boat),
 84   const Choice(title: 'BUS', icon: Icons.directions_bus),
 85   const Choice(title: 'TRAIN', icon: Icons.directions_railway),
 86   const Choice(title: 'WALK', icon: Icons.directions_walk),
 87 ];
 88 
 89 class ChoiceCard extends StatelessWidget {
 90   const ChoiceCard({ Key key, this.choice }) : super(key: key);
 91 
 92   final Choice choice;
 93 
 94   @override
 95   Widget build(BuildContext context) {
 96     final TextStyle textStyle = Theme.of(context).textTheme.display1;
 97     return new Card(
 98       color: Colors.white,
 99       child: new Center(
100         child: new Column(
101           mainAxisSize: MainAxisSize.min,
102           crossAxisAlignment: CrossAxisAlignment.center,
103           children: <Widget>[
104             new Icon(choice.icon, size: 128.0, color: textStyle.color),
105             new Text(choice.title, style: textStyle),
106           ],
107         ),
108       ),
109     );
110   }
111 }
112 
113 void main() {
114   runApp(new AppBarBottomSample());
115 }

運行效果:

在這里插入圖片描述
  1. 用法

2.2.8 FlutterLogo

  1. 簡介
    定義flutter應(yīng)用的logo灸叼,該控件受IconTheme約束。
  2. 實例
import 'package:flutter/material.dart';
 2 
 3 void main() {
 4   runApp(new FadeAppTest());
 5 }
 6 
 7 class FadeAppTest extends StatelessWidget {
 8   // This widget is the root of your application.
 9   @override
10   Widget build(BuildContext context) {
11     return new MaterialApp(
12       title: 'Fade Demo',
13       theme: new ThemeData(
14         primarySwatch: Colors.blue,
15       ),
16       home: new MyFadeTest(title: 'Fade Demo'),
17     );
18   }
19 }
20 
21 class MyFadeTest extends StatefulWidget {
22   MyFadeTest({Key key, this.title}) : super(key: key);
23   final String title;
24   @override
25   _MyFadeTest createState() => new _MyFadeTest();
26 }
27 
28 class _MyFadeTest extends State<MyFadeTest> with TickerProviderStateMixin {
29   AnimationController controller;
30   CurvedAnimation curve;
31 
32   @override
33   void initState() {
34     controller = new AnimationController(duration: const Duration(milliseconds: 2000), vsync: this);
35     curve = new CurvedAnimation(parent: controller, curve: Curves.easeIn);
36   }
37 
38   @override
39   Widget build(BuildContext context) {
40     return new Scaffold(
41       appBar: new AppBar(
42         title: new Text(widget.title),
43       ),
44       body: new Center(
45           child: new Container(
46               child: new FadeTransition(
47                   opacity: curve,
48                   child: new FlutterLogo(
49                     size: 100.0,
50                   )))),
51       floatingActionButton: new FloatingActionButton(
52         tooltip: 'Fade',
53         child: new Icon(Icons.brush),
54         onPressed: () {
55           controller.forward();
56         },
57       ),
58     );
59   }
60 }
  1. 用法

2.2.9 Placeholder

  1. 簡介

占位控件庆捺,該控件繪制一個框古今,表示將來會在該位置添加其他控件。
這個控件在開發(fā)過程中很有用滔以,可提示該處接口還沒完成捉腥。
默認(rèn)情況下,控件的大小自適應(yīng)其容器你画。如果該控件處于無界空間抵碟,它將根據(jù)給定的fallbackWidth和fallbackHeight自行調(diào)整大小。
詳見:https://docs.flutter.io/flutter/widgets/Placeholder-class.html

  1. 實例

  2. 用法

2.2.10

  1. 簡介

  2. 實例

  3. 用法

3.深入研究

3.1 flutter項目結(jié)構(gòu)分析

  • 純Flutter項目結(jié)構(gòu)


    在這里插入圖片描述
  • projectName
    -android //android的工程文件
    -build //項目的構(gòu)建輸出文件
    -ios //項目的ios工程文件
    -lib //項目中的dart文件
    -src //包含其他的源文件
    -main.dart //自動生成的項目入口文件
    -test //測試相關(guān)的文件
    -assets
    -images//建議存放圖片
    -2.0x
    -3.0x
    xxxxx //圖片可以直接放到images
    -fonts//建議存放字體
    -pubspec.yaml //項目依賴配置文件
  • 混編Flutter項目


    在這里插入圖片描述

如上圖坏匪,下面我們就按個來分析拟逮,看一下一個flutter混編工程都有那些不同之處相對我們傳統(tǒng)的android工程。首先第一個.gradle文件沒有區(qū)別适滓,里面就是我們當(dāng)前工程使用的gradle的版本敦迄,接下來一個,就是我們的android文件夾凭迹,用來存放我們的android工程罚屋,再下來是我們的asset文件夾,用來存放flutter工程的資源嗅绸,包括圖片脾猛,字體,視頻等任何資源文件鱼鸠,http_plugin大家先不看猛拴,因為他是一個插件工程羹铅,我們最后看,再下來是一個ios文件夾愉昆,里面當(dāng)然是存放我們的ios工程的所有內(nèi)容职员,再下來的lib文件夾,則是存放flutter代碼的默認(rèn)目錄(可以修改名字,后面詳細(xì)講解)撼唾,最后一個最重要的文件是pubspec.yaml文件,這個文件用來配置flutter工程所需要的依賴等哥蔚,到這里其實我們就從整體上知道了倒谷,flutter工程有那些特別的地方,當(dāng)然還只是停留在一個整體糙箍,下面我們以一張圖來進行對比渤愁,從整體上我們來看一下與傳統(tǒng)android工程的區(qū)別。

在這里插入圖片描述

從圖中我們可以看到深夯,其實flutter混編工程無非就是多了下面兩部分抖格,很容易理解,因為是跨平臺的所以,需要一個ios的容器工程咕晋,最后一部分就是flutter工程本身的東西雹拄,包括他的資源和代碼,以及依賴等掌呜。

3.2 flutter項目pubspec.yaml文件

pubspecyaml文件用于配置flutter的資源依賴滓玖、庫依賴

  • yaml語法
    大小寫敏感
    用冒號和縮進代表層次關(guān)系
    只能用空格,不能用tab鍵质蕉,對空格多少沒要求势篡,同級對齊即可
    可表示三種數(shù)據(jù)類型,常量值模暗,對象禁悠,數(shù)組
#即表示url屬性值:
url: http://www.wolfcode.cn 
#即表示server.host屬性的值;
server:
    host: http://www.wolfcode.cn 
#數(shù)組兑宇,即表示server為[a,b,c]
server:
    - 120.168.117.21
    - 120.168.117.22
     - 120.168.117.23
#常量
pi: 3.14   #定義一個數(shù)值3.14
hasChild: true  #定義一個boolean值
name: '你好YAML'   #定義一個字符串

  1. 在dependencies:下添加庫依賴
dependencies:
  flutter:
    sdk:flutter
#^表示適配和當(dāng)前大版本一致的版本碍侦,即2.x.x都可,~表示適配和當(dāng)前小版本一致的版本隶糕,即2.1.x都可
  dio:^2.1.0

^表示適配和當(dāng)前大版本一致的版本祝钢,即2.x.x都可,~表示適配和當(dāng)前小版本一致的版本若厚,即2.1.x都可

  1. 在flutter:下面添加添加資源依賴
flutter:
  user-material-design:true
  assets:
    - images/lake.jpg
    - images/light.jpg

冒號后面一定要有空格拦英,表示數(shù)組元素的-符號后面也要有空格,否則語法不通過测秸。
images/lake.jpg是圖片的路徑 即在project下建立一個images文件夾 再把lake.jpg放進去疤估。

3.3 flutter項目圖片資源配置

Flutter應(yīng)用程序可以包含代碼和 assets(有時稱為資源)灾常。asset是打包到程序安裝包中的,可在運行時訪問铃拇。常見類型的asset包括靜態(tài)數(shù)據(jù)(例如JSON文件)钞瀑,配置文件,圖標(biāo)和圖片(JPEG慷荔,WebP雕什,GIF,動畫WebP / GIF显晶,PNG贷岸,BMP和WBMP)
資源需要在 pubspec.yaml中配置,配置方法:

flutter:
  assets:
    - assets/my_icon.png
    - assets/background.png
  • Asset 變體(variant)
  1. 變體就是指在構(gòu)建時磷雇,根據(jù)不同的場景偿警,選擇適應(yīng)該場景的資源∥希可以類比Android多圖片資源的適配:自動選擇加載xxh或者xh下的圖片螟蒸。
  2. 在根據(jù)pubspec.yaml構(gòu)建資源時,會在相鄰目錄中找到相同名稱的任何文件崩掘,這些文件會一起打入包中七嫌。
應(yīng)用程序中有如下文件:
assets/image/a.png
assets/image/2x/a.png
assets/image/3x/a.png

pubspec.yaml 中配置:
flutter:
assets:
- assets/calendar.png

那么,這三種a.png 都會打入asset bundle中苞慢。后面2個被認(rèn)為是變體抄瑟。
  • 加載資源

參考文章:http://www.imooc.com/article/278442

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市枉疼,隨后出現(xiàn)的幾起案子皮假,更是在濱河造成了極大的恐慌,老刑警劉巖骂维,帶你破解...
    沈念sama閱讀 219,110評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件惹资,死亡現(xiàn)場離奇詭異,居然都是意外死亡航闺,警方通過查閱死者的電腦和手機褪测,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來潦刃,“玉大人侮措,你說我怎么就攤上這事」愿埽” “怎么了分扎?”我有些...
    開封第一講書人閱讀 165,474評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長胧洒。 經(jīng)常有香客問我畏吓,道長墨状,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,881評論 1 295
  • 正文 為了忘掉前任菲饼,我火速辦了婚禮肾砂,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘宏悦。我一直安慰自己镐确,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,902評論 6 392
  • 文/花漫 我一把揭開白布饼煞。 她就那樣靜靜地躺著源葫,像睡著了一般。 火紅的嫁衣襯著肌膚如雪派哲。 梳的紋絲不亂的頭發(fā)上臼氨,一...
    開封第一講書人閱讀 51,698評論 1 305
  • 那天掺喻,我揣著相機與錄音芭届,去河邊找鬼。 笑死感耙,一個胖子當(dāng)著我的面吹牛褂乍,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播即硼,決...
    沈念sama閱讀 40,418評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼逃片,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了只酥?” 一聲冷哼從身側(cè)響起褥实,我...
    開封第一講書人閱讀 39,332評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎裂允,沒想到半個月后损离,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,796評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡绝编,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,968評論 3 337
  • 正文 我和宋清朗相戀三年僻澎,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片十饥。...
    茶點故事閱讀 40,110評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡窟勃,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出逗堵,到底是詐尸還是另有隱情秉氧,我是刑警寧澤,帶...
    沈念sama閱讀 35,792評論 5 346
  • 正文 年R本政府宣布蜒秤,位于F島的核電站谬运,受9級特大地震影響隙赁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜梆暖,卻給世界環(huán)境...
    茶點故事閱讀 41,455評論 3 331
  • 文/蒙蒙 一伞访、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧轰驳,春花似錦厚掷、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至勤哗,卻和暖如春抡爹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背芒划。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評論 1 272
  • 我被黑心中介騙來泰國打工冬竟, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人民逼。 一個月前我還...
    沈念sama閱讀 48,348評論 3 373
  • 正文 我出身青樓泵殴,卻偏偏與公主長得像,于是被迫代替她去往敵國和親拼苍。 傳聞我的和親對象是個殘疾皇子笑诅,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,047評論 2 355

推薦閱讀更多精彩內(nèi)容