「这是我参加11月更文挑战的第28天,活动详情检查:2021最终一次更文挑战」。

  • 咱们在快捷方式创立stateless Widget或许stateful Widget时分会让咱们创立一个key,之前一向没有讲讲解,接下来 就讨论下。

1. 例子

咱们创立一个listView增加3个cell,同时给他随机色彩,点击的时分移除第一个元素,

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: const Icon(Icons.delete),
      ),
    )
    );
  }
}

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!),
        )
    );
  }
}

Flutter学习-30-Flutter的key

咱们点击删去,移除了第一个元素,但是setState后从头build了,色彩从头随机了

Flutter学习-30-Flutter的key

这明显不是咱们想要的姿态。咱们把cell换成statefulWidget

Flutter学习-30-Flutter的key
点击删去

Flutter学习-30-Flutter的key

发现数据产生了改动,但是色彩没有产生改动,咱们删去了最终一个的色彩和第一个的文字。

  • 这是因为在删去第一条数据的时分,Widget对应的Element并没有改动;
  • Element中对应的State引用也没有产生改动;
  • 在更新Widget的时分,Widget运用了没有改动的Element中的State

2. key的运用

咱们给咱们的statefulWidget增加key

Flutter学习-30-Flutter的key

点击删去后,得到咱们想要的效果

Flutter学习-30-Flutter的key

咱们检查源码

Flutter学习-30-Flutter的key

当咱们的 [runtimeType] and [key]没有产生改动的时分Element就不更新,咱们删去第一个widget的时分,因为widgetkey都是空而且[runtimeType]也是一样的,所以直接运用之前的Element

Flutter学习-30-Flutter的key

咱们运用随机key的话

Flutter学习-30-Flutter的key

删去后

Flutter学习-30-Flutter的key

也验证了每次咱们的key产生改动后,Element会强制刷新,那么对应的State也会从头创立

3. key的分类

key是一个抽象类,里边有个工厂结构函数能够返回key

Flutter学习-30-Flutter的key
key有2个子类LocalKeyGlobalKey

3.1 LocalKey

LocalKey首要分为3个子类

  • ValueKey

    • ValueKey是当咱们以特定的值作为key时运用,比方一个字符串、数字等等
  • ObjectKey

    • 假如两个模型,他们的类型一样,运用type作为他们的key就不合适了
    • 咱们能够创立出一个模型目标,运用目标来作为key
  • UniqueKey

    • 假如咱们要保证key的唯一性,能够运用UniqueKey;
    • 比方咱们之前运用随机数来保证key的不同,这儿咱们就能够换成UniqueKey;

3.2 GlobalKey

能够协助咱们拜访某个Widget的信息,包括WidgetStateElement等目标

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: const Icon(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) {
    return Center(
      child: Column(
        children: [
          Text(count.toString()),
          Text(data),
        ],
      ),
    );
  }
}

Flutter学习-30-Flutter的key