Open In App

Flutter – Concept of Key in Widgets

Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we will study Keys and when and where to use them. So you may ask what are keys? Well, Keys are the ones to preserve state when widgets move around the widget tree. It is used to preserve the user scroll location or keeping state when modifying a collection.  Key’s aren’t needed if the entire widget subtree is stateless. Now let us study when to use the keys.

As we know that we use keys to preserve states when widgets move around the widget subtree. So, basically, keys are not needed in a stateless widget but would be needed in a Stateful widget.

To explain the keys we will create a basic application in which on tapping the button the boxes will swap the colors. The values of the colors would be stored using the keys.  The following code is of the application created without the use of keys.

Stateless Widget Tree:

Here in this code, we have created the application using the stateless widget. A class PositionedTiles is created here. The comment you are seeing in this code is for the unique color generate to generate the colors for the boxes randomly. On tapping the button the swapTiles function gets activated then the swapping takes place. The onTap button is the smiley face at the bottom.

Dart




import 'package:flutter/material.dart';
import 'dart:math';
  
void main() => runApp(new MaterialApp(home: PositionedTiles()));
  
class PositionedTiles extends StatefulWidget{
  @override
  State<StatefulWidget> createState() => PositionedTilesState();
}
  
class PositionedTilesState extends State<PositionedTiles>{
  late List<Widget> tiles;
  
  @override
  void initState(){
    super.initState();
    tiles = [
      StatelessColorfulTile(),
      StatelessColorfulTile(),
    ];
  }
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("GEEKSFORGEEKS"),
        backgroundColor: Colors.green,
      ) ,
      body: SafeArea(child: Row(children: tiles)),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.sentiment_very_satisfied), onPressed: swapTiles),
    );
  }
  
  swapTiles(){
    setState(() {
      tiles.insert(1, tiles.removeAt(0));
    });
  }
}
  
class StatelessColorfulTile extends StatelessWidget {
  Color myColor = UniqueColorGenerator.getColor();
  @override
  Widget build(BuildContext context) {
    return Container(
        color: myColor, child: Padding(padding: EdgeInsets.all(70.0)));
  }
}
  
//this code snippet tells you how UniqueColorGenerator works
class UniqueColorGenerator {
  static List colorOptions = [
    Colors.blue,
    Colors.red,
    Colors.green,
    Colors.yellow,
    Colors.purple,
    Colors.orange,
    Colors.indigo,
    Colors.amber,
    Colors.black,
  ];
  static Random random = new Random();
  static Color getColor() {
    if (colorOptions.length > 0) {
      return colorOptions.removeAt(random.nextInt(colorOptions.length));
    } else {
      return Color.fromARGB(random.nextInt(256), random.nextInt(256),
          random.nextInt(256), random.nextInt(256));
    }
  }
}


Output:

Stateless Widget Tree

Here you can see that the colors are changing but when we would change it to the Stateful widget the code will work correctly but nothing will be shown on the application. But as we use the keys here in the Stateful widget the application will work fine. The following code shown below is direct with the keys. 

Stateful Widget Tree:

Here in this code, you can see we have used the keys feature here, because of which the application is working fine. The rest of the code is the same, only the Key feature is newly added here.

Dart




import 'package:flutter/material.dart';
import 'dart:math';
  
void main() => runApp(new MaterialApp(home: PositionedTiles()));
  
class PositionedTiles extends StatefulWidget{
  @override
  State<StatefulWidget> createState() => PositionedTilesState();
}
  
class PositionedTilesState extends State<PositionedTiles>{
  late List<Widget> tiles;
  
  @override
  void initState(){
    super.initState();
    tiles = [
      StatefulColorfulTile(key: UniqueKey()),
      StatefulColorfulTile(key: UniqueKey()),
    ];
  }
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
        title: Text("GEEKSFORGEEKS"),
        backgroundColor: Colors.green,
        ) ,
      body: SafeArea(child: Row(children: tiles)),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.sentiment_very_satisfied), onPressed: swapTiles),
    );
  }
  
  swapTiles(){
    setState(() {
      tiles.insert(1, tiles.removeAt(0));
    });
  }
}
  
class StatefulColorfulTile extends StatefulWidget {
  StatefulColorfulTile({required Key key}) : super(key: key);
  @override
  State<StatefulWidget> createState() => StatefulColorfulTileState();
}
class StatefulColorfulTileState extends State<StatefulColorfulTile> {
  late Color myColor;
  @override
  void initState() {
    super.initState();
    myColor = UniqueColorGenerator.getColor();
  }
  @override
  Widget build(BuildContext context) {
    return Container(
        color: myColor,
        child: Padding(
          padding: EdgeInsets.all(70.0),
        ));
  }
}
  
class UniqueColorGenerator {
  static List colorOptions = [
    Colors.blue,
    Colors.red,
    Colors.green,
    Colors.yellow,
    Colors.purple,
    Colors.orange,
    Colors.indigo,
    Colors.amber,
    Colors.black,
  ];
  static Random random = new Random();
  static Color getColor() {
    if (colorOptions.length > 0) {
      return colorOptions.removeAt(random.nextInt(colorOptions.length));
    } else {
      return Color.fromARGB(random.nextInt(256), random.nextInt(256),
          random.nextInt(256), random.nextInt(256));
    }
  }
}


Output:

Stateful Widget Tree

Now it is clear from the above example where to add them. The answer is simple, if you have to use the Stateful widget then you have to use the Keys else no need to use them. 

Now there are many types of Keys in flutter. All of them have been discussed below:

Types of keys in Flutter:

  • Value Key: The value key is used when it has to be assigned to something constant and extraordinary. For example, in the  To-Do List  the text entered is the value.
  • Object Key: The Object key is used when any single field such as name or birthday, they maybe the same of more than two people but would be unique for each person or each data combination.
  • Unique Key: The unique key is used when there are many widgets with the same incentive then we must use define each widget as a unique widget. We used it in our code also because we didn’t know what random color would be assigned to it until the widgets were assembled.
  • Global key:  The use of Global key is that it contains the data which can be accessed by other widgets present in the code. In case you don’t want to share it with other widgets then you must use the Global Key<From State> that holds a form of state and won’t allow other widgets to access the data stored in it.

So, in conclusion, we can say that keys are a very good feature in flutter. It only works with the Stateful widget and the purpose to use it to store the value of the current state when modifying the collection.



Last Updated : 28 Jul, 2021
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads