这是我参与2022首次更文挑战的第3天,活动详情查看:2022首次更文挑战
我是谁?我在哪?我学会了什么?
跟着官网教程往下走,就莫名其妙的搞完了一个点击后自增的小demo,但是此刻不禁发出灵魂拷问。
那么今天它来了。
本文将带你重新理解flutter的基础结构,以及页面关系。
你是从Vue过来的?没关系,低门槛。
你是后端转行的?求你了,别卷前端了,后端安逸得很。(不是,欢迎.jpg)
文件与页面的关系
这里只是简单的,粗暴的是概括一下文件的关系,借此来表述是如何创建页面的。
ps: 这里说的不是路由,可以理解为用多个Widget拼成一个页面。
如果是已经入门了flutter开发,能用flutter独立布局页面的已经可以跳过这里了。
在使用Vue/React开发时,有一个词叫组件化
,我是从Vue转过来的,所以借Vue的经验去理解flutter这一块的芝士点。
先简单看个代码
// home page
import 'package:flutter/material.dart';
import 'package:learn/widgets/demo.dart';
void main() => runApp(MyApp()); // 虽然这也是dart的语法, 但我就当JavaScript看了,减少接受成本。
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: HomePage(), // 这里相当于是确认主页的布局函数
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar( // 创建一个AppBar, 即常见的顶部栏的部分
title: Text('Flutter learn'),
elevation: 10,
centerTitle: true,
),
body: ProcessDemo(), // ProcessDemo函数来自于顶部引入的demo.dart文件
/*body: Column( // 引入多个Widget时的写法
children: [
ProcessDemo(),
CheckDemo(),
],
),
*/
);
}
}
// demo.dart
import 'package:flutter/material.dart';
class ProcessDemo extends StatelessWidget {
const ProcessDemo({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(10),
child: Column(
children: [
LinearProgressIndicator(
value: .5,
valueColor: AlwaysStoppedAnimation(Colors.red),
),
SizedBox(height: 16),
Container(
width: 100,
height: 100,
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation(Colors.red),
),
),
],
),
);
}
}
复制代码
ps: 因为组件都在官网教程里有,所以直接上链接。 >> 戳链接学习
开发与多选框组件
前面刚刚说完组件都在教程里,为什么作者又要开个段落呢? 作者是不是在水字数啊?
并不是,这里不确定是不是脸黑,碰上一个没见过的好问题。
先看代码
class CheckDemo extends StatefulWidget {
const CheckDemo({Key? key}) : super(key: key);
@override
_CheckDemoState createState() => _CheckDemoState();
}
class _CheckDemoState extends State<CheckDemo> {
bool _check = false;
bool _switch = false;
@override
Widget build(BuildContext context) {
return Column(
children: [
Checkbox(
value: _check,
activeColor: Colors.red,
onChanged: (v) {
setState(() {
_check = !_check;
});
},
),
Switch(
value: _switch,
activeColor: Colors.red,
onChanged: (v) {
setState(() {
_switch = v;
});
},
),
],
);
}
}
复制代码
请问,你看到了关于两个组件在修改状态的时候的不同了吗? 你肯定看到了对吧。
在我写多选框
时,我乖巧的跟着教程写了_check = v;
,于是我得到了一个报错。
翻译过来的白话就是:
搞咩啊,为什么bool无法赋值给bool啊。 来个大腿子解释下?
Checkbox(
value: _check,
activeColor: Colors.red,
onChanged: (value) {
setState(() {
_check = value!;
});
},
)
复制代码
后面找到解决解决方法, 在布尔值后面加个!
感叹号。
有一个可为空的值,所以在使用它时,必须执行
value!