一個Android開發快速入門Flutter (二)

目錄

一個Java開發快速入門Dart前端

Flutter使用簡報android

一個Android開發快速入門Flutter(一)ios

一個Android開發快速入門Flutter (二) c++

前言

    接上一篇博客,入門Flutter(一)中的內容相對來講更加全局一些,並無涉及到具體控件的使用,本篇入門會更加深刻一些,不過仍是停留在總覽的地步,不會對每個控件進行深刻探究。app

正文

如何監聽Activity中的生命週期事件

    在Android中咱們經過Activity自帶的方法或者在Application中註冊ActivityLifecycleCallbacks接口進行生命週期監聽。在Flutter中固然沒有相關的概念(由於連Activity的概念也沒有)less

    不過Flutter仍是有方法去監聽app狀態的,不然就沒辦法響應切換到後臺這種狀況了。async

    先來講說監聽方法,咱們能夠經過繼承WidgetsBindingObserver,該類中存在一個回調方法didChangeAppLifecycleState,用於表示當前應用狀態改變。(固然WidgetsBindingObserver 中還有其餘不少狀態回調,好比一個route 被push 或者pop,好比橫豎屏變化,好比用戶locales切換,是否存在內存壓力,輔助功能切換等。)ide

    具體代碼以下學習

import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';

class LifecycleWatcher extends StatefulWidget {
  @override
  _LifecycleWatcherState createState() => _LifecycleWatcherState();
}

//多重繼承了 WidgetsBindingObserver
class _LifecycleWatcherState extends State<LifecycleWatcher>
    with WidgetsBindingObserver {
  AppLifecycleState _lastLifecycleState;

  //至關於初始化
  @override
  void initState() {
    super.initState();
    //註冊應用聲明週期監聽
    WidgetsBinding.instance.addObserver(this);
  }
  //至關於銷燬
  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }
  //監聽應用聲明週期方法
  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    print("current state is $state");
    setState(() {
      _lastLifecycleState = state;
    });
  }

  @override
  Widget build(BuildContext context) {
    if (_lastLifecycleState == null)
      return Text('This widget has not observed any lifecycle changes.',
          textDirection: TextDirection.ltr);

    return Text(
        'The most recent lifecycle state this widget observed was: $_lastLifecycleState.',
        textDirection: TextDirection.ltr);
  }
}

class MyApp extends StatelessWidget {
  static const platform = const MethodChannel('app.channel.shared.data');

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      title: 'Sample App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text("Sample App"),
        ),
        body: Center(child: LifecycleWatcher()),
        //添加一個懸浮按鈕,該按鈕點擊後觸發_updateText方法
        floatingActionButton: FloatingActionButton(
          onPressed: _updateText,
          tooltip: 'Goto Next',
          child: Icon(Icons.update),
        ),
      ),
    );
  }

  /**
   * 這裏定義一個native方法,用於打開一個新的activity,這個activity是一個dialog模式的,意味着會調用當前
   * activity的 onPause,可是不會調用onStop
   */
  void _updateText() async{
    await platform.invokeMethod("gotoNext");
  }
}

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

    

  native生命週期 flutter生命週期
打開app onCreate->onStart->onResume
打開dialog actiivty onPause AppLifecycleState.inactive
關閉 dialog actiivty onResume AppLifecycleState.resumed
home onPause->onStop AppLifecycleState.inactive -> AppLifecycleState.paused
返回app onStart->onResume AppLifecycleState.inactive -> AppLifecycleState.resumed
返回鍵退出 onPause->onStop->onDestory AppLifecycleState.inactive -> AppLifecycleState.paused

    

    先看看Flutter有哪幾種狀態 (這個地方就很是困惑了,由於官方文檔上寫的和我實際測試的存在區別,基於不迷信書本的理念,我實事求是貼出觀測狀況,有錯誤還請你們指正下)測試

    AppLifecycleState.inactive  應用處於非活動狀態,而且沒有接收到用戶輸入。在Android中,這對應應用在前臺非活動狀態,好比分屏應用,電話,畫中畫應用,系統對話框或者其餘窗口。相似於onPause,可是又不徹底是,由於在返回app的時候也會先進入inactive狀態,而後再resumed。

    AppLifecycleState.paused 當應用對於用戶不可見,不響應輸入,而且在後臺運行。至關於android中的onStop 。處於這個狀態的app隨時都會進入suspending掛起狀態。

    AppLifecycleState.resumed 至關於android中的onPostResume(onResume以後執行),表示應用可見而且響應輸入.

    AppLifecycleState.suspending 應用處於掛起狀態。暫時尚未見到這種狀態。

如何在一個widget上添加onClick事件    

    在Flutter中有兩個方式來添加點擊事件:

    1.若是widget自己支持事件分發,好比RaisedButton,它有一個onPressed參數,這種狀況咱們能夠直接使用

@override
Widget build(BuildContext context) {
  return RaisedButton(
      onPressed: () {
        print("click");
      },
      child: Text("Button"));
}

    2.若是widget自己不支持事件分發,那麼就須要把這個控件包裹在一個GestureDetector控件中,而且響應onTab參數。

class SampleApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
      child: GestureDetector(
        child: FlutterLogo(
          size: 200.0,
        ),
        onTap: () {
          print("tap");
        },
      ),
    ));
  }
}

 

響應其餘手勢事件

    實際上咱們已經在前面簽名版的時候監聽過一些手勢事件了,這裏列舉一下GestureDetector可以響應的事件

    點擊:

            onTabDown -> 相似於ACTION_DOWN

            onTabUp ->  ACTION_UP

            onTab -> 點擊事件

            onTabCancel ->點擊被取消,觸發了onTabDown,可是不會觸發onTabUp 和 onTab

    雙擊:

            onDoubleTab

    長按

            onLongPress

    垂直拖動

            onVerticalDragStart  和屏幕接觸,而且可能會開始垂直的移動

            onVerticalDragUpdate  和屏幕接觸,在垂直方向上進一步移動

            onVerticalDragEnd 以前與屏幕接觸的指針再也不於屏幕接觸,而且在中止接觸時有一個移動速度

    水平拖動

            onHorizontalDragStart

            onHorizontalDragUpdate

            onHorizontalDragEnd

導入三方字體

    咱們能夠到Google Fonts下載各類字體

    首先咱們須要先準備好咱們的字體文件ttf,而且將其放入Flutter app下面,好比放在fonts文件夾中

awesome_app/
  fonts/
    Raleway-Regular.ttf
    Raleway-Italic.ttf
    RobotoMono-Regular.ttf
    RobotoMono-Bold.ttf

    和android中直接加載字體到textview中不一樣,咱們須要在pubspec.yaml文件中註冊咱們的字體.

fonts:
    - family: Raleway
          fonts:
            - asset: fonts/Raleway-Regular.ttf
            - asset: fonts/Raleway-Italic.ttf
              style: italic
    - family: RobotoMono
          fonts:
            - asset: fonts/RobotoMono-Regular.ttf
            - asset: fonts/RobotoMono-Bold.ttf
              weight: 700

    family表示字體的名字,咱們在TextStyle對象(用於肯定字體樣式的對象)的fontFamily中填入family值來使用這個字體。

    asset指向字體文件的地址。在打包時這些字體文件會被打包到應用程序中。

    同一種字體能夠有不一樣的輪廓。

        weight 用來用來表示字體的粗細,值在100到900之間,是100的整數倍。咱們能夠在TextStyle的fontWeight中設置這個值。

        style 表示字體是斜體仍是正常,能夠在TextStyle的fontStyle中指定。

    咱們刻經過在主題中設置fontFamily來改變默認字體,固然也能夠在單獨的控件中使用

MaterialApp(
  title: 'Custom Fonts',
  // Set Raleway as the default app font
  theme: ThemeData(fontFamily: 'Raleway'),
  home: MyHomePage(),
);

    或者

Text(
  'Roboto Mono sample',
  style: TextStyle(fontFamily: 'RobotoMono'),
);

    若是咱們給TextStyle設置的weight或者style沒有對應的asset,那麼系統就會自動選擇這種字體裏的一種風格。

 

如何在Flutter中使用NDK

    很遺憾,當前在Flutter中沒有辦法直接調用c++的代碼,全部c++代碼都須要通過native層的中轉,建立custom plugin或者直接MethodChannel。

如何使用Shared Preferences

    Shared_Preferences plugin

    這是一個Flutter插件,可以在NSUserDefaults(ios中的數據存儲)和Shared Preferences的功能.

如何使用SQLite

    SQFlite

如何使用消息推送

    這個目前Flutter對於Firebase仍是有插件的,可是其餘的三方推送就沒有插件了,只能本身開發或者創建Channel

結語

    至此,咱們已經入門了Flutter,隨着學習的深刻,發現Flutter並非一個簡單的UI替代方案,它已是一整套完整的開發流程。另外最近Flutter的火熱程度感受急速上升,或許真能在移動開發界掀起顛覆也說不定。另外,聽說Flutter也在向其餘平臺進軍,它的目標是整合全部前端開發(PC應用,網頁前端等等)。而且在2019年的I/O大會上還會有更多的分享。

相關文章
相關標籤/搜索