Flutter 你需要知道的那些事 01

公眾號(hào)「AndroidTraveler」首發(fā)。

1. width 屬性

對(duì)于設(shè)置控件寬度填充父控件這件事情,在 Android 里面嚷量,只需要設(shè)置 MATCH_PARENT 即可镇饮。

但是在 Flutter 里面卻不是這樣,因?yàn)?Flutter 要具體的數(shù)值耗绿。

所以我們可以這樣考慮苹支,假設(shè)我這個(gè)值非常大,比所有市面上的設(shè)備寬度還要大误阻,那么是不是表現(xiàn)出來就是充滿父控件了债蜜。

所以這邊的做法是設(shè)置為無限,即 double.infinite

我們以一個(gè)常用場景來說明究反。

比如設(shè)置圖片填充屏幕寬度寻定。

剛開始沒有設(shè)置的代碼如下:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
          appBar: AppBar(
            title: Text('My Flutter'),
          ),
          body: Center(
            child: Image.asset('assets/images/example.jpeg'),
          ),
        )
    );
  }
}

效果:

可以看到?jīng)]有設(shè)置的情況下,顯示會(huì)根據(jù)圖片自身的寬高顯示精耐。

這個(gè)時(shí)候如果設(shè)置 width 為無窮大狼速,修改代碼如下:

child: Image.asset('assets/images/example.jpeg', width: double.infinity,),

效果

什么情況,沒起作用卦停?

這個(gè)時(shí)候不要慌向胡,我們來給大家分析分析。

以后大家遇到類似問題也可以這樣分析惊完。

我們通過給 Image 外面套上一層 Container捷枯,然后設(shè)置背景顏色來對(duì)比一下。

代碼如下:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
      appBar: AppBar(
        title: Text('My Flutter'),
      ),
      body: Center(
        child: Container(
          color: Colors.blue,
          //left
//          child: Image.asset('assets/images/example.jpeg',),
          //right
          child: Image.asset('assets/images/example.jpeg', width: double.infinity,),
        ),
      ),
    ));
  }
}

效果如下:

可以看到专执,設(shè)置寬度之后淮捆,Image 確實(shí)是填充了寬度,只不過由于圖片本身沒有那么寬本股,因此看起來就以為是沒有起作用攀痊。

那么如何讓圖片可以填充寬度呢?

這個(gè)就涉及到圖片的填充模式了拄显。

2. fit 屬性

點(diǎn)擊 Image 的 fit 屬性進(jìn)入源碼可以看到如下:

/// How to inscribe the image into the space allocated during layout.
///
/// The default varies based on the other fields. See the discussion at
/// [paintImage].
final BoxFit fit;

我們?cè)冱c(diǎn)一下 BoxFit苟径,可以看到如下:

/// How a box should be inscribed into another box.
///
/// See also [applyBoxFit], which applies the sizing semantics of these values
/// (though not the alignment semantics).
enum BoxFit {
  /// Fill the target box by distorting the source's aspect ratio.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/painting/box_fit_fill.png)
  fill,

  /// As large as possible while still containing the source entirely within the
  /// target box.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/painting/box_fit_contain.png)
  contain,

  /// As small as possible while still covering the entire target box.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/painting/box_fit_cover.png)
  cover,

  /// Make sure the full width of the source is shown, regardless of
  /// whether this means the source overflows the target box vertically.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/painting/box_fit_fitWidth.png)
  fitWidth,

  /// Make sure the full height of the source is shown, regardless of
  /// whether this means the source overflows the target box horizontally.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/painting/box_fit_fitHeight.png)
  fitHeight,

  /// Align the source within the target box (by default, centering) and discard
  /// any portions of the source that lie outside the box.
  ///
  /// The source image is not resized.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/painting/box_fit_none.png)
  none,

  /// Align the source within the target box (by default, centering) and, if
  /// necessary, scale the source down to ensure that the source fits within the
  /// box.
  ///
  /// This is the same as `contain` if that would shrink the image, otherwise it
  /// is the same as `none`.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/painting/box_fit_scaleDown.png)
  scaleDown,
}

相信大家看到源碼的注釋應(yīng)該很清楚每個(gè)值的意義了。

