2018-03-03 | learn

[翻译] Flutter for Android part 3

https://flutter.io/flutter-for-android/#working-with-text

Working with Text

如何自定义 Text widgets 字体

Android 开发中(比如 Android O),你要创建好字体资源文件,并将它赋值给 Textview 的 FontFamily 属性。

Flutter 需要两个步骤:

  1. 首先将字体文件复制到项目(最佳实践是创建一个 asset 文件夹扔里边)
  2. 然后在 pubspec.yaml 配置文件中声明使用

    1
    2
    3
    4
    5
    fonts:
    - family: MyCustomFont
    fonts:
    - asset: fonts/MyCustomFont.ttf
    - style: italic
  3. 最后在代码中实用
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    @override
    Widget build(BuildContext context) {
    return new Scaffold(
    appBar: new AppBar(
    title: new Text("Sample App"),
    ),
    body: new Center(
    child: new Text(
    'This is a custom font text',
    style: new TextStyle(fontFamily: 'MyCustomFont'),
    ),
    ),
    );
    }

    如何为 Text widgets 设置样式

    能设的样式那可多了去了
    TextWidget 的 style 属性接受一个 TextStyle 对象,比如下面这些属性:
  • color
  • decoration
  • decorationColor
  • decorationStyle
  • fontFamily
  • fontSize
  • fontStyle
  • fontWeight
  • hashCode
  • height
  • inherit
  • letterSpacing
  • textBaseline
  • wordSpacing

Form Input

什么对应 Input 的 “hint”

构造一个 InputDecoration 对象传给Text Widget 的 decoration 属性

1
2
3
4
5
body: new Center(
child: new TextField(
decoration: new InputDecoration(hintText: "This is a hint"),
)
)

如何显示验证错误提示

错误提示我们也用 InputDecoration 实现。当然你可不想界面刚出来就提示错误对吧,我们得在用户输入错误数据后再显示错误提示,只要动态的更新 InputDecoration 即可实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import 'package:flutter/material.dart';

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

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

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

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

class _SampleAppPageState extends State<SampleAppPage> {
String _errorText;

@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Sample App"),
),
body: new Center(
child: new TextField(
onSubmitted: (String text) {
setState(() {
if (!isEmail(text)) {
_errorText = 'Error: This is not an email';
} else {
_errorText = null;
}
});
},
decoration: new InputDecoration(hintText: "This is a hint", errorText: _getErrorText()),
),
),
);
}

_getErrorText() {
return _errorText;
}

bool isEmail(String em) {
String emailRegexp =
r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$';

RegExp regExp = new RegExp(p);

return regExp.hasMatch(em);
}
}

Flutter Plugins

如何访问 GPS 传感器

To access the GPS sensor you can use the community plugin https://pub.dartlang.org/packages/location

如何访问 Camera

A popular community plugin to access the camera is https://pub.dartlang.org/packages/image_picker

如何使用 Facebook 登录

To access Facebook Connect functionality you can use https://pub.dartlang.org/packages/flutter_facebook_connect .

如何自己实现 native 集成

If there is platform specific functionality that Flutter or its community Plugins are missing then you can build your own following this tutorialhttps://flutter.io/developing-packages/ .

总的来说,Flutter plugin 框架用起来很像 Android 里的 EventBus:你发送一个消息,等待 receiver 处理完毕,再将结果传回给你,只不过 Flutter 的 receiver 变成了 iOS 或是 Android。

如何使用 NDK

得自定义 plugin,先和你的 android 应用通信,等待它去执行 jni 方法,再把结果传回来。

Themes

如何为 Material-styled 应用设置主题

Flutter 已经为我们实现好了 MaterialDesign,并设置好了大部分样式。Android 里使用 AndroidManifest.xml 控制主题样式,而 Flutter 的主题是在顶级 Widget 里声明的。
你可以将一个 MaterialApp 对象声明为整个应用的入口。它包含一系列实现 MaterialDesign 所需的组件。继承自 WidgetsApp,并实现了 Material 相关的功能。

不需要 MaterialDesign 的话,直接使用 WidgetsApp 即可。

构建 MaterialApp 时,传入定义好的 ThemeData 即可指定样式:

1
2
3
4
5
6
7
8
9
10
11
12
13
class SampleApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Sample App',
theme: new ThemeData(
primarySwatch: Colors.blue,
textSelectionColor: Colors.red
),
home: new SampleAppPage(),
);
}
}

Databases and local storage

如何访问 Shared Preferences ?

使用 Shared Preferences plugin Shared_Preferences

除了 Android 使用的 SharePreferences,给他还提供 iOS 的 NSUserDefaults。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() {
runApp(
new MaterialApp(
home: new Scaffold(
body: new Center(
child: new RaisedButton(
onPressed: _incrementCounter,
child: new Text('Increment Counter'),
),
),
),
),
);
}

_incrementCounter() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
int counter = (prefs.getInt('counter') ?? 0) + 1;
print('Pressed $counter times.');
prefs.setInt('counter', counter);
}

如何访问 SQLite ?

使用 SQFlite plugin SQFlite

Notifications

如何发送 Notifications

广告时间 : Firebase_Messaging plugin Firebase_Messaging