Flutter 里的 key 是什么?有什么用?

发布于 1周前 作者 ionicwang 来自 Flutter

Flutter 里的 key 是什么?有什么用?

在 Flutter 中,Key 是一种标识符,用于帮助框架区分和管理不同的 widget 实例。它可以防止在重新构建界面时,Flutter 不必要地销毁和重建 widget,从而更高效地更新 UI。Key 通常用于需要保持状态或优化性能的场景。

Flutter 中 Key 的作用

在 Flutter 的 widget 树中,每当界面发生变化时,Flutter 会尝试对比新旧 widget 树的差异,然后进行必要的更新。如果某些 widget 的位置改变或被替换,Flutter 可能会在没有 Key 的情况下重新创建它们,而这可能导致状态丢失等问题。Key 的主要作用就是帮助 Flutter 确认一个 widget 在重建过程中是否相同。通过为 widget 提供 Key,Flutter 可以根据 Key 来匹配和识别 widget,即使它们在树中的位置发生了变化。

常见的 Key 类型

  1. GlobalKey

    GlobalKey 是全局唯一的 Key,允许在 widget 树的任何地方访问对应 widget 的状态。它适用于需要跨组件访问状态或在多个地方共享同一状态的场景。

    import 'package:flutter/material.dart';
    
    void main() {
      final GlobalKey myGlobalKey = GlobalKey();
      runApp(MyApp(myGlobalKey));
    }
    
    class MyApp extends StatelessWidget {
      final GlobalKey myGlobalKey;
    
      MyApp(this.myGlobalKey);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(title: Text('GlobalKey Example')),
            body: Center(
              child: MyWidget(key: myGlobalKey),
            ),
            floatingActionButton: FloatingActionButton(
              onPressed: () {
                // Access the state of MyWidget using myGlobalKey
                final state = myGlobalKey.currentState as MyWidgetState;
                print(state.someData);
              },
              tooltip: 'Get State',
              child: Icon(Icons.info),
            ),
          ),
        );
      }
    }
    
    class MyWidget extends StatefulWidget {
      @override
      _MyWidgetState createState() => _MyWidgetState();
    }
    
    class _MyWidgetState extends State<MyWidget> {
      String someData = 'Hello, World!';
    
      @override
      Widget build(BuildContext context) {
        return Text(someData);
      }
    }
    
  2. ValueKey

    ValueKey 是根据给定的值创建的 Key。当 ValueKey 的值相同,Flutter 会认为是同一个 widget。ValueKey 通常用于列表项等不需要全局唯一的元素。

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(title: Text('ValueKey Example')),
            body: ListView.builder(
              itemCount: 10,
              itemBuilder: (context, index) {
                return ListTile(
                  key: ValueKey(index),
                  title: Text('Item $index'),
                );
              },
            ),
          ),
        );
      }
    }
    
  3. UniqueKey

    UniqueKey 是一个总是唯一的 Key,即使是两个 UniqueKey 实例之间也不会相同。它适用于需要确保每个 widget 都唯一的情况。

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(title: Text('UniqueKey Example')),
            body: Column(
              children: List.generate(
                5,
                (index) => UniqueWidget(key: UniqueKey()),
              ),
            ),
          ),
        );
      }
    }
    
    class UniqueWidget extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Container(
          color: Colors.primary,
          height: 50,
          child: Center(child: Text('Unique Widget')),
        );
      }
    }
    

什么时候使用 Key

Key 通常在以下场景中使用:

  1. 可重排序的列表:在 ListViewGridView 中使用 Key 来跟踪每个列表项,确保用户在重排序时状态不会丢失。

  2. 有状态的组件:当组件的重建会导致状态丢失时,可以通过 Key 来帮助 Flutter 区分组件的不同实例,从而保留其状态。

  3. 复杂的 UI 结构:在一些复杂布局或动态修改 widget 的情况下,使用 Key 可以避免 Flutter 误认为某些 widget 是新的,从而避免无谓的重建。

总结

在 Flutter 中,Key 是一种优化工具,用于控制 widget 在重建过程中的标识性。通过合理使用 Key,可以确保应用在界面更新时保留状态、优化性能。


更多关于Flutter 里的 key 是什么?有什么用?的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter 里的 key 是什么?有什么用?的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,Key是一个非常重要的概念,它主要用于框架内部来高效地管理Widget树的重建过程。理解Key的作用,对于优化UI性能和避免不必要的组件重建至关重要。以下是对Key的详细解释以及相关的代码示例。

Flutter 里的 Key 是什么?

Key是Flutter框架中用于唯一标识Widget的一个类。它主要用于帮助Flutter的Widget树在重建时确定哪些Widget是“相同”的,哪些是“新”的,以及哪些是“被移除”的。这对于列表渲染、动画状态保持以及动态UI更新等方面特别重要。

有什么用?

  1. 优化重建过程:当Widget树发生变化时,Flutter会基于Key来判断哪些Widget需要被重新构建,哪些可以保持不变。这可以显著提高UI的性能。

  2. 控制列表项的动画:在使用AnimatedListAnimatedBuilder等动画组件时,Key用于跟踪每个列表项的身份,以确保动画能够正确应用。

  3. 保持Widget状态:当Widget的位置在列表中发生变化时,Key可以帮助Flutter保持Widget的内部状态。

Key 的类型

Flutter提供了几种不同类型的Key:

  • ValueKey:用于具有简单值类型的Widget。
  • ObjectKey:用于任意对象的Widget。
  • LocalKey:通常用于框架内部,开发者较少直接使用。
  • GlobalKey:一个全局唯一的Key,可以用于在Widget树的任何位置访问Widget的状态。

代码示例

使用ValueKey

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('ValueKey Example')),
        body: ListView.builder(
          itemCount: 10,
          itemBuilder: (context, index) => ListTile(
            key: ValueKey(index),
            title: Text('Item $index'),
          ),
        ),
      ),
    );
  }
}

在这个例子中,ValueKey(index)用于唯一标识每个ListTile

使用GlobalKey

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        key: scaffoldKey,
        appBar: AppBar(title: Text('GlobalKey Example')),
        body: Center(
          child: ElevatedButton(
            onPressed: () {
              scaffoldKey.currentState?.showSnackBar(
                SnackBar(content: Text('Hello from GlobalKey!')),
              );
            },
            child: Text('Show SnackBar'),
          ),
        ),
      ),
    );
  }
}

在这个例子中,GlobalKey<ScaffoldState>用于在按钮点击时访问Scaffold的状态,以显示一个SnackBar

总结

在Flutter中,Key是管理Widget树重建过程的核心机制之一。正确使用Key不仅可以提高UI性能,还可以保持Widget的状态和动画的一致性。开发者应该根据具体场景选择合适的Key类型,并在需要时合理地使用它们。

回到顶部