Home > Blockchain >  Prevent children from rebuilding in SliverList
Prevent children from rebuilding in SliverList

Time:06-03

Minimum example:

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

If you click the checkbox, then scroll out of view and then back in to view.. The box becomes unchecked. This is because the widget rebuilds...setting the _personalData to false. I would of thought addAutomaticKeepAlives would prevent the widget rebuilding and keep the state of the checkbox. How do I prevent CheckboxWidget from rebuilding?

CodePudding user response:

Firstly, I will choose state management or passing value to the CheckboxWidget. To answer this question, we need to save (keep alive) the state of CheckboxWidget. Therefore, we need to use AutomaticKeepAliveClientMixin on _CheckboxWidgetState instead of parent widget.

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()
        ],
      ),
    );
  }
}
  • Related