flutter - 关于 Flutter 的 Key 有一些地方我不是很了解
问题描述
我是在看了一个解释 Flutter's Key 的视频后练习的。
https://api.flutter.dev/flutter/foundation/Key-class.html
该视频展示了一个使用特定颜色更改容器位置的示例。(约 1 分 50 秒)
在视频中,statefulwidget 说没有密钥,位置不会改变。
但是我自己编写了示例代码并确认它可以在没有给有状态小部件密钥的情况下工作。
我想我写错了示例代码。下面是我写的代码。
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: KeyPractice(),
);
}
}
class StatefulColorfulTile extends StatefulWidget {
StatefulColorfulTile({@required this.color});
final Color color;
@override
_StatefulColorfulTileState createState() => _StatefulColorfulTileState();
}
class _StatefulColorfulTileState extends State<StatefulColorfulTile> {
@override
Widget build(BuildContext context) {
return Container(
width: 100,
height: 100,
color: widget.color,
);
}
}
class KeyPractice extends StatefulWidget {
@override
_KeyPracticeState createState() => _KeyPracticeState();
}
class _KeyPracticeState extends State<KeyPractice> {
List<Widget> tiles;
@override
void initState() {
super.initState();
tiles = [
StatefulColorfulTile(
color: Colors.blueAccent,
),
StatefulColorfulTile(
color: Colors.amber,
),
];
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Row(
children: tiles,
),
),
floatingActionButton: FloatingActionButton(
child: Icon(
Icons.autorenew,
),
onPressed: () {
setState(() {
tiles.insert(1, tiles.removeAt(0));
});
},
),
);
}
}
上述代码相互交换位置。
当视频中的有状态小部件未分配键时,小部件如何相互重新定位的示例会发生什么?
而且我知道该密钥仅适用于 Stateful 小部件,Stateless 是否使用该密钥?
而且我知道 Key 仅适用于 Stateful 小部件。我想知道无状态小部件是否使用密钥。
如果我理解错了,请教我。
解决方案
您将颜色存储在State
of 中KeyPractice
。他们使用的示例将其存储在State
孩子的 中,在您的情况下:StatefulColorfulTile
。
下面是使用键正确重新定位小部件的示例,就像您尝试做的那样。我的示例最终与这篇中等文章中显示的非常相似。在此处删除键可防止小部件反映颜色交换,但使用键可实现预期行为。
import 'package:flutter/material.dart';
import 'dart:math';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: KeyPractice(),
);
}
}
class StatefulColorfulTile extends StatefulWidget {
StatefulColorfulTile({Key key}) : super(key: key);
@override
_StatefulColorfulTileState createState() => _StatefulColorfulTileState();
}
class _StatefulColorfulTileState extends State<StatefulColorfulTile> {
final Color myColor = UniqueColorGenerator.getColor();
@override
Widget build(BuildContext context) {
return Container(
width: 100,
height: 100,
color: myColor,
);
}
}
class KeyPractice extends StatefulWidget {
@override
_KeyPracticeState createState() => _KeyPracticeState();
}
class _KeyPracticeState extends State<KeyPractice> {
List<Widget> tiles;
@override
void initState() {
super.initState();
tiles = [
StatefulColorfulTile(key: UniqueKey()),
StatefulColorfulTile(key: UniqueKey()),
];
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Row(
children: tiles,
),
),
floatingActionButton: FloatingActionButton(
child: Icon(
Icons.autorenew,
),
onPressed: () {
setState(() {
tiles.insert(1, tiles.removeAt(0));
});
},
),
);
}
}
class UniqueColorGenerator {
static Random random = new Random();
static Color getColor() {
return Color.fromARGB(255, random.nextInt(255), random.nextInt(255), random.nextInt(255));
}
}
推荐阅读
- javascript - 有没有办法将包含日期的字符串数组从服务器端传递到客户端?
- angular - 重置多个字段后如何只发送一个请求?
- javascript - 如何使用 javascript 将文件上传到 GCS?
- html - 如何使用线性渐变实现两个选项卡
- python - ValueError:预期的 2D 数组,得到了标量数组:array=11
- android - Appcelerator-Titanium - 当应用程序在后台/关闭时不接收 fcm 数据推送消息
- python - Dataflow BigQuery 插入作业因大数据集而立即失败
- html - iframe 表结构的替代方案
- android - 材质对话框更改文本大小
- python - Python:ConnectionError:抓取特定网站时“连接中止”