小闹钟android stu,flutter快速开发(1)知识总结

s)

1系统要求

2 设置Flutter镜像(非必须)

3获取Flutter SDK

4Android 开发环境设置

5 安装Flutter插件(Flutter Dart)

#系统要求

在windows上安装并运行Flutter要满足以下最低要求

1 操作系统:Windows 7 SP1或更新版本

2 操作空间:400MB(Android Studio的磁盘空间)

3工具:Flutter 依赖下面命令行工具

(1)Windows PowerShell 5.0

Windows 10 已经预装了这个工具

(2)Git for Windows 2.x

确保windows电脑下载安装了git工具

镜像

可以从Flutter官网上获取最新的镜像 https://flutter.dev/community/china

(Using Flutter in China)

将以下环境变量加到用户环境变量中:

当前提供的镜像地址

FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn

PUB_HOSTED_URL=https://pub.flutter-io.cn

配置环境变量

1 windows

就像平常配置环境变量一样

4faba26c63a5c345faa3fcf23a117c13.png

2mac和linux就比较好配置了

打开(或创建) $HOME/.bash_profile.

文件路径和文件名可能在您的机器上不同:比如博主mac配置的/Users/xxx/.bash_profile

添加以下配置

添加以下配置

#flutter国内用户镜像环境

export

PUB_HOSTED_URL=https://pub.flutter-io.cn

export

FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn

保存,使这个.base_profile生效

source 路径/.bash_profile

到此就配置完毕了,如果配置后不能访问,重启以下机器应该就可以了

二 AndroidStuido开发工具相关

1 切换到Android模式下

(1)

7e4b24ba1f69bdf0558dd27866d152b6.png

(2)

a3a2d5ad5a53b3d89e5e425dadebe38c.png

2 环境问题 ,工具问题 ,版本问题

>>Flutter

1 Flutter 环境变量

2 stable,beta, dev, master 建议使用stable

稳定版

3 Flutter doctor 遇到问题可以在cmd中运行这个命令进行诊断

,进而修复

>>工具 AndroidStudio

1 配置 Sdk

2 Flutter Sdk

3 Flutter,Dart 插件

三 Flutter 快速上手开发

程序的入口

Dart 中每一个app 都有一个顶级的 main() 函数

作为应用程序的入口

//Dart

main(){

}

>>>>>>>在先dart编译工具

https://dartpad.dartlang.org/

变量

Dart是类型安全的 -

它使用静态类型检查和运行时的组合,检查以确保变量的值始终与变量的静态值匹配类型。尽量类型是必须的,但某些类型注释是可选的,因为Dart会执行类型推断

#创建和分配 变量

JavaScript中无法定义变量类型。

例:

var name

='JavaScript';

在Dart中,变量必须是明确的

类型或系统能够解析的类型

例:

String name

=“dart”;

var otherName

= 'Dart';

默认值

在JavaScript中,未初始化的变量是undefined

在Dart中,未初始化的变量的初始值为null

注意: 数字在Dart 中

也被当成对象,所以只要带数字类型的未初始化的变量值都是“null'

例:

//JavaScript

var name ;

// == undefined

//Dart

var name ; //

== null

int x;

// == null

检查null 或 零

在javaScript 中 ,1 或者任何非null对象的值被视为true

在Dart中,只有布尔值的值”true“ 被视为true

从Dart 1.12开始 ,null-aware

运算符可帮助我们做null检查

”?.“ 运算符在左边为null的时候会阻断右边的调用

”??“ 运算符 主要是判断左边表达式如果未null 为其赋一个默认值

为右边的值,否则是左边的值

a59d82214f6b6cd1d33b47bdfba602d1.png

Functions

Dart 和JavaScript的函数类似 。主要区别是声明:

//javascript

function fn(){

return true;

}

//dart

fn(){

return ture;

}

#异步编程

Futures

Dart 中使用 Future来表示异步操作

在Dart 中,async函数返回一个Future,函数的主题是稍候执行 ,await

运算符用于等待Future:

声明式UI

Flutter 采用了声明性UI布局方式

Flutter 入门基础知识

如何使用Widget并将其嵌套以形成widget树?

在Flutter中,几乎所有的东西都是widget

widget是用户界面的基本构建块,您将widget组成一个层次结构,调用widget树,每个窗口widget都是嵌套在父窗口widget中,并从其父窗口继承属性,甚至应用程序对象本身也是一个组件,没有单独的“应用程序”对象。相反,根widget担任此角色

