Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Call a method from one statefulWidget in tab page in Flutter

I have two widgets – one is the main page with tabs and buttons and the second one is – Page with some TextFields. I would like to clean all TextFields after the button click. I tried to use
GlobalKey<_Page1> _key = GlobalKey<_Page1>(); and _key.currentState!.CleanAll(); but I received an error – Unhandled Exception: Null check operator used on a null value

Do you have any other ideas on how to do this?

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

  @override
  _MyTabsState createState() => _MyTabsState();
}

class _MyTabsState extends State<MyTabs> {

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        DefaultTabController(
          length: 1, // length of tabs
          initialIndex: 0,
          child: Column(
            children: <Widget>[
              const TabBar(
                labelColor: Colors.green,
                unselectedLabelColor: Colors.blueGrey,
                tabs: [
                  Tab(text: 'Page 1'),
                ],
              ),
              SizedBox(
                height: 200,
                child: TabBarView(
                    children: <Widget>[
                      Page1(),
                    ]
                ),
              ),
            ],
          ),),

        ElevatedButton(
            onPressed: () {
              // <- clean all TextField in Page1
            },
            child: Text('Clean')
        ),
      ],
    );
  }
}

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

  @override
  _Page1State createState() => _Page1State();
}

class _Page1State extends State<Page1> {

  TextEditingController text1 = TextEditingController();
  TextEditingController text2 = TextEditingController();

  void CleanAll() {
    text1.clear();
    text2.clear();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
      TextField(
        controller: text1,
      ),
        TextField(
          controller: text2,
        ),
      ],
    );
  }
}

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

You can use a ValueNotifier that will listen on Page1. then we will override initState on Page1 and clear the controlles.

class _MyTabsState extends State<MyTabs> {
  final ValueNotifier<bool> clearNotifier = ValueNotifier(false);

pass it to the Page1

Page1(
  clearCallback: clearNotifier,
),

to notify the listener we are just switching the value. bool value does not matter, we just need to update it.

onPressed: () {
  clearNotifier.value = !clearNotifier.value;
},

and on Page1

class Page1 extends StatefulWidget {
  final ValueNotifier clearCallback;
  const Page1({Key? key, required this.clearCallback}) : super(key: key);

  @override
  _Page1State createState() => _Page1State();
}

class _Page1State extends State<Page1> {
  @override
  void initState() {
    super.initState();
    widget.clearCallback.addListener(() {
      CleanAll();
    });
  }

Test snippet

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

  @override
  _MyTabsState createState() => _MyTabsState();
}

class _MyTabsState extends State<MyTabs> {
  final ValueNotifier<bool> clearNotifier = ValueNotifier(false);
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        DefaultTabController(
          length: 1, // length of tabs
          initialIndex: 0,
          child: Column(
            children: <Widget>[
              const TabBar(
                labelColor: Colors.green,
                unselectedLabelColor: Colors.blueGrey,
                tabs: [
                  Tab(text: 'Page 1'),
                ],
              ),
              SizedBox(
                height: 200,
                child: TabBarView(children: <Widget>[
                  Page1(
                    clearCallback: clearNotifier,
                  ),
                ]),
              ),
            ],
          ),
        ),
        ElevatedButton(
            onPressed: () {
              clearNotifier.value = !clearNotifier.value;
            },
            child: Text('Clean')),
      ],
    );
  }
}

class Page1 extends StatefulWidget {
  final ValueNotifier clearCallback;
  const Page1({Key? key, required this.clearCallback}) : super(key: key);

  @override
  _Page1State createState() => _Page1State();
}

class _Page1State extends State<Page1> {
  @override
  void initState() {
    super.initState();
    widget.clearCallback.addListener(() {
      CleanAll();
    });
  }

  TextEditingController text1 = TextEditingController();
  TextEditingController text2 = TextEditingController();

  void CleanAll() {
    text1.clear();
    text2.clear();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        TextField(
          controller: text1,
        ),
        TextField(
          controller: text2,
        ),
      ],
    );
  }
}

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading