Flutter Getting Started and Advanced Journey (23) Flutter Key

Introduction:
Key is a very important concept in Flutter, which can help us optimize performance, avoid reconstruction problems, and ensure that Widgets are updated correctly. This article will provide a detailed analysis of Flutter Key and introduce how to flexibly apply it in actual development.

1. What is Key?

Key is an abstract class in Flutter, which is used to identify Widgets. Each Flutter Widget can use Key as a unique identifier to identify itself, which can also be used to compare new Widgets with old Widgets. Key itself does not have any specific implementation, but its subclasses have many types to choose from, such as ValueKey, ObjectKey, etc.

The specific categories are as follows:

1.1Key types In Flutter, Key mainly has the following types:

  • ValueKey: This is the most commonly used Key type, which assigns a value to the Key. When the values ​​of two ValueKeys are the same, the Flutter framework will consider the two Keys to be the same.

  • ObjectKey: Similar to ValueKey, but ObjectKey uses a reference to an object.

  • UniqueKey: A unique Key is generated every time it is created.

  • GlobalKey: This is a globally unique Key that can be referenced throughout the application
    mage.png

  • LocalKey

LocalKey is directly inherited from Key. It is used when comparing widgets with the same parent Element. That is, in the above example, there is a multi-child Widget that needs to move its child widgets. In this case, you should use Localkey. It is also a key that we use more every day.

Localkey derives many subclass keys:

  • ValueKey : ValueKey(‘String’)
  • ObjectKey : ObjectKey(Object)
  • UniqueKey : UniqueKey()
  • Valuekey derives PageStorageKey: PageStorageKey('value')

Note: If it is a statelessWidget, then there is no need to use a key, because the widget will be rebuilt every frame; and because the statefulWidget uses state, the state usually caches many variables that need to be displayed on the UI, and it will not be rebuilt frequently, so You need to use key to force the change.

  • ValueKey

Any object can be passed in, and its contents will be compared to see if they are consistent.

  
  bool operator ==(Object other) {
    
    
    if (other.runtimeType != runtimeType)
      return false;
    return other is ValueKey<T>
        && other.value == value;
  }
  • ObjectKey

You can pass in any parameter, and during comparison, it will compare whether its pointers are consistent, that is, whether they are the same object.

  
  bool operator ==(Object other) {
    
    
    if (other.runtimeType != runtimeType)
      return false;
    return other is ObjectKey
        && identical(other.value, value);
  }
  • UniqueKey

There is no need to pass any parameters. Each refresh will generate a new value, which is usually used for animation transitions. for example:

         AnimatedSwitcher(
              duration: const Duration(seconds: 1),
              child: Text("no keyrrths", key: UniqueKey()),
            )

Every time the text is changed, if uniqueKey is not passed, there will be no gradient animation effect, and if UniqueKey is passed, there will be a gradient animation effect. Because when uniqueKey is not passed, it will only be considered that the text widget has changed every time, and the text widget will only be replaced with a new widget, while the element will still be the same and will not change, so it will be considered that the UI has not changed, so It will not change; if a uniqueKey is passed, each time the widget is compared, it will be considered a different widget because its own key is inconsistent, resulting in the reconstruction of element and renderObject. The two UIs before and after are inconsistent, and animation effects will occur. .

  • GlobalKey

Global variables, as the name suggests, are unique in the entire application, so the same globalKey can only be used on one widget. You can get the corresponding state and element or widget through globalKey, which can be used to change the state or variable value of the state, and refresh the UI. However, this is not recommended. It is generally recommended to refresh the UI by controlling external variables.


        floatingActionButton: FloatingActionButton(
          onPressed: (){
    
    
            var state = (_globalKey as BoxState);
            state.count++;
            state.setState(() {
    
    
            });
          },
          child: const Icon(Icons.add),
        ),

2. The role of Key

2.1 Unique identifier

The main function of Key is to uniquely identify the Widget. When the Widget structure changes, Flutter will identify the difference between the old Widget and the new Widget based on the Key to determine whether it needs to be rebuilt. Without Key, Flutter will not be able to distinguish different Widgets and will rebuild them all, resulting in performance degradation.

2.2 Optimize performance

Through Key, Flutter can efficiently update some subtrees in the Widget tree instead of rebuilding the entire Widget tree. This avoids unnecessary rebuilds and improves performance.

2.3 Avoid rebuild problems

In some cases, we want to keep the Widget's state unchanged even if the Widget's position changes. Key can help us solve this problem by adding a unique Key to the Widget to ensure that the original state is correctly retained when updating the Widget tree instead of resetting it to the default value.

3. Key usage examples

3.1 Build list

When building lists, we often use ListView.builder. At this time we need to use IndexedWidgetBuilder as the itemBuilder parameter. In order to ensure that the list items are displayed and updated correctly, we need to add a unique Key to each list item, usually using ValueKey or ObjectKey.

List<String> items = ["item1", "item2", "item3"];

ListView.builder(
  itemCount: items.length,
  itemBuilder: (context, index) {
    
    
    return ListTile(
      key: ValueKey(items[index]), // 或者使用ObjectKey(items[index])
      title: Text(items[index]),
    );
  },
);

3.2 Update Widget

When we need to update an existing Widget, if the type of the Widget changes, Flutter will think that this is a different Widget, not just a change in attributes, and will rebuild the entire subtree. To avoid this rebuild, we can use the same Key when updating.

ValueKey("myKey") // 使用相同Key更新Widget

4. Key usage specifications

4.1 Uniqueness

Each Widget should have a unique Key so that Flutter can correctly identify their differences. If the same Key appears, Flutter will report an error and throw an exception.

4.2 Stability

Key should be stable and should not change as the properties of the Widget change. If the Key changes as the Widget's properties change, Flutter will think it is a different Widget, causing it to be rebuilt.

4.3 Maintainability

Key should be a readable and descriptive string or other type. This helps us quickly locate the problem and debug it if needed.

Summarize

Key is a very important concept in Flutter, which can help us better manage and update Widgets. Understanding and mastering the use of Key can help better optimize performance, avoid rebuild problems, and ensure that Widgets are updated correctly.

Guess you like

Origin blog.csdn.net/xieluoxixi/article/details/121626028