• 150455

    文章

  • 1009

    评论

  • 13

    友链

  • 最近新加了换肤功能,大家多来逛逛吧~~~~
  • 喜欢这个网站的朋友可以加一下QQ群,我们一起交流技术。

一个Android开发快速入门Flutter (二)


目录

一个Java开发快速入门Dart

Flutter使用简报

一个Android开发快速入门Flutter(一)

一个Android开发快速入门Flutter (二) 

前言

    接上一篇博客,入门Flutter(一)中的内容相对来说更加全局一些,并没有涉及到具体控件的使用,本篇入门会更加深入一些,不过还是停留在总览的地步,不会对每一个控件进行深入探究。

正文

如何监听Activity中的生命周期事件

    在Android中我们通过Activity自带的方法或者在Application中注册ActivityLifecycleCallbacks接口进行生命周期监听。在Flutter中当然没有相关的概念(因为连Activity的概念也没有)

    不过Flutter还是有方法去监听app状态的,否则就没办法响应切换到后台这种情况了。

    先来说说监听方法,我们可以通过继承WidgetsBindingObserver,该类中存在一个回调方法didChangeAppLifecycleState,用于表示当前应用状态改变。(当然WidgetsBindingObserver 中还有其他很多状态回调,比如一个route 被push 或者pop,比如横竖屏变化,比如用户locales切换,是否存在内存压力,辅助功能切换等。)

    具体代码如下

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大会上还会有更多的分享。


695856371Web网页设计师②群 | 喜欢本站的朋友可以收藏本站,或者加入我们大家一起来交流技术!

0条评论

Loading...


发表评论

电子邮件地址不会被公开。 必填项已用*标注

自定义皮肤 主体内容背景
打开支付宝扫码付款购买视频教程
遇到问题联系客服QQ:419400980
注册梁钟霖个人博客