如果你還不清楚躬审,可以點(diǎn)擊注釋里面對(duì)應(yīng)的鏈接去查看示意圖棘街。

比如以我們這個(gè)實(shí)際應(yīng)用場景填充寬度為例蟆盐,那么我們可以看到 fitWidth 應(yīng)該是符合我們要求的,我們點(diǎn)擊注釋的鏈接遭殉,跳轉(zhuǎn)可以看到圖片如下:

很形象的做了幾種情況的示意石挂。我們?cè)O(shè)置了 Image 的 fit 屬性如下:

child: Image.asset('assets/images/example.jpeg', width: double.infinity, fit: BoxFit.fitWidth,),

效果:

可以看到已經(jīng)滿足我們的需求了。

溫馨提示:測試完之后不要忘記去掉測試的 Container 以及對(duì)應(yīng)顏色哦~

3. print

我們知道在 Android 里面险污,當(dāng)我們 try catch 之后痹愚,我們打印異常基本會(huì)寫出類似下面代碼:

Log.e(TAG, "exception="+e);

在 Flutter 也有異常捕獲蛔糯。

你可能會(huì)習(xí)慣的寫出如下代碼:

print('exception='+e);

但是切記拯腮,不要使用上面的寫法。

因?yàn)楫?dāng) e 為 null 時(shí)蚁飒,上面的 print 不會(huì)執(zhí)行打印动壤。

這可能會(huì)誤導(dǎo)你。因?yàn)槟阍诔晒Φ臅r(shí)候加上打印語句淮逻,異常捕獲也加上打印語句琼懊。但是程序就是沒有打印。你就會(huì)覺得很奇怪弦蹂。

實(shí)際上當(dāng) e 為 null 時(shí),print 語句會(huì)報(bào)錯(cuò)强窖,+ 號(hào)連接的左右不能是 null凸椿,所以不會(huì)正常打印。因此請(qǐng)避免上面的寫法翅溺∧月可以用下面的替換寫法:

//替換寫法一
print('exception=');
print(e);
//替換寫法二
print('exception='+(e ?? ''));
//替換寫法三
var printContent = e ?? '';
print('exception='+printContent);

4. GestureDetector

我們知道如果要給一個(gè) Widget 增加點(diǎn)擊事件,最簡單的方法就是套一層 GestureDetector咙崎。

但是有時(shí)候你這樣做了优幸,卻發(fā)現(xiàn)有些“隱患”,或者說褪猛,有些你意料不到的事情网杆。

這里用一個(gè)場景來告訴你,你平時(shí)可能沒有發(fā)現(xiàn)的細(xì)節(jié)伊滋。

微博里面有點(diǎn)贊這個(gè)小組件碳却,我們寫下如下代碼:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
      appBar: AppBar(
        title: Text('My Flutter'),
      ),
      body: Row(
        children: <Widget>[
          Image.asset('assets/images/2.0x/like.png', width: 20, height: 20,),
          SizedBox(width: 5,),
          Text('30')
        ],
      ),
    ));
  }
}

效果如下:

假設(shè)我們要求給這個(gè)點(diǎn)贊組件加上點(diǎn)擊事件,那么我們直接給 Row 套上 GestureDetector Widget笑旺。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
      appBar: AppBar(
        title: Text('My Flutter'),
      ),
      body: GestureDetector(
        onTap: (){
          print('onTap');
        },
        child: Row(
          children: <Widget>[
            Image.asset('assets/images/2.0x/like.png', width: 20, height: 20,),
            SizedBox(width: 5,),
            Text('30')
          ],
        ),
      ),
    ));
  }
}

點(diǎn)擊點(diǎn)贊組件確實(shí)會(huì)打印 onTap昼浦,但是如果你點(diǎn)擊了點(diǎn)贊圖標(biāo)和數(shù)字中間的白色區(qū)域,你會(huì)發(fā)現(xiàn)點(diǎn)擊事件沒有回調(diào)筒主,沒有打印关噪。

這個(gè)時(shí)候有兩種解決方法:

1. 給空白組件設(shè)置 color 屬性鸟蟹,顏色值設(shè)置透明

