Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stateful widget not being restored with ValueKey #16

Open
melio-matt opened this issue Mar 6, 2023 · 4 comments
Open

Stateful widget not being restored with ValueKey #16

melio-matt opened this issue Mar 6, 2023 · 4 comments

Comments

@melio-matt
Copy link

Hello
I've created a carousel by supplying an array of stateful widgets and when the provider signals, this will be reconstructed as part of the normal build process. On the rebuild and the array changing dimension I loose the state of my widgets, which do have ValueKeys on each. Switching the key to a GlobalKey means I retain the state, but there are obvious reasons for not wanting to use GlobalKeys.
I didn't find anything in the documentation about this, so I assumed that it should work the same way as other lists where the position of a widget can be changed using local keys.
regards
Matthew

@nixrajput
Copy link
Owner

Hi @melio-matt

Can you please provide some test cases or any screenshots or a video that how are you implementing it and what are you trying to do?

Thanks
Nikhil

@melio-matt
Copy link
Author

Hi @nixrajput

I've added below some code that illustrates what I'm doing. The floating button when clicked alters the state and removes one of the pages from the carousel. Before pressing this, navigate to the last page and enter some text into the box, then press the button. You will then see the input box no longer has the text present. There is some commented out code that switches out the local and global keys. Once swapped round and you repeat the above action you will see the text is maintained in the input box.

regards
Matthew

import 'package:flutter/material.dart';
import 'package:flutter_carousel_widget/flutter_carousel_widget.dart';

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

GlobalKey inputScreenGlobalKey = GlobalKey();

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(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Carousel State Test'),
    );
  }
}

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

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  CarouselController carouselController = CarouselController();
  bool _itemsAltered = false;

  void _alterItems() {
    setState(() {
      _itemsAltered = !_itemsAltered;
    });
  }

  @override
  Widget build(BuildContext context) {
    List<Widget> carouselItems = [];
    carouselItems.add(const Text("panel 1", key: ValueKey("panel1")));
    if (_itemsAltered == false) {
      carouselItems.add(const Text("panel 2", key: ValueKey("panel2")));
    }

    // swap these lines to move between local keys and global keys
    carouselItems.add(const InputScreen(key: ValueKey("inputScreen")));
    // carouselItems.add(InputScreen(key: inputScreenGlobalKey));

    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: FlutterCarousel(
          items: carouselItems,
          options: CarouselOptions(),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _alterItems,
        tooltip: 'Alter',
        child: const Icon(Icons.ac_unit),
      ),
    );
  }
}

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

  @override
  State<StatefulWidget> createState() {
    return _InputScreenState();
  }
}

class _InputScreenState extends State<InputScreen> {
  late TextEditingController textEditingController;

  @override
  void initState() {
    super.initState();
    textEditingController = TextEditingController();
  }

  @override
  Widget build(BuildContext context) {
    return TextField(
      controller: textEditingController,
    );
  }
}
```

@nixrajput
Copy link
Owner

Hi @melio-matt

I will look into this and I will definitely revert back to you after testing and solution.

Please have some patience.

Thanks and regards,
Nikhil

@melio-matt
Copy link
Author

Thanks @nixrajput

No massive urgency, I have a solution that works for me at the moment and will be easy enough to put back in the more permanent solution.

Matthew

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants