超過(guò)百萬(wàn)的StackOverflow Flutter 問(wèn)題

老孟導(dǎo)讀:今天分享StackOverflow上高訪問(wèn)量的20大問(wèn)題,這些問(wèn)題給我一種特別熟悉的感覺(jué),我想你一定或多或少的遇到過(guò),有的問(wèn)題在stackoverflow上有幾十萬(wàn)的閱讀量,說(shuō)明很多人都遇到了這些問(wèn)題,把這些問(wèn)題整理分享給大家,每期20個(gè),每隔2周分享一次。

如何實(shí)現(xiàn)Android平臺(tái)的wrap_content 和match_parent

你可以按照如下方式實(shí)現(xiàn):

1、Width = Wrap_content Height=Wrap_content:

Wrap(
  children: <Widget>[your_child])

2、Width = Match_parent Height=Match_parent:

Container(
        height: double.infinity,
    width: double.infinity,child:your_child)

3、Width = Match_parent ,Height = Wrap_conten:

Row(
  mainAxisSize: MainAxisSize.max,
  children: <Widget>[*your_child*],
);

4、Width = Wrap_content ,Height = Match_parent:

Column(
  mainAxisSize: MainAxisSize.max,
  children: <Widget>[your_child],
);

如何避免FutureBuilder頻繁執(zhí)行future方法

錯(cuò)誤用法:

@override
Widget build(BuildContext context) {
  return FutureBuilder(
    future: httpCall(),
    builder: (context, snapshot) {
     
    },
  );
}

正確用法:

class _ExampleState extends State<Example> {
  Future<int> future;

  @override
  void initState() {
    future = Future.value(42);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: future,
      builder: (context, snapshot) {
       
      },
    );
  }
}

底部導(dǎo)航切換導(dǎo)致重建問(wèn)題

在使用底部導(dǎo)航時(shí)經(jīng)常會(huì)使用如下寫(xiě)法:

Widget _currentBody;

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: _currentBody,
    bottomNavigationBar: BottomNavigationBar(
      items: <BottomNavigationBarItem>[
        ...
      ],
      onTap: (index) {
        _bottomNavigationChange(index);
      },
    ),
  );
}

_bottomNavigationChange(int index) {
  switch (index) {
    case 0:
      _currentBody = OnePage();
      break;
    case 1:
      _currentBody = TwoPage();
      break;
    case 2:
      _currentBody = ThreePage();
      break;
  }
  setState(() {});
}

此用法導(dǎo)致每次切換時(shí)都會(huì)重建頁(yè)面。

解決辦法,使用IndexedStack

int _currIndex;

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: IndexedStack(
        index: _currIndex,
        children: <Widget>[OnePage(), TwoPage(), ThreePage()],
      ),
    bottomNavigationBar: BottomNavigationBar(
      items: <BottomNavigationBarItem>[
        ...
      ],
      onTap: (index) {
        _bottomNavigationChange(index);
      },
    ),
  );
}

_bottomNavigationChange(int index) {
  setState(() {
      _currIndex = index;
    });
}

TabBar切換導(dǎo)致重建(build)問(wèn)題

通常情況下,使用TabBarView如下:

TabBarView(
  controller: this._tabController,
  children: <Widget>[
    _buildTabView1(),
    _buildTabView2(),
  ],
)

此時(shí)切換tab時(shí),頁(yè)面會(huì)重建,解決方法設(shè)置PageStorageKey

var _newsKey = PageStorageKey('news');
var _technologyKey = PageStorageKey('technology');

TabBarView(
  controller: this._tabController,
  children: <Widget>[
    _buildTabView1(_newsKey),
    _buildTabView2(_technologyKey),
  ],
)

Stack 子組件設(shè)置了寬高不起作用

在Stack中設(shè)置100x100紅色盒子,如下:

Center(
  child: Container(
    height: 300,
    width: 300,
    color: Colors.blue,
    child: Stack(
      children: <Widget>[
        Positioned.fill(
          child: Container(
            height: 100,
            width: 100,
            color: Colors.red,
          ),
        )
      ],
    ),
  ),
)

此時(shí)紅色盒子充滿父組件,解決辦法,給紅色盒子組件包裹Center、Align或者UnconstrainedBox,代碼如下:

Positioned.fill(
  child: Align(
    child: Container(
      height: 100,
      width: 100,
      color: Colors.red,
    ),
  ),
)

如何在State類中獲取StatefulWidget控件的屬性

class Test extends StatefulWidget {
  Test({this.data});
  final int data;
  @override
  State<StatefulWidget> createState() => _TestState();
}

class _TestState extends State<Test>{

}

如下,如何在_TestState獲取到Test的data數(shù)據(jù)呢:

  1. 在_TestState也定義同樣的參數(shù),此方式比較麻煩,不推薦。
  2. 直接使用widget.data(推薦)。

default value of optional parameter must be constant

上面的異常在類構(gòu)造函數(shù)的時(shí)候會(huì)經(jīng)常遇見(jiàn),如下面的代碼就會(huì)出現(xiàn)此異常:

class BarrageItem extends StatefulWidget {
  BarrageItem(
      { this.text,
      this.duration = Duration(seconds: 3)});

異常信息提示:可選參數(shù)必須為常量,修改如下:

const Duration _kDuration = Duration(seconds: 3);

class BarrageItem extends StatefulWidget {
  BarrageItem(
      {this.text,
      this.duration = _kDuration});

定義一個(gè)常量,Dart中常量通常使用k開(kāi)頭,_表示私有,只能在當(dāng)前包內(nèi)使用,別問(wèn)我為什么如此命名,問(wèn)就是源代碼中就是如此命名的。

如何移除debug模式下右上角“DEBUG”標(biāo)識(shí)

MaterialApp(
 debugShowCheckedModeBanner: false
)

如何使用16進(jìn)制的顏色值

下面的用法是無(wú)法顯示顏色的:

Color(0xb74093)

因?yàn)镃olor的構(gòu)造函數(shù)是ARGB,所以需要加上透明度,正確用法:

Color(0xFFb74093)

FF表示完全不透明。

如何改變應(yīng)用程序的icon和名稱

鏈接:https://blog.csdn.net/mengks1987/article/details/95306508

如何給TextField設(shè)置初始值

class _FooState extends State<Foo> {
  TextEditingController _controller;

  @override
  void initState() {
    super.initState();
    _controller = new TextEditingController(text: '初始值');
  }

  @override
  Widget build(BuildContext context) {
    return TextField(
          controller: _controller,
        );
  }
}

Scaffold.of() called with a context that does not contain a Scaffold

Scaffold.of()中的context沒(méi)有包含在Scaffold中,如下代碼就會(huì)報(bào)此異常:

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('老孟'),
      ),
      body: Center(
        child: RaisedButton(
          color: Colors.pink,
          textColor: Colors.white,
          onPressed: _displaySnackBar(context),
          child: Text('show SnackBar'),
        ),
      ),
    );
  }
}

_displaySnackBar(BuildContext context) {
  final snackBar = SnackBar(content: Text('老孟'));
  Scaffold.of(context).showSnackBar(snackBar);
}

注意此時(shí)的context是HomePage的,HomePage并沒(méi)有包含在Scaffold中,所以并不是調(diào)用在Scaffold中就可以,而是看context,修改如下:

_scaffoldKey.currentState.showSnackBar(snackbar); 

或者:

Scaffold(
    appBar: AppBar(
        title: Text('老孟'),
    ),
    body: Builder(
        builder: (context) => 
            Center(
            child: RaisedButton(
            color: Colors.pink,
            textColor: Colors.white,
            onPressed: () => _displaySnackBar(context),
            child: Text('老孟'),
            ),
        ),
    ),
);