對(duì)于 Container 設(shè)置的 padding 可以直接設(shè)置,對(duì)于我們這里例子的 SizeBox 需要改為如下:

SizedBox(width: 15, child: Container(color: Colors.transparent,),),

為了方便測試使兔,這邊將寬度改為 15建钥。

所以對(duì)于設(shè)置 GestureDetector 的 Container,如果沒有設(shè)置 color 屬性火诸,那么點(diǎn)擊空白不會(huì)回調(diào)锦针。

2. 設(shè)置 GestureDetector 的 behavior 屬性(推薦方式)

其實(shí)如果你需要空白區(qū)域也響應(yīng)點(diǎn)擊,只需要設(shè)置一下 GestureDetector 的 behavior 屬性即可置蜀。

behavior 默認(rèn)值為 HitTestBehavior.deferToChild奈搜,我們這里將其設(shè)置為 HitTestBehavior.translucent

代碼如下:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
      appBar: AppBar(
        title: Text('My Flutter'),
      ),
      body: GestureDetector(
        behavior: HitTestBehavior.translucent,
        onTap: (){
          print('onTap');
        },
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Image.asset('assets/images/2.0x/like.png', width: 20, height: 20,),
            SizedBox(width: 15),
            Text('30')
          ],
        ),
      ),
    ));
  }
}

這里的點(diǎn)贊圖片我直接從網(wǎng)上獲取的盯荤,你測試可以用隨便一張圖片代替驗(yàn)證馋吗。或者用兩個(gè)文本來驗(yàn)證也是可以的秋秤。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末宏粤,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子灼卢,更是在濱河造成了極大的恐慌绍哎,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鞋真,死亡現(xiàn)場離奇詭異崇堰,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)涩咖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門海诲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人檩互,你說我怎么就攤上這事特幔。” “怎么了闸昨?”我有些...
    開封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵蚯斯,是天一觀的道長。 經(jīng)常有香客問我饵较,道長溉跃,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任告抄,我火速辦了婚禮撰茎,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘打洼。我一直安慰自己龄糊,他們只是感情好逆粹,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著炫惩,像睡著了一般僻弹。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上他嚷,一...
    開封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天蹋绽,我揣著相機(jī)與錄音,去河邊找鬼筋蓖。 笑死卸耘,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的粘咖。 我是一名探鬼主播蚣抗,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼瓮下!你這毒婦竟也來了翰铡?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤讽坏,失蹤者是張志新(化名)和其女友劉穎锭魔,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體路呜,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡迷捧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拣宰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片党涕。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡烦感,死狀恐怖巡社,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情手趣,我是刑警寧澤晌该,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站绿渣,受9級(jí)特大地震影響朝群,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜中符,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一姜胖、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧淀散,春花似錦右莱、人聲如沸蚜锨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽亚再。三九已至,卻和暖如春晨抡,著一層夾襖步出監(jiān)牢的瞬間氛悬,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國打工耘柱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留如捅,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓帆谍,卻偏偏與公主長得像伪朽,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子汛蝙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

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

  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5烈涮? 答:HTML5是最新的HTML標(biāo)準(zhǔn)。 注意:講述HT...
    kismetajun閱讀 27,422評(píng)論 1 45
  • HTML 5 HTML5概述 因特網(wǎng)上的信息是以網(wǎng)頁的形式展示給用戶的窖剑,因此網(wǎng)頁是網(wǎng)絡(luò)信息傳遞的載體坚洽。網(wǎng)頁文件是用...
    阿啊阿吖丁閱讀 3,828評(píng)論 0 0
  • ¥開啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個(gè)線程,因...
    小菜c閱讀 6,358評(píng)論 0 17
  • 選擇qi:是表達(dá)式 標(biāo)簽選擇器 類選擇器 屬性選擇器 繼承屬性: color西土,font讶舰,text-align,li...
    love2013閱讀 2,303評(píng)論 0 11
  • 選擇qi:是表達(dá)式 標(biāo)簽選擇器 類選擇器 屬性選擇器 繼承屬性: color需了,font跳昼,text-align,li...
    wzhiq896閱讀 1,731評(píng)論 0 2