widget可以定义

~ 结构元素-如按钮或者菜单

~文本元素 - 像字体或颜色主题

~类似布局的填充或对齐的一个方向

Flutter

目录结构

400cfe833aef929d25035fb1e882849d.png

4b359f8fcf1f976a9dc05fe1cbdeeb48.png

7b13746316c5f1f9eb77a3d006b8e27e.png

图片的声明

Assets 可以被放置到任何属性文件夹中--Flutter

并没有预先定义的文件结构。我们需要在pubspec.yaml 文件中声明assets位置,然后Flutter

会把他们识别出来

举个例子,好吧

icon.png图片放到Flutter工程中,把图片(1.0x)放置到images文件夹中,并把其他分辨率的图片放在对应的文件夹中,并接上合适的比例系数:

images/icon.png

//base : 1.0x image

images/2.0x/icon.png //2.0x

image

images/3.0x/icon.png //3.0x image

接下来就可以在pubspec.yaml

文件中这样声明这个图片资源:

---> assets:

- images/icon.png

---> 现在,我们就可以借助AssetImage来访问它了

return

AssetImage('image/icon.png')

---> 也可以通过 Image Widget

直接使用

@override

Widget build(BuildContext

context){

return

Image.asset('images/icon.png')

}

如何归档Strings资源,以及如何处理不同语言

Flutter 目前没有专门的

字符串资源系统,目前最佳做法是将Strings资源作为静态字段保存在类中 。例如:

class Strings {

static String

welcomeMessage ='welcome to Flutter';

}

然后像如下方式访问它:

Text(Strings.welcomeMessage)

默认情况下,Flutter只支持美式英语字符串

。如果你要支持其他语言,请引入flutter_localizations

包。

你可能也要引入 intl包支持其他 i10n 机制,如果日期/时间格式化

dependencies:

#...

flutter_localizations

sdks:flutter

intl:

'^0.15.6

要使用flutter_localizations

包,还需要在app widget 中指定 localizationsDelegates 和 supportedLocales

e1f04627066a37a3675bfb6dbb7b1830.png

如何添加Flutter项目所需的依赖?

Flutter

使用Dart构建系统和pub包管理器来处理依赖。这些工具将Android和ios

native包装应用程序的构建委派给相应的构建系统

dependencies:

flutter:

sdk:

flutter

google_sign_in:^3.0.3

注意:在Flutter

中,虽然在Flutter项目中的Android文件夹下有Gradle文件,但只有在添加平台相关所需的依赖关系时才使用这些文件。否则,应该使用pubspec.yaml来声明用于Flutter的外部依赖项

ios也也是一样,如果你的Flutter工程中的ios文件夹中有podfile,请仅在添加ios平台相关的依赖时使用它,否则,应该使用pubspec.yaml来声明用于Flutter的外部依赖项

>>>>>>>>Flutter中查找Flutter插件的一个软件Pub

