temirbek
temirbek

Reputation: 1452

StatefulWidget gets disposed on navigation

I have a stateful widget MyList that contains ListView. On tapping on any list tile the new screen (MyScreen) opens and after coming back (by pressing back button on top left) the scroll position is lost because MyList gets disposed and initState runs again. How can I prevent MyList from disposing?

class MyList extends StatefulWidget {
      @override
      _MyListState createState() => new _MyListState();
    }

class _MyListState extends State<MyList> {
  List<String> items = new List.generate(20, (index) => 'Hello $index');

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new Scrollbar(
        child: new ListView.builder(
          itemBuilder: (context, index) {
            return new ListTile(
              title: Text(items[index] + ' index $index'),
              onTap: () {
                Navigator.push(
                    context,
                    new MaterialPageRoute(
                      builder: (BuildContext context) => new MyScreen(index),
                    ));
              },
            );
          },
          itemCount: items.length,
        ),
      ),
    );
  }
}

And here is MyScreen:

class MyScreen extends StatefulWidget {
  final int indx;
  MyScreen(this.indx);
  _TaskDetailState createState() => new _TaskDetailState();
}

class _TaskDetailState extends State<MyScreen> {
  @override
  void initState() {
    super.initState();
  }

  Widget build(context) {
    return Scaffold(
      appBar: AppBar(
        elevation: 0.0,
        title: Text('yoba'),
      ),
      body: Text('yoba ${widget.indx}'),
    );
  }
}

Upvotes: 0

Views: 428

Answers (1)

Jordan Davies
Jordan Davies

Reputation: 10861

You need to add a PageStorageKey to your ListView widget.

class _MyListState extends State<MyList> {
  List<String> items = new List.generate(20, (index) => 'Hello $index');

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new Scrollbar(
        child: new ListView.builder(
          key: PageStorageKey("MyList"), // <-- Add this line
          itemBuilder: (context, index) {
            return new ListTile(
              title: Text(items[index] + ' index $index'),
              onTap: () {
                Navigator.push(
                    context,
                    new MaterialPageRoute(
                      builder: (BuildContext context) => new MyScreen(index),
                    ));
              },
            );
          },
          itemCount: items.length,
        ),
      ),
    );
  }
}

Upvotes: 2

Related Questions