Waiting for another flutter command to release the startup lock

在執(zhí)行flutter命令時(shí)經(jīng)常遇到上面的問(wèn)題,

解決辦法一:

1、Mac或者Linux在終端執(zhí)行如下命令:

killall -9 dart

2、Window執(zhí)行如下命令:

taskkill /F /IM dart.exe

解決辦法二:

刪除flutter SDK的目錄下/bin/cache/lockfile文件。

無(wú)法調(diào)用setState

不能在StatelessWidget控件中調(diào)用了,需要在StatefulWidget中調(diào)用。

設(shè)置當(dāng)前控件大小為父控件大小的百分比

1、使用FractionallySizedBox控件

2、獲取父控件的大小并乘以百分比:

MediaQuery.of(context).size.width * 0.5

Row直接包裹TextField異常:BoxConstraints forces an infinite width

解決方法:

Row(
    children: <Widget>[
        Flexible(
            child: new TextField(),
        ),
  ],
),

TextField 動(dòng)態(tài)獲取焦點(diǎn)和失去焦點(diǎn)

獲取焦點(diǎn):

FocusScope.of(context).requestFocus(_focusNode);

_focusNode為T(mén)extField的focusNode:

_focusNode = FocusNode();

TextField(
    focusNode: _focusNode,
    ...
)

失去焦點(diǎn):

_focusNode.unfocus();

如何判斷當(dāng)前平臺(tái)

import 'dart:io' show Platform;

if (Platform.isAndroid) {
  // Android-specific code
} else if (Platform.isIOS) {
  // iOS-specific code
}

平臺(tái)類型包括:

Platform.isAndroid
Platform.isFuchsia
Platform.isIOS
Platform.isLinux
Platform.isMacOS
Platform.isWindows

Android無(wú)法訪問(wèn)http

其實(shí)這本身不是Flutter的問(wèn)題,但在開(kāi)發(fā)中經(jīng)常遇到,在Android Pie版本及以上和IOS 系統(tǒng)上默認(rèn)禁止訪問(wèn)http,主要是為了安全考慮。

Android解決辦法:

./android/app/src/main/AndroidManifest.xml配置文件中application標(biāo)簽里面設(shè)置networkSecurityConfig屬性:

<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
    <application android:networkSecurityConfig="@xml/network_security_config">
         <!-- ... -->
    </application>
</manifest>

./android/app/src/main/res目錄下創(chuàng)建xml文件夾(已存在不用創(chuàng)建),在xml文件夾下創(chuàng)建network_security_config.xml文件,內(nèi)容如下:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="system" />
        </trust-anchors>
    </base-config>
</network-security-config>

IOS無(wú)法訪問(wèn)http

./ios/Runner/Info.plist文件中添加如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    ...
    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>
</dict>
</plist>

交流

Github地址:https://github.com/781238222/flutter-do

170+組件詳細(xì)用法:http://laomengit.com

如果你對(duì)Flutter還有疑問(wèn)或者技術(shù)方面的疑惑,歡迎加入Flutter交流群(微信:laomengit)。

同時(shí)也歡迎關(guān)注我的Flutter公眾號(hào)【老孟程序員】,公眾號(hào)首發(fā)Flutter的相關(guān)內(nèi)容。

Flutter生態(tài)建設(shè)離不開(kāi)你我他,需要大家共同的努力,點(diǎn)贊也是其中的一種,如果文章幫助到了你,希望點(diǎn)個(gè)贊。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,030評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,310評(píng)論 3 415
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 175,951評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 62,796評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,566評(píng)論 6 407
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,055評(píng)論 1 322
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,142評(píng)論 3 440
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,303評(píng)論 0 288
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,799評(píng)論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,683評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,899評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,409評(píng)論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,135評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,520評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,757評(píng)論 1 282
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,528評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,844評(píng)論 2 372

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