阻止 children 在 SliverList 中重建

Prevent children from rebuilding in SliverList

最小示例:

import 'package:flutter/material.dart';

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

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
        title: 'Welcome to Flutter',
        home: Scaffold(
          body: CustomScrollView(
            slivers: [Example()],
          ),
        ));
  }
}

class Example extends StatefulWidget {
  const Example({Key? key}) : super(key: key);

  @override
  State<Example> createState() => ExampleState();
}

class ExampleState extends State<Example> with AutomaticKeepAliveClientMixin {
  @override
  Widget build(BuildContext context) {
    super.build(context);
    return SliverList(
        delegate: SliverChildListDelegate(const <Widget>[
      SizedBox(
        height: 1400,
      ),
      CheckboxWidget()
    ], addAutomaticKeepAlives: true));
  }

  @override
  bool get wantKeepAlive => true;
}

class CheckboxWidget extends StatefulWidget {
  const CheckboxWidget({Key? key}) : super(key: key);

  @override
  State<CheckboxWidget> createState() => _CheckboxWidgetState();
}

class _CheckboxWidgetState extends State<CheckboxWidget> {
  late bool _personalData = false;
  @override
  Widget build(BuildContext context) {
    return Checkbox(
      checkColor: Colors.black,
      onChanged: (bool? value) {
        setState(() {
          _personalData = value!;
        });
      },
      value: _personalData,
    );
  }
}

如果您单击该复选框,然后滚动出视图,然后返回视图。该框将变为未选中状态。这是因为小部件重建...将 _personalData 设置为 false。我认为 addAutomaticKeepAlives 会阻止小部件重建并保持复选框的状态。如何防止 CheckboxWidget 重建?

首先,我会选择状态管理或将值传递给CheckboxWidget。要回答这个问题,我们需要保存(keep alive)CheckboxWidget的状态。因此,我们需要在 _CheckboxWidgetState 上使用 AutomaticKeepAliveClientMixin 而不是父控件。

class CheckboxWidget extends StatefulWidget {
  const CheckboxWidget({Key? key}) : super(key: key);

  @override
  State<CheckboxWidget> createState() => _CheckboxWidgetState();
}

class _CheckboxWidgetState extends State<CheckboxWidget>
    with AutomaticKeepAliveClientMixin {
  late bool _personalData = false;
  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Checkbox(
      checkColor: Colors.black,
      onChanged: (bool? value) {
        setState(() {
          _personalData = value!;
        });
      },
      value: _personalData,
    );
  }

  @override
  bool get wantKeepAlive => true;
}

class Example extends StatefulWidget {
  const Example({Key? key}) : super(key: key);

  @override
  State<Example> createState() => ExampleState();
}

class ExampleState extends State<Example> {
  @override
  Widget build(BuildContext context) {
    return SliverList(
      delegate: SliverChildListDelegate(
        const <Widget>[
          SizedBox(
            height: 1400,
          ),
          CheckboxWidget()
        ],
      ),
    );
  }
}