site (https://pub.dev/flutter)

谁是Flutter中的view

在Flutter中我们可以将widget当作Android ios

,RN中的view,但他们并不完全等价,但当我们试图去理解Flutter是如何工作的时候,我们可以认为他是“声明和构建UI的方式”。

但是,widget和view 有一些区别:

首先widget具有不同的生命周期:他们时不可变的,他们会存在于状态改变之前,每当widget或其他状态发生变化的时,Flutter的框架都会创建一个新的widget

是实例树。相比之下,Android/ios 视图被绘制一次,并且在调用

invalidate/setNeedDisplay之前不会重绘

此外,与view不同,Flutter的widget很轻巧,部分原因在于他的不变性,因为它本身不是视图,并且不会直接绘制任何东西,而是对ui及语义的描述

如何更新widgets

在flutter中,widget不可变的,不会直接更新。相反,我们可以通过操作widget的状态更新他们

。这就是有状态无状态widget的来源 。

statelessWidget

无状态,statefulWidget有状态

无状态widget和有状态的widget之前的区别在与statefulwidgets具有一个state对象,该对象存储状态数据并将其传递到树重建中,因此状态不会丢失

请记住以下规则:如果widget在build之外更改(例如,由于运行时用户交互),则他是有状态的。如果widget永远不会改变,一旦构建,它就是无状态的。但是,即使widget是有状态的,如果包含其他的父窗口小部件本身不对这些更改(或其他输入)做出反应,父widget仍然可以是无状态的

如何声明布局

在flutter中,我们通过编写一个widget树来声明布局

2850809b04592ca92ea2f1b009e3777f.png

如何在布局中添加或删除组件

在flutter中可以通过动态的返回一个函数表达式,该函数或表达式返回一个widget给父项,并通过布尔值控制该widget的创建

d93d056ad49c20c03166ccbe6e2f663c.png

如何对widget做动画

在Flutter

中使用动画库来包裹Widget,而不是创建一个动画widget

在Flutter 中,使用AnimationController,这是一个可以暂替、寻找、停止、反转的Animation类型。它需要一个Ticker当vsync

发生时来发送信号,并且在每帧运行时创建一个介于0和1之见的线性插值(interpolation)。我们可以创建一个或者多个的Animation

并附加给一个controller

当构建widget树时,你会把Anamation指定给你个widget的动画属性,比如FadeTransitionde

的opacity,并告诉控制器开始动画

如何绘图(Canvas draw/paint)

Flutter有自己的Canvas

API,因为它基于相同的底部渲染引擎Skia,因此,对于Android开发人员来说,在Flutter中绘制到画布是一项熟悉的任务,Flutter有两个类可以帮助我们绘制画布,CustomPaint和CustomPainer,它们实现您的算法以绘制到画布

例子:在线签名

import

'package:flutter/material.dart';

///在线签名

画笔void

main()=>runApp(MaterialApp(home:

DemoApp()));

class DemoApp extends

StatelessWidget{

Widget build(BuildContext

buildContext)=>Scaffold(body:Signature());

}

class Signature extends StatefulWidget{

SignatureState

createState()=>SignatureState();

}

class SignatureState extends State{

List _points = [];

@override Widget

build(BuildContext context) {

// TODO: implement build

return GestureDetector(

onPanUpdate: (DragUpdateDetails

details){

setState(() {

RenderBox referenceBox =

context.findRenderObject();

Offset localPosition =

referenceBox.globalToLocal(details.globalPosition);

_points =

List.from(_points)..add(localPosition);

});

},

onPanEnd:(DragEndDetails

details)=>_points.add(null)

,

child:

CustomPaint(painter:

SignaturePainter(_points),size:Size.infinite),

);

}

}

class SignaturePainter

extends CustomPainter{

SignaturePainter(this.points);

final List

points;

void paint(Canvas canvas,Size

size){

var paint =

Paint()

..color = Colors.black ..strokeCap =

StrokeCap.round ..strokeWidth=5.0;

for(int i=0

;i<points.length-1;i++){

if(points[i]!=null && points[i+1]!=null)

canvas.drawLine(points[i],points[i+1],

paint);

}

}

bool shouldRepaint(SignaturePainter

other)=>other.points !=points;

}

绘制圆形和方形

在Flutter 中,你可以使用CustomPaint 和CustomPainter

类去绘制到画布

使用customPaint Widget 在绘制阶段绘制,它实现了抽象类

customPainter,并将其传递给customPaint 的painter属性。customPaint

子类必须实现paint和shouldRepaint方法。

import

'package:flutter/material.dart';

///绘制圆形和方形void

main() =>runApp(MyApp());

class MyApp extends

StatelessWidget{

@override Widget build(BuildContext context)

{

// TODO: implement build

return new MaterialApp(

title: 'Flutter bottomNavigationBar',

theme: new

ThemeData.fallback(),

home: _MyCanvas(),

);

}

}

//Flutterclass MyCanvasPainter

extends CustomPainter{

@override void paint(Canvas canvas,

Size size) {

Paint paint = Paint();

paint.color = Colors.amber;

canvas.drawCircle(Offset(100.0,

200.0), 40.0, paint);

Paint paintRect = Paint();

paintRect.color = Colors.cyan;

Rect rect =

Rect.fromPoints(Offset(150.0,

300.0), Offset(300.0,

150.0));

canvas.drawRect(rect, paintRect);

}

@override bool shouldRepaint(MyCanvasPainter

oldDelegate) {

return false;

}

@override bool

shouldRebuildSemantics(MyCanvasPainter oldDelegate) {

return false;

}

}

class _MyCanvas extends

StatelessWidget{

@override Widget build(BuildContext context)

{

// TODO: implement build

return Scaffold(

body: CustomPaint(

painter: MyCanvasPainter(),

),

);

}

}

如何构建自定义widgets

在Flutter

中,推荐组合多个小的Widgets 来构建一个自定义的Widget(而不是扩展它)。

举个例子,如果你要构建一个customButton,并在构建器中传入它的label?那就组合Raiseon 和

label,而不是扩展Raiseon 。

例子:

class CustomButton extends

StatelessWidget{

final String label;

CustomButton(this.label);

@override Widget build(BuildContext context)

{

// TODO: implement build

return new Raiseon(onPressed: (){},child:

new Text(label));

}

// 调用使用自定义组件

@override Widget build(BuildContext context)

{

// TODO: implement build

return new

CustomButton('hell0');

}

}

如何设置Widget的透明度?

在Flutter中 如果要改变透明度,我们可以给widget包裹一个

Opacity widget 来做到这一点

如:

Opacity(

opacity :0.5,

child

:Text ('透明度50%')

)

布局与列表

(1)LinearLayout 在Flutter中等价于什么

在Android 中,使用LinearLayout

来使你的控件呈水平或垂直排列。在Flutter中,你可以使用Row或Colomn

widget来实现相同的结果

例子:

class MyApp

extends StatelessWidget{

@overrideWidget build(BuildContext context)

{

// TODO: implement build

return Row(

mainAxisAlignment: MainAxisAlignment.center,

children: [

Text('Row one'),

Text('Row Two'),

Text('Row Three'),

Text('Row Four'),

],

);

}

}

例子:

class MyColumn extends

StatelessWidget{

@overrideWidget build(BuildContext context)

{

// TODO: implement build

return Column(

mainAxisAlignment:MainAxisAlignment.center,

children: [

Text('Column one'),

Text('Column Two'),

Text('Column Three'),

Text('Column Four'),

],

);

}

}

(2)RelativeLayout在Flutter中等价于什么

RelativeLayout

用于使Widget相当于对于彼此位置排列。在Flutter中,可以通过使用Column、Row、和 Stack 的组合来实现

RelativieLayout的效果

(3)如何使用Widget在定义布局属性

在Flutter中,布局主要由专门设计用于提供布局的小部件定义,并结合控件widget及其样式属性。

e156181e5c508647671dd0a2c75e11ed.png

(4)如何分层布局

Flutter使用Stack widge控制子widget在一层

,子widgets可以完全或部分覆盖基础widgets。

Stack

控件将其子项相对于其框的边缘定位。如果你想重叠多个子窗口小部件,这个类很有用

例子:

import

'package:flutter/material.dart';

//stack widget

类似Android中的framelayout

分层布局void

main()=>runApp( new MyApp());

class MyApp extends

StatelessWidget{

@override Widget build(BuildContext context)

{

// TODO: implement build

return new MaterialApp(

home: new MyStack(),

);

}

}

class MyStack extends

StatelessWidget{

var textStyle =

TextStyle(fontSize: 32,color:

Colors.cyan,fontWeight:

FontWeight.bold);

@override Widget build(BuildContext context)

{

// TODO: implement build

return new Scaffold(

appBar: AppBar(

title: Text(

'stack widget',

style: textStyle,

),

),

body:Stack(

children: [

Container(

width: 100.0,

height: 100.0,

color: Colors.amber,

) ,

Container(

width: 80.0,

height: 80.0,

color: Colors.pink,

),

Container(

width: 50.0,

height: 50.0,

color: Colors.cyan,

)

],

),

);

}

}

(5)如何设置布局样式

Flutter

有自己的布局系统,padding、center、column、row

等都是widget,另外组件也是通常接受于布局样式的构造参数:比如 Text widget 可以使用textStyle

属性,如果要在多个位置上使用相同的文本样式,你可以创建一个textstyle 类 并将其应用于各个text widget

92d98c9fb6c1e09e6bcce07671515855.png

(6)scrollview在Flutter中等价于什么

Flutter中用Listview替代

(7)谁是Flutter的列表组件

可以用listview来实现

例子:

import

'package:flutter/material.dart';

//listview

滚动条目void

main()=>runApp(new MyApp());

class MyApp extends

StatelessWidget{

@override Widget build(BuildContext context)

{

// TODO: implement build

return new MaterialApp(

title: 'Sample List',

theme: ThemeData(

primarySwatch: Colors.cyan ),

home: SampleAppPage(),

);

}

}

class SampleAppPage extends

StatefulWidget{

SampleAppPage({Key key}):super(key:key);

@override State createState() {

// TODO: implement createStatex

return MyListApp();

}

}

class MyListApp extends State{

@override Widget build(BuildContext context)

{

return Scaffold(

appBar: AppBar(

title: Text('Sample listview'),

//这里显示titlebar要显示的 ),

body: ListView(children:_getListData()),

);

}

}

_getListData(){

List widgets = [];

for(int i=0;i<

>100;i++){

widgets.add(Padding(padding:

EdgeInsets.all(10.0),child:

Text('Row $i')));

}

return widgets;

}

(8)如何动态更新Listview

在Flutter中,如果想通过setState()方法更新widget列表,你会很快发现你的数据展示并没有什么变化,这是因为当setState()被调用的时候,Flutter渲染引擎回去检查widget树来查看是否什么地方改变了,当它得到你的listview时,它会使用一个==判断

,并且发现两个listview是相同的。没有什么东西是变了的。因此更新不是必须的。

一个更新Listview的简单办法是,在setState()中创建一个List,并把旧的list的数据拷贝给新的list

,虽然这样很简单,但是数据集很大时候,并不推荐这样做

高效的且有效的做法是:使用Listview.Builder

来构建列表。这个方法在你想要的构建动态列表,或是列表拥有大量数据时候非常好用

创建一个Listview.Builder 要接收2个参数 :列表的初始长度 和 ItemBuilder

方法

例子:

import

'package:flutter/material.dart';

//listview 动态更新数据

采用Listview.Buildervoid main()=>runApp(new

SampleApp());

class SampleApp extends

StatelessWidget{

@override Widget build(BuildContext context)

{

// TODO: implement build

return MaterialApp(

title: 'sample app',

theme: ThemeData(

primarySwatch: Colors.blue,

),

home: SampleAppPage(),

);

}

}

class SampleAppPage extends

StatefulWidget{

SampleAppPage({Key key}):super(key : key);

@override State createState() {

return _SampleAppPageState();

}

}

class _SampleAppPageState extends

State{

List widgets = [];

@override void initState() {

super.initState();

for(int i=0;i<

>100;i++){

widgets.add(getRow(i));

}

}

@override Widget build(BuildContext context)

{

// TODO: implement build

return Scaffold(

appBar: AppBar(

title: Text('AppListview state'),

),

body:ListView.builder(

itemCount: widgets.length,

itemBuilder: (BuildContext context,int position){

return getRow(position);

}),

);

}

Widget getRow(int i){

return GestureDetector(

child: Padding(

padding:

EdgeInsets.all(10.0),

child: Text('Row $i')

),

onTap: (){

setState((){

widgets.add(getRow(widgets.length+1));

print('row $i');

});

},

);

}

}

状态管理

(1)什么是statelessWidget

Flutter 中的statelessWidget

是一个不需要改变状态的widget-它没有要管理的内部状态

当您描述的界面部分不依赖于对象本身中的配置信息以及widget的buildContext时,无状态的widget

非常有用。

aboutDialog,

CircleAvator 和 Text 都是 stateLessWidget

无状态的widget的build方法通常只会在以下三种情况下调用:

1

将widget插入树种时

2

当widget的父级更改其配置时

3

当它依赖的inheritedWidget发生变化时候

(2)什么是statefullWidget

statefullWidget是可变状态的widget。使用setstate方法管理statefullWidget的状态的改变,用setState告诉Flutter框架,某个状态发生了变化,Flutter会重新运行build方法

以便应用程序可以应用最新状态

状态是在构建widget时可以同步读取的信息可能会在widget的声明周期中发生比阿奴哈。确保在状态改变时通知状态变化是widget实现者的责任。当widget可以动态更改时,需要使用statefullwidget。例如通过键入表单或移动滑块来更改widget的状态,或者,它可以随时间变化

或者 数据推送更新UI

checkbox , Radio ,

Slider , InkWell , Form 和 TextField 都是有状态的widget,

都是statefullwidget的子类

(3)什么是statefullWidget和statelessWidget的最佳实践

7ff2bc65acf6a07b50f80645f914d77a.png

路由与导航

(1)Flutter中intent等价于什么?

在Android中,intent

主要由2中使用场景:在Acitivty之间切换,已经调用外部组件。Flutter不具Intents概念。如果要使用的话,Flutter可以通过Native整合来触发Intents

Intent 调用外部组件如:相机,文件选择器等,在flutter中实现类似的功能可以借助第三方插件

官网地址:https://pub.dev/packages

(2)Flutter中如何实现不同页面中的跳转?

86e6b6127456774730bb9dcac3c0fa3f.png

b0660411bf18e5ccb4d061a0599b5ce2.png

(3)Flutter中路由跳转返回的结果?

559ed1b2d005da997401e34a4c5d317f.png

(4)如果在Flutter中处理来自外部应用程序传入的intents?

493c9fbe290c286020ce1fb6951c8d6a.png

然后 在mainactvity

中处理intnet,一旦从intent中获取到共享数据,我们就会持有它,直到Flutter在完成准备就绪时候请求它

9dd528765af1562452d7dad3e9e439ca.png

最后,在Flutter中 ,可以渲染Flutter视图时请求数据

15a40b4694eb356cb91396762dc46bcd.png

(5)怎么跳转到其他App?

在Flutter中实现这个功能,你可以创建一个原声平台的整合层,或者使用现有的plugin,例如url_launcher

线程和异步UI

(1)怎么编写异步代码

Dart有一个单线程执行模式,支持Isolate(一种在另一个线程上运行的Dart代码的方法),一个事件循环和异步编程。除非你自己创建一个Isolate,否则你的Dart代码永远运行在主UI线程,并由event

loop驱动,Flutter的 evnet loop 和ios的main

loop相似:looper是附加在主线程上的。

Dart的单线程模型,并不意味着你写的代码一定要作为阻塞操作的方式运行,从而卡住UI。相反,可以使用Dart语言提供的异步工具,例如async/await,

来实现异步操作。

举个例子:使用async/await

来让Dart帮你做一些繁重的工作,编写网络请求代码而不会挂起UI:

loadData() async

{

String dataUrl

='https://jsonplaceholder.typicode.com/posts';

http.Response response =

await http.get(dataUrl);

setState((){ //setState更新ui

这里做法类似 Android中的runOnuithread

widgets =

json.decode(response.body);

})

}

loadData()

async {

String dataUrl =

'https://jsonplaceholder.typicode.com/posts';

http.Response response = await

http.get(dataUrl);

print('test'+response.body);

setState(() {

widgets =

json.decode(response.body);

});

}

以上就是对网络操作,数据库访问,I/O操作的典型做法

Isolate是分离的运行线程,并且不和主线程的内存堆共享内存,这意味着你不能访问主线程中

的变量,或者使用setState()来更新UI,即Isolate不能共享内存。

发送网络请求,在http.get()

这个async方法中使用 await:

import

'package:flutter/material.dart';

import

'dart:convert';

import

'package:http/http.dart' as http;

loadData() async {

String dataUrl =

'https://jsonplaceholder.typicode.com/posts';

http.Response response = await

http.get(dataUrl);

print('test'+response.body);

setState(() {

widgets =

json.decode(response.body);

});

}

获取结果 用setState()更新Flutter的UI;

(4) 如何为长时间运行的任务添加一个进度条

在Flutter中对应的widget叫progressIndicator。

通过布尔值来控制是否显示进度。在任务开始时,告诉Flutter更新状态,任务结束后隐藏

(3) 如何进行网络请求

要是用http包,在pubspec.yaml

中添加依赖

dependencies:

...

http:^0.12.0+1

(2)怎么把工作放到后台线程执行

由于Flutter

是单线程并且跑着一个event

loop(就像Node.js),因此你不必担心线程管理或生成后台线程。如果让你做I/O操作,如访问磁盘或者网络请求,可以安全的使用async/await来完成

。如果你需要让cpu执行繁忙的计算密集型任务,你需要使用Isolate来避免evenet

loop.

对于I/O操作,通过关键字async把方法声明为异步方法,然后通过await关键字等待该异步方法执行完成

手势监测及触摸事件处理

(1)

如何给Flutter的widget添加点击事件的监听

Flutter中有2种方式来添加点击监听者:

1

如果widget本身支持事件监测,直接传递给他一个函数,饼子啊函数里实现相应方法。例如,raiseon widget

拥有onpRessed 参数

class

SampleApp extends

StatelessWidget{

@override Widget build(BuildContext context)

{

// TODO: implement build

return Raiseon(

onPressed: (){

print('click');

},

child: Text('Button'),

);

}

}

2

如果widget本身不支持事件监听,则在外面包裹一个GestureDetector,并给它onTap属性传递一个函数:

例子 :

class GestrueApp extends

StatelessWidget{

@overrideWidget build(BuildContext context)

{

// TODO: implement build

return Scaffold(

body: Center(

child: GestureDetector(

child: FlutterLogo(

size: 200.0,

),

onTap: (){

print('tap');

},

),

),

);

}

}

3如何处理widget上的其他手势

使用

GestureDetector,可以监听多种手势

1点击

# onTapDown

在特定位置上轻触手势接触了屏幕

#onTapUp

在特定位置产生了轻触手势,并停止接触屏幕

#onTap

产生了一个轻触手势

# onTapCancel

出发了onTapDown 但是没触发tap

2 双击

#onDoubleTap

用户在同一个位置长时间接触屏幕

3 垂直拖动

#onVerticalDragStart

接触了屏幕,并且可能会垂直移动

#onVerticalDragUpdate

接触了屏幕,并继续在垂直方向移动

#onVerticalDragEnd

之前接触了屏幕并垂直移动,并在停止接触屏幕前以某个垂直的速度移动

3 水平拖动

#onHorizontalDragStart 接触了屏幕

,并且可能会水平移动

#onHorizontalDragUpdate

接触了屏幕 ,并继续水平移动

#onHorizontalDragEnd

之前接触了屏幕 ,并水平移动的触摸点与屏幕分离

主题和文字处理

在Flutter中,只需要在文件夹中放置字体文件,并在pubspec.yaml

中引用它,就像添加图片那样

fonts:

-

family: Schyler fonts: - asset:

fonts/Schyler-Regular.ttf style: italic

然后通过如下方式使用字体:

class

MyFont extends

StatelessWidget{

@override Widget build(BuildContext context)

{

return Scaffold(

appBar: AppBar(

title: Text('Sample'),

),

body: Center(

child: Text('this is a custom font

text',

style: TextStyle(fontFamily:

'Schyler'),

),

),

);

}

}

(2) 如何在Text上定义样式

除了字体意外,你也可以给Text widget 的样式元素设置自定义值。Text

widget

接收一个TextStyle对象,你可以指定许多参数,如下:

color

decoration

decorationColor

decorationStyle

fontFamily

fontSIze

fontStyle

fontWeight

hashCode

height

inherit

letterSpacing

textBaseline

wordSpacing

(3) 如何给App设置主题

c280d611217ac0c82a14ed6e99af4460.png

adba71c2700ba9ac9a9fb8fac410bf18.png

(1) 如何设置字体样式

>表单输入与富文本

(1) 如何获取用户的输入

在Flutter

中我们使用TextField活TextFormField ,然后通过

TextEditingController来获取用户输入。

2780e00b4fa2f86f04d0b49ed9a6db5a.png

1ebf80c7a75a1000c9878bbe5db2a058.png

(2) 如何设置输入框的提示文字

在Flutter中,你可以通过向Text

Widget的装饰构造器参数设置一个inputDecoration来展示’小提示‘,伙食占位符文字

body :Center(

child

:TextField(

decoration:inputDecoration(hintText:'this is a

hint'),

),

)

(3)如何显示验证错误信息

TextField的decoration参数为他设置一个InputDecoration,我们借助inputDecoration

除了可以添加提示信息外,还可以添加错误信息 :

decoration:inputDecoration(hintText:'This is a

hint',erroText:

'错误提示')

调用硬件、第三方服务以及平台交互、通知

(1)

如何调用硬件与第三方服务

在Flutter中调用硬件与第三方服务都是可以通过集成对应的插件来完成:

1

用于访问位置信息GPS的插件:geolocator;

2

用于访问相册与相机的插件:image_picker;

3 本地存储

:用于ios的userDefaults与Android的sharedPreference插件:Shared

Preferences

plugin

4 用于访问数据的插件:SQFlite

5

用于呼唤起第三方登录FaceBook的插件:flutter_facebook_login;

6 用于推送通知的插件 :firebase_messaging

7 用于使用Firebase的插件

:firebase

plugin

关于Flutter的更多的插件,可以在(2)

如何构建与集成Native Sdk /模块

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值