“This is the 28th day of my participation in the November Gwen Challenge. See details of the event: The Last Gwen Challenge 2021”.
- We created in shortcut
stateless Widget
orstateful Widget
Will let us create onekey
I haven’t talked about it before, so let’s talk about it.
Example 1.
We’re going to create a listView and add three cells, give it a random color, and when we click remove the first element,
class _keyDemoState extends State<keyDemo>{
List<String> names = ['1111'.'2222'.'3333'];
@override
Widget build(BuildContext context) {
return Container(
child: Scaffold(
appBar: AppBar(),
body: ListView(
children: names.map((str) {
return listCell(name: str,);
}).toList(),
),
floatingActionButton: FloatingActionButton(
onPressed: (){
names.removeAt(0);
setState(() {
});
},
tooltip: 'delete',
child: constIcon(Icons.delete), ), ) ); }}Copy the code
The style of the cell
class listCell extends StatelessWidget {
final String? name;
final Color bgcolor = Color.fromRGBO(Random().nextInt(256), Random().nextInt(256), Random().nextInt(256), 1); listCell({Key? key,this.name,}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
height: 44, child: ListTile( tileColor:bgcolor , title: Text(name!) )); }}Copy the code
We hit Delete to remove the first element, but after setState we rebuild it, and the color is again random
This is clearly not what we want. Let’s replace the cell with a statefulWidget
Click the delete
We found that the data changed, but the color did not. We deleted the color of the last one and the text of the first one.
- That’s because when you delete the first data,
Element corresponding to the Widget
It hasn’t changed; - while
Element
In the correspondingThe State reference
It hasn’t changed; - In the update
Widget
The time,Widget
It uses the sameElement
In theState
;
2. Key usage
We add a key to our statefulWidget
Click delete to get the effect we want
Let’s look at the source code
Element does not update when our [runtimeType] and [key] are unchanged. When we delete the first widget, we use the previous Element because the key is empty and the [runtimeType] is the same.
If we use random keys
After deleting
We also verify that every time our key changes, Element forces a refresh and the corresponding State is recreated
3. Key classification
Key is an abstract class with a factory constructor that returns the key
Key has two subclassesLocalKey
andGlobalKey
3.1 LocalKey
There are three main subclasses of LocalKey
-
ValueKey:
- ValueKey is used when we have a specific value as the key, such as a string, number, and so on
-
ObjectKey:
- If two models have the same type, it is not appropriate to use type as their key
- We can create a model object and use the object as the key
-
UniqueKey
- If we want to ensure that the key is unique, we can use UniqueKey;
- For example, we used random numbers to ensure that the key is different, so we can use UniqueKey;
3.2 GlobalKey
Can help us access information about a Widget, including widgets or objects such as State or Element
class GlobalKeyDemo extends StatelessWidget {
final GlobalKey<_ChildPageState> _globalKey = GlobalKey();
GlobalKeyDemo({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('GlobalKeyDemo'), ), body: ChildPage( key: _globalKey, ), floatingActionButton: FloatingActionButton( onPressed: () { _globalKey.currentState! .setState(() { _globalKey.currentState! .data ='old:'+ _globalKey.currentState! .count.toString(); _globalKey.currentState! .count++; }); }, child:constIcon(Icons.add), ), ); }}class ChildPage extends StatefulWidget {
const ChildPage({Key? key}) : super(key: key);
@override
_ChildPageState createState() => _ChildPageState();
}
class _ChildPageState extends State<ChildPage> {
int count = 0;
String data = 'hello';
@override
Widget build(BuildContext context) {
returnCenter( child: Column( children: [ Text(count.toString()), Text(data), ], ), ); }}Copy the code