Flutter完整开发实战详解(一、Dart语言和Flutter基础) _ 掘金技术征文

}

2.4、Flutter

Flutter 中支持 async/await如下代码所示async/await 其实只是语法糖,最终会编译为 Flutter 中返回 Future 对象,之后通过 then 可以执行下一步。如果返回的还是 Future 便可以 then().then.() 的流式操作了 。

///模拟等待两秒,返回OK
request() async {
await Future.delayed(Duration(seconds: 1));
return “ok!”;
}

///得到"ok!"后,将"ok!“修改为"ok from request”
doSomeThing() async {
String data = await request();
data = “ok from request”;
return data;
}

///打印结果
renderSome() {
doSomeThing().then((value) {
print(value);
///输出ok from request
});
}

  • Flutter 中 setState 很有 React Native 的既视感,Flutter 中也是通过 State 跨帧实现管理数据状态的,这个后面会详细讲到。

  • Flutter 中一切皆 Widget 呈现,通过 build方法返回 Widget,这也是和 React Native 中,通过 render 函数返回需要渲染的 component 一样的模式。

  • Stream 对应的 async* / yield 也可以用于异步,这个后面会说到。

3、Flutter Widget

在 Flutter 中一切的显示都是 Widget ,Widget 是一切的基础,利用响应式模式进行渲染。

我们可以通过修改数据,再用setState 设置数据,Flutter 会自动通过绑定的数据更新 Widget , 所以你需要做的就是实现 Widget 界面,并且和数据绑定起来

Widget 分为 有状态无状态 两种,在 Flutter 中每个页面都是一帧,无状态就是保持在那一帧,而有状态的 Widget 当数据更新时,其实是创建了新的 Widget,只是 State 实现了跨帧的数据同步保存。

这里有个小 Tip ,当代码框里输入 stl 的时候,可以自动弹出创建无状态控件的模板选项,而输入 stf 的时,就会弹出创建有状态 Widget 的模板选项。

代码格式化的时候,括号内外的逗号都会影响格式化时换行的位置。

如果觉得默认换行的线太短,可以在设置-Editor-Code Style-Dart-Wrapping and Braces-Hard wrap at 设置你接受的数值。

3.1、无状态StatelessWidget

直接进入主题,如下下代码所示是无状态 Widget 的简单实现。继承 StatelessWidget,通过 build 方法返回一个布局好的控件。可能现在你还对 Flutter 的内置控件不熟悉,but Don’t worry , take it easy ,后面我们就会详细介绍这里你只需要知道,一个无状态的 Widget 就是这么简单。

