Flutter 學習:基礎文檔

Views
在flutter中,什麼相當於一個View呢?
在安卓中,View時顯示在屏幕上最基礎的部分,包括Buttons,toolbars, and inputs, 這些都是一個View的子控件。而在flutter中,Widget相當於View。Widgets雖然跟Android裏的Views不完全一樣,本質上是一樣的。
但是,這些與View有一些區別。首先,小部件具有不同的生命週期:它們是不可變的,只有在需要更改時才存在。每當窗口小部件或其狀態發生變化時,Flutter的框架都會創建一個新的窗口小部件實例樹。相比之下,Android視圖被繪製一次,並且在調用invalidate之前不會重繪    


Flutter的小部件很輕巧,部分原因在於它們的不變性。因爲它們本身不是視圖,並且不是直接繪製任何東西,而是對UI及其語義的描述,這些描述被“誇大”到引擎蓋下的實際視圖對象中。

這些是實現Material Design準則的小部件。 Material Design是一個靈活的設計系統,適用於所有平臺,包括iOS。

怎樣刷新Widgets的顯示?


在Android中,您可以通過直接更改視圖來更新視圖。但是,在Flutter中,窗口小部件是不可變的,不會直接更新,而是必須使用窗口小部件的狀態。

這就是有狀態和無狀態小部件的概念來源。 StatelessWidget聽起來就像是一個沒有狀態信息的小部件。

當您描述的用戶界面部分不依賴於對象中的配置信息時,StatelessWidgets非常有用。

例如,在Android中,這類似於將帶有徽標的ImageView放置。徽標在運行時不會改變,因此請在Flutter中使用StatelessWidget。

如果要根據在進行HTTP調用或用戶交互後收到的數據動態更改UI,則必須使用StatefulWidget並告訴Flutter框架該窗口小部件的狀態已更新,以便它可以更新該窗口小部件。

這裏需要注意的重要一點是,無狀態和有狀態小部件的行爲都是相同的。它們重建每一幀,區別在於StatefulWidget有一個State對象,它跨幀存儲狀態數據並恢復它。

如果您有疑問,那麼請始終記住此規則:如果窗口小部件發生更改(例如,由於用戶交互),則它是有狀態的。但是,如果窗口小部件對更改做出反應,則包含父窗口小部件仍然可以是無狀態的,如果它本身不會對更改做出反應。

以下示例顯示如何使用StatelessWidget。常見的StatelessWidget是Text小部件。如果你看一下Text小部件的實現,你會發現它是StatelessWidget的子類。

Text(
  'I like Flutter!',
  style: TextStyle(fontWeight: FontWeight.bold),
);


正如您所看到的,Text Widget沒有與之關聯的狀態信息,它呈現了在其構造函數中傳遞的內容,僅此而已。

但是,如果你想讓“I Like Flutter”動態變化,例如點擊FloatingActionButton會怎樣?

要實現此目的,請將Text小部件包裝在StatefulWidget中,並在用戶單擊按鈕時更新它。
import 'package:flutter/material.dart';

void main() {
  runApp(SampleApp());
}

class SampleApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Sample App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: SampleAppPage(),
    );
  }
}

class SampleAppPage extends StatefulWidget {
  SampleAppPage({Key key}) : super(key: key);

  @override
  _SampleAppPageState createState() => _SampleAppPageState();
}

class _SampleAppPageState extends State<SampleAppPage> {
  // Default placeholder text
  String textToShow = "I Like Flutter";

  void _updateText() {
    setState(() {
      // update the text
      textToShow = "Flutter is Awesome!";
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Sample App"),
      ),
      body: Center(child: Text(textToShow)),
      floatingActionButton: FloatingActionButton(
        onPressed: _updateText,
        tooltip: 'Update Text',
        child: Icon(Icons.update),
      ),
    );
  }
}

我們應該怎樣放置 widgets? Where is my XML layout file?


在之前Android開發,你一般是以XML的形式來定義佈局,但是在flutter裏是以widget tree的形式
@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text("Sample App"),
    ),
    body: Center(
      child: MaterialButton(
        onPressed: () {},
        child: Text('Hello'),
        padding: EdgeInsets.only(left: 10.0, right: 10.0),
      ),
    ),
  );
}

如何自定義小部件Widget


在Android中,我們一般使用的控件都是View的子類,或使用預先存在的視圖來覆蓋和實現實現所需行爲的方法。

在Flutter中,通過組合較小的小部件(而不是擴展它們)來構建自定義小部件。 它有點類似於在Android中實現自定義ViewGroup,其中所有構建塊都已存在,但您提供了不同的行爲 - 例如,自定義佈局邏輯。

例如,如何構建一個在構造函數中採用標籤的CustomButton? 創建一個CustomButton,它使用標籤組成RaisedButton,而不是通過擴展RaisedButton
class CustomButton extends StatelessWidget {
  final String label;

  CustomButton(this.label);

  @override
  Widget build(BuildContext context) {
    return RaisedButton(onPressed: () {}, child: Text(label));
  }
}


在FLutter中有類似Intents的東東嗎?


在Android中,Intents有兩個主要用例:在Activities之間導航,以及與組件通信。另一方面,Flutter沒有意圖的概念,儘管你仍然可以通過本機集成(使用插件)啓動意圖。

在FLutter裏面沒有直接的Activity和Fragment;相反,在Flutter中,您可以使用導航器和路徑在屏幕之間導航,所有這些都在同一個Activity中。

路徑是應用程序的“屏幕”或“頁面”的抽象,導航器是管理路徑的窗口小部件。路線粗略地映射到活動,但它沒有相同的含義。導航器可以推送和彈出路徑以在屏幕之間移動。導航器的工作方式類似於堆棧,您可以在其上推送()要導航到的新路由,並且當您想要“返回”時可以從中彈出()路由。

在Android中,您在應用程序的AndroidManifest.xml中聲明您的活動。

在Flutter中,您有幾個選項可以在頁面之間導航:

指定路徑名稱的映射。 (MaterialApp)
直接導航到路線。 (WidgetApp)
以下示例構建一個Map


void main() {
  runApp(MaterialApp(
    home: MyAppHome(), // becomes the route named '/'
    routes: <String, WidgetBuilder> {
      '/a': (BuildContext context) => MyPage(title: 'page A'),
      '/b': (BuildContext context) => MyPage(title: 'page B'),
      '/c': (BuildContext context) => MyPage(title: 'page C'),
    },
  ));
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章