Home > Blockchain >  Flutter DefaultTabController add/edit a button when the user reach last tab
Flutter DefaultTabController add/edit a button when the user reach last tab

Time:07-19

I have got a DefaultTabController with a couple of tabs that the user can swipe or press an ElevatedButton to proceed to the next slide, my issue is that I don't know how to change the button's label when the user reaches the last tab using swipes.

Using a stateful widget I managed to change the label when the user presses the button but it doesn't work if the user swipes. Is it possible to change the button when the user reaches the last tab?

class SlidesWidget extends StatelessWidget {
  static List<Slide> slides = [
    const Slide(
        text: 'Welcome to ..'),
    const Slide(
        text: 'Ready to discover your city?')
  ];

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: slides.length,
      child: Builder( // Builder here, otherwise `DefaultTabController.of(context)` returns null.
        builder: (BuildContext context) => Padding(
          padding: const EdgeInsets.all(8.0),
          child: SafeArea(
            child: Column(
              children: [
                const TabPageSelector(
                  selectedColor: Colors.white,
                ),
                Expanded(
                  flex: 100,
                  child: TabBarView(
                    children: slides,
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.all(18.0),
                  child: ElevatedButton(
                    onPressed: () {
                      final TabController controller =
                          DefaultTabController.of(context)!;
                      if (!controller.indexIsChanging &&
                          controller.index < slides.length - 1) {
                        // Go to next slide if exists
                        controller.index  ;
                      }
                    },
                    child: Text('Next'), // <== on last slide should change label and do other things
                  ),
                )
              ],
            ),
          ),
        ),
      ),
    );
  }
}

CodePudding user response:

I will recommend using StatefulWidget, also you can use inline StatefulBuilder to update the UI. And using TabController is handy instead of calling it multiple times, and there is risk of getting null for DefaultTabController.

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

  @override
  State<SlidesWidget> createState() => _SlidesWidgetState();
}

class _SlidesWidgetState extends State<SlidesWidget>
    with SingleTickerProviderStateMixin {
  late TabController controller;
  List<Slide> slides = [
    const Slide(text: 'Welcome to ..'),
    const Slide(text: 'Ready to discover your city?')
  ];
  @override
  void initState() {
    super.initState();
    controller = TabController(length: slides.length, vsync: this)
      ..addListener(() {
        setState(() {});
      });
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Padding(
      padding: const EdgeInsets.all(8.0),
      child: SafeArea(
        child: Column(
          children: [
         
            TabPageSelector(
              controller: controller,
              selectedColor: Colors.white,
            ),
            Expanded(
              flex: 100,
              child: TabBarView(
                controller: controller,
                children: slides,
              ),
            ),
            Padding(
              padding: const EdgeInsets.all(18.0),
              child: ElevatedButton(
                onPressed: () {
                  if (!controller.indexIsChanging &&
                      controller.index < slides.length - 1) {
                    // Go to next slide if exists
                    controller.index  ;
                  }
                },
                child: Text(controller.index == 1 ? 'start' : "Next"), //
              ),
            )
          ],
        ),
      ),
    ));
  }
}

More about TabController and I think you will also like IndexedStack for this case.

  • Related