Widget 和 Widget 之间通过 child: 进行嵌套。其中有的 Widget 只能有一个 child,比如下方的 Container ;有的 Widget 可以多个 child ,也就是children,比如` Column 布局,下方代码便是 Container Widget 嵌套了 Text Widget。

import ‘package:flutter/material.dart’;

class DEMOWidget extends StatelessWidget {
final String text;

//数据可以通过构造方法传递进来
DEMOWidget(this.text);

@override
Widget build(BuildContext context) {
//这里返回你需要的控件
//这里末尾有没有的逗号,对于格式化代码而已是不一样的。
return Container(
//白色背景
color: Colors.white,
//Dart语法中,?? 表示如果text为空,就返回尾号后的内容。
child: Text(text ?? “这就是无状态DMEO”),
);
}
}

3.2、有状态StatefulWidget

继续直插主题,如下代码,是有状态的widget的简单实现,你需要创建管理的是主要是 State , 通过 State 的 build 方法去构建控件。在 State 中,你可以动态改变数据,在 setState 之后,改变的数据会触发 Widget 重新构建刷新,而下方代码中,是通过延两秒之后,让文本显示为 “这就变了数值”

如下代码还可以看出,State 中主要的声明周期有 :

  • initState :初始化,理论上只有初始化一次,第二篇中会说特殊情况下。
  • didChangeDependencies:在 initState 之后调用,此时可以获取其他 State 。
  • dispose :销毁,只会调用一次。

看到没,Flutter 其实就是这么简单!你的关注点只要在:创建你的 StatelessWidget 或者 StatefulWidget 而已。你需要的就是在 build 中堆积你的布局,然后把数据添加到 Widget 中,最后通过 setState 改变数据,从而实现画面变化。

import ‘dart:async’;
import ‘package:flutter/material.dart’;

class DemoStateWidget extends StatefulWidget {

final String text;

通过构造方法传值
DemoStateWidget(this.text);

///主要是负责创建state
@override
_DemoStateWidgetState createState() => _DemoStateWidgetState(text);
}

class _DemoStateWidgetState extends State {

String text;

_DemoStateWidgetState(this.text);

@override
void initState() {
///初始化,这个函数在生命周期中只调用一次
super.initState();
///定时1秒
new Future.delayed(const Duration(seconds: 1), () {
setState(() {
text = “这就变了数值”;
});
});
}

@override
void dispose() {
///销毁
super.dispose();
}

@override
void didChangeDependencies() {
///在initState之后调 Called when a dependency of this [State] object changes.
super.didChangeDependencies();
}

@override
Widget build(BuildContext context) {
return Container(
child: Text(text ?? “这就是有状态DMEO”),
);
}
}

4、Flutter 布局

Flutter 中拥有需要将近30种内置的 布局Widget,其中常用有 Container、Padding、Center、Flex、Stack、Row、Column、ListView 等,下面简单讲解它们的特性和使用。

类型作用特点
Container只有一个子 Widget。默认充满,包含了padding、margin、color、宽高、decoration 等配置。
Padding只有一个子 Widget。只用于设置Padding,常用于嵌套child,给child设置padding。
Center只有一个子 Widget。只用于居中显示,常用于嵌套child,给child设置居中。
Stack可以有多个子 Widget。 子Widget堆叠在一起。
Column可以有多个子 Widget。垂直布局。
Row可以有多个子 Widget。水平布局。
Expanded只有一个子 Widget。在 Column 和 Row 中充满。
ListView可以有多个子 Widget。自己意会吧。
  • Container :最常用的默认控件,但是实际上它是由多个内置控件组成的模版,只能包含一个child,支持 padding,margin,color,宽高,decoration(一般配置边框和阴影)等配置,在 Flutter 中,不是所有的控件都有 宽高、padding、margin、color 等属性,所以才会有 Padding、Center 等 Widget 的存在。

new Container(
///四周10大小的maring
margin: EdgeInsets.all(10.0),
height: 120.0,
width: 500.0,
///透明黑色遮罩
decoration: new BoxDecoration(
///弧度为4.0
borderRadius: BorderRadius.all(Radius.circular(4.0)),
///设置了decoration的color,就不能设置Container的color。
color: Colors.black,
///边框
border: new Border.all(color: Color(GSYColors.subTextColor), width: 0.3)),
child:new Text(“666666”));

  • Column、Row 绝对是必备布局, 横竖布局也是日常中最常见的场景。如下方所示,它们常用的有这些属性配置:主轴方向是 start 或 center 等;副轴方向方向是 start 或 center 等;mainAxisSize 是充满最大尺寸,或者只根据子 Widget 显示最小尺寸。

//主轴方向,Column的竖向、Row我的横向
mainAxisAlignment: MainAxisAlignment.start,
//默认是最大充满、还是根据child显示最小大小
mainAxisSize: MainAxisSize.max,
//副轴方向,Column的横向、Row我的竖向
crossAxisAlignment :CrossAxisAlignment.center,

  • Expanded 在 Column 和 Row 中代表着平均充满的作用,当有两个存在的时候默认均分充满。同时页可以设置 flex 属性决定比例。

new Column(
///主轴居中,即是竖直向居中
mainAxisAlignment: MainAxisAlignment.center,
///大小按照最小显示
mainAxisSize : MainAxisSize.min,
///横向也居中
crossAxisAlignment : CrossAxisAlignment.center,
children: [
///flex默认为1
new Expanded(child: new Text(“1111”), flex: 2,),
new Expanded(child: new Text(“2222”)),
],
);

接下来我们来写一个复杂一些的控件,首先我们创建一个私有方法_getBottomItem,返回一个 Expanded Widget,因为后面我们需要将这个方法返回的 Widget 在 Row 下平均充满。

如代码中注释,布局内主要是现实一个居中的Icon图标和文本,中间间隔5.0的 padding:

///返回一个居中带图标和文本的Item
_getBottomItem(IconData icon, String text) {
///充满 Row 横向的布局
return new Expanded(
flex: 1,
///居中显示
child: new Center(
///横向布局
child: new Row(
///主轴居中,即是横向居中
mainAxisAlignment: MainAxisAlignment.center,
///大小按照最大充满
mainAxisSize : MainAxisSize.max,
///竖向也居中
crossAxisAlignment : CrossAxisAlignment.center,
children: [
///一个图标,大小16.0,灰色
new Icon(
icon,
size: 16.0,
color: Colors.grey,
),
///间隔
new Padding(padding: new EdgeInsets.only(left:5.0)),
///显示文本
new Text(
text,
//设置字体样式:颜色灰色,字体大小14.0
style: new TextStyle(color: Colors.grey, fontSize: 14.0),
//超过的省略为…显示
overflow: TextOverflow.ellipsis,
//最长一行
maxLines: 1,
),
],
),
),
);
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

接着我们把上方的方法,放到新的布局里,如下流程和代码:

  • 首先是 Container包含了Card,用于快速简单的实现圆角和阴影。
  • 然后接下来包含了FlatButton实现了点击,通过Padding实现了边距。
  • 接着通过Column垂直包含了两个子Widget,一个是Container、一个是Row
  • Row 内使用的就是_getBottomItem方法返回的 Widget ,效果如下图。

@override
Widget build(BuildContext context) {
return new Container(
///卡片包装
child: new Card(
///增加点击效果
child: new FlatButton(
onPressed: (){print(“点击了哦”);},
child: new Padding(
padding: new EdgeInsets.only(left: 0.0, top: 10.0, right: 10.0, bottom: 10.0),
child: new Column(
mainAxisSize: MainAxisSize.min,
children: [
///文本描述
new Container(
child: new Text(
“这是一点描述”,
style: TextStyle(
color: Color(GSYColors.subTextColor),
fontSize: 14.0,
),
///最长三行,超过 … 显示
maxLines: 3,
overflow: TextOverflow.ellipsis,
),
margin: new EdgeInsets.only(top: 6.0, bottom: 2.0),
alignment: Alignment.topLeft),
new Padding(padding: EdgeInsets.all(10.0)),

///三个平均分配的横向图标文字
new Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_getBottomItem(Icons.star, “1000”),
_getBottomItem(Icons.link, “1000”),
_getBottomItem(Icons.subject, “1000”),
],
),
],
),
))),
);
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Flutter 中,你的布局很多时候就是这么一层一层嵌套出来的,当然还有其他更高级的布局方式,这里就先不展开了。

5、Flutter 页面

Flutter 中除了布局的 Widget,还有交互显示的 Widget 和完整页面呈现的Widget,其中常见的有 _MaterialApp、Scaffold、Appbar、Text、Image、FlatButton_等,下面简单介绍这些 Wdiget,并完成一个页面。

类型作用特点
MaterialApp一般作为APP顶层的主页入口,可配置主题,多语言,路由等
Scaffold一般用户页面的承载Widget,包含appbar、snackbar、drawer等material design的设定。
Appbar一般用于Scaffold的appbar ,内有标题,二级页面返回按键等,当然不止这些,tabbar等也会需要它 。
Text显示文本,几乎都会用到,主要是通过style设置TextStyle来设置字体样式等。
RichText富文本,通过设置TextSpan,可以拼接出富文本场景。
TextField文本输入框 :new TextField(controller: //文本控制器, obscureText: "hint文本");
Image图片加载: new FadeInImage.assetNetwork( placeholder: "预览图", fit: BoxFit.fitWidth, image: "url");
FlatButton按键点击: new FlatButton(onPressed: () {},child: new Container());

那么再次直插主题实现一个简单完整的页面试试。如下方代码:

  • 首先我们创建一个StatefulWidget:DemoPage
  • 然后在_DemoPageState 中,通过build创建了一个Scaffold
  • Scaffold内包含了一个AppBar和一个ListView
  • AppBar类似标题了区域,其中设置了 title为 Text Widget。
  • body是ListView,返回了20个之前我们创建过的 DemoItem Widget。

import ‘package:flutter/material.dart’;

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助

因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
中…(img-vQTIQ0SV-1715530767014)]

[外链图片转存中…(img-JCT4EZpp-1715530767016)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值