skip to Main Content

Try to keep drawer alive (do not rebuild when open/close drawer):

import 'package:flutter/material.dart';

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

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      drawer: const AutomaticKeepAlive(
        child: Drawer(
          child: MyWidget(),
        ),
      ),
    );
  }
}

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

  @override
  State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget>
    with AutomaticKeepAliveClientMixin {
  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    super.build(context);

    return const Column(
      children: [
        Text('Input Name:'),
        SizedBox(
          width: 50,
          height: 30,
          child: TextField(),
        ),
      ],
    );
  }
}

Runtime Error:

════════ Exception caught by widgets library ═══════════════════════════════════
The following assertion was thrown while applying parent data.:
Incorrect use of ParentDataWidget.
The ParentDataWidget KeepAlive(keepAlive: false) wants to apply ParentData of type KeepAliveParentDataMixin to a RenderObject, which has been set up to accept ParentData of incompatible type ParentData.
Usually, this means that the KeepAlive widget has the wrong ancestor RenderObjectWidget. Typically, KeepAlive widgets are placed directly inside SliverWithKeepAliveWidget or TwoDimensionalViewport widgets.
The offending KeepAlive is currently placed inside a Semantics widget.
The ownership chain for the RenderObject that received the incompatible parent data was:
  Semantics ← Drawer ← NotificationListener<KeepAliveNotification> ← KeepAlive ← AutomaticKeepAlive ← _FocusInheritedScope ← Semantics ← FocusScope-[GlobalKey#b1269] ← RepaintBoundary ← Align ← ⋯

2

Answers


  1. When you close the drawer, the AutomaticKeepAlive is also getting disposed along with all it’s children.

    To preserve the Drawer widget, you will need a Global Key and you will need to move the drawer object somewhere hidden in the Widget tree so that the drawer does not get disposed.

    Here is sample code.

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
            useMaterial3: true,
          ),
          home: const MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      const MyHomePage({super.key, required this.title});
      final String title;
    
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      final GlobalKey drawerKey = GlobalKey();
      bool isDrawerOpened = false;
    
      Widget get drawer => Drawer(
            key: drawerKey,
            child: const MyWidget(),
          );
    
      @override
      Widget build(BuildContext context) {
        return Stack(
          children: [
            Visibility(
              visible: !isDrawerOpened,
              child: drawer,
            ),
            Scaffold(
              
              appBar: AppBar(
                backgroundColor: Theme.of(context).colorScheme.inversePrimary,
                title: Text(widget.title),
              ),
              onDrawerChanged: (isOpened) {
                Future.delayed(Duration.zero, () {
                  isDrawerOpened = isOpened;
                  setState(() {});
                });
              },
              drawer: isDrawerOpened ? drawer : const Drawer(),
              floatingActionButton: FloatingActionButton(
                onPressed: () {
                  setState(() {});
                },
                child: const Icon(Icons.add),
              ),
            ),
          ],
        );
      }
    }
    
    class MyWidget extends StatefulWidget {
      const MyWidget({super.key});
    
      @override
      State<MyWidget> createState() => _MyWidgetState();
    }
    
    class _MyWidgetState extends State<MyWidget> {
      @override
      Widget build(BuildContext context) {
        return const Column(
          children: [
            Text('Input Name:'),
            SizedBox(
              width: 50,
              height: 30,
              child: TextField(),
            ),
          ],
        );
      }
    }
    
    
    Login or Signup to reply.
  2. You're facing suggests that the AutomaticKeepAlive widget is not 
    being used correctly. The AutomaticKeepAlive widget is typically used 
    within a SliverWithKeepAliveWidget or TwoDimensionalViewport widget. In 
    your case, it seems like you're trying to use it within a Drawer, which 
    is causing the error. Please replace this Drawer Code:
    
    
       drawer: Drawer(
          child: KeepAlive(
            child: MyWidget(),
          ),
        ),
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search