Skip to content

PageStorage strange behavior without describe in docs #63656

@xu-baolin

Description

@xu-baolin

Simple code:

import 'package:flutter/material.dart';

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

class PageStorageTest extends StatefulWidget {
  @override
  _PageStorageTestState createState() => _PageStorageTestState();
}

class _PageStorageTestState extends State<PageStorageTest> {
  PageStorageKey key0 = PageStorageKey<String>('key0');
  PageStorageKey key1 = PageStorageKey<String>('key1');
  PageStorageKey key2 = PageStorageKey<String>('key2');
  bool flag = true;

  void _onPress() {
    setState(() {
      flag = !flag;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Flutter Demo',
        home: Scaffold(
          floatingActionButton: FloatingActionButton(
            onPressed: _onPress,
            child: Text("+"),
          ),
          appBar: AppBar(
            title: Text('PageStorageKey bug app'),
          ),
          drawer: Drawer(
            child: ListView(
              key: key0,
              children: <Widget>[
                Container(height: 700, width: 100, color: Colors.red),
                SingleChildScrollView(
                  key: flag ? key1 : null,
                  scrollDirection: Axis.horizontal,
                  child: Container(
                      height: 200,
                      width: 500,
                      child: Center(
                          child: SizedBox(
                              width: 100,
                              child: TextField(
                                key: key2,
                                controller: TextEditingController(
                                    text:
                                        'asdgfhjkklsgsdklgfjklsjgklsdgjlsdkjgkl'),
                              ))),
                      decoration: BoxDecoration(
                          gradient: LinearGradient(
                        colors: [Colors.green, Colors.black],
                        begin: Alignment.topLeft,
                        end: Alignment.bottomRight,
                      ))),
                )
              ],
            ),
          ),
          body: Container(),
        ));
  }
}

Step:

  1. Run APP and scroll the ListView SingleChildScrollView TextField, PageStorage will save their positions
  2. Close Drawer and open again, it works well
  3. Close Drawer and tap '+' Button, modify key1
  4. Open Drawer, SingleChildScrollView and TextField lose state
  5. Close Drawer and tap '+' Button, recover key1
  6. Open Drawer, SingleChildScrollView and TextField recover state too
    This is very strange to developers because I only modified the key1 of SingleChildScrollView, but the state of TextField is lost too. Even more strange is that I restored key1 of SingleChildScrollView and TextField recover state too.

Root cause:
The root cause of that is PageStorage distinguish widget by a chain of PageStorageKeys, so if modify the key of the middle chain, all the descendants will lose state.
In addition, repeated additions and deletions of a widget(different PageStorageKey) will cause PageStorage._storage memory leaks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listd: api docsIssues with https://api.flutter.dev/frameworkflutter/packages/flutter repository. See also f: labels.team-frameworkOwned by Framework teamtriaged-frameworkTriaged by Framework team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions