Gaurav Kumar
Gaurav Kumar

Reputation: 1231

How to swipe to next tab from `bottomNavigationBar` button named Next?

Following is my code where I am trying to navigate to the next tab from bottom navigation bar button. See mock for understanding.

Code:

class TabbedAppBarSample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: DefaultTabController(
        length: choices.length,
        child: Scaffold(
          floatingActionButtonLocation:
              FloatingActionButtonLocation.centerDocked,
          bottomNavigationBar: BottomAppBar(
            notchMargin: 20,
            child: new Row(
              // mainAxisSize: MainAxisSize.max,
              mainAxisAlignment: MainAxisAlignment.end,
              children: <Widget>[
                Text(
                  'Next >',
                  style: TextStyle(fontSize: 20, color: Colors.red),
                )
              ],
            ),
          ),
          backgroundColor: Colors.white,
          appBar: AppBar(
            backgroundColor: Colors.white, // status bar color
            brightness: Brightness.light,
            title: TimerPage(),
            bottom: TabBar(
              // isScrollable: true,
              indicatorColor: Colors.red,
              unselectedLabelColor: Colors.grey,
              labelColor: Colors.red,
              tabs: choices.map((Choice choice) {
                return Tab(
                  text: choice.title,
                );
              }).toList(),
            ),
          ),
          body: TabBarView(
            children: choices.map((Choice choice) {
              return Padding(
                padding: const EdgeInsets.all(6.0),
                child: ChoiceCard(choice: choice),
              );
            }).toList(),
          ),
        ),
      ),
    );
  }
}

Mock:

enter image description here

Also, Idea is to navigate either via swipe or clicking on the Next button.

Upvotes: 3

Views: 4341

Answers (2)

TWL
TWL

Reputation: 6646

The swiping behavior should already be there, but if you want to make a Text clickable like a button, you should look into some examples at How can I implement OnPressed callback for Text widget, Flutter. (I’ll use a FlatButton in my example)

Second, I recommend doing this with a StatefulWidget. Now, if you want a “next” button, then you’ll have to implement your own TabController. In your button’s onPressed, you can implement your “next” behavior by using TabController.animateTo(). Simplified stateful example:

class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {

  TabController myTabController;

  @override
  void initState() {
    super.initState();
    myTabController = new TabController(
        vsync: this,
        length: //your_choices,
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      bottomNavigationBar: BottomAppBar(
        child: new Row(
          mainAxisAlignment: MainAxisAlignment.end,
          children: <Widget>[
            FlatButton(
              onPressed: () {
                myTabController.animateTo(myTabController.index + 1);
              },
              child: new Text('Next >'),
            ),
          ],
        ),
      ),
      appBar: AppBar(
        title: Text(widget.title),
        bottom: TabBar(
          controller: myTabController,
          tabs: //your_choices,
        ),
      ),
      body: TabBarView(
        controller: myTabController,
        children: //your_choices,
      ),
    );
  }
}

Now, if you want to keep it as StatelessWidget. You’ll need to wrap your Scaffold inside Builder to access your DefaultTabController for the same actions as above. Here’s a simplified example snippet of your Widget build(BuildContext context):

home: DefaultTabController(
  length: //your_choices,
  child: Builder(builder: (BuildContext context) {
    return Scaffold(
      bottomNavigationBar: BottomAppBar(
        child: new Row(
          mainAxisAlignment: MainAxisAlignment.end,
          children: <Widget>[
            FlatButton(
              onPressed: () {
                DefaultTabController.of(context).animateTo(DefaultTabController.of(context).index + 1);
              },
              child: new Text('Next >'),
            ),
          ],
        ),
      ),
      appBar: ...
      body: ...
    );
  }),
)

Modify as needed.

Upvotes: 3

chunhunghan
chunhunghan

Reputation: 54367

With TabController and animateTo
You can see full code below

code snippet

@override
  void initState() {
    super.initState();
    _tabController = TabController(vsync: this, length: 3);
  }

  void _toggleTab() {
    _tabIndex = _tabController.index + 1;
    _tabController.animateTo(_tabIndex);
  }

  ...
bottomNavigationBar: BottomAppBar(
        notchMargin: 20,
        child: new Row(
          // mainAxisSize: MainAxisSize.max,
          mainAxisAlignment: MainAxisAlignment.end,
          children: <Widget>[
            InkWell(
              onTap: () {
                _toggleTab();
              },

working demo

enter image description here

full code

    import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final appTitle = 'Tabs Demo';
    return MaterialApp(
      title: appTitle,
      home: MyHomePage(title: appTitle),
    );
  }
}

class MyHomePage extends StatefulWidget {
  final String title;

  const MyHomePage({Key key, this.title}) : super(key: key);

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

class _MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin {
  int _tabIndex = 0;

  TabController _tabController;

  @override
  void initState() {
    super.initState();
    _tabController = TabController(vsync: this, length: 3);
  }

  void _toggleTab() {
    _tabIndex = _tabController.index + 1;
    _tabController.animateTo(_tabIndex);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
      bottomNavigationBar: BottomAppBar(
        notchMargin: 20,
        child: new Row(
          // mainAxisSize: MainAxisSize.max,
          mainAxisAlignment: MainAxisAlignment.end,
          children: <Widget>[
            InkWell(
              onTap: () {
                _toggleTab();
              },
              child: Text(
                'Next >',
                style: TextStyle(fontSize: 20, color: Colors.red),
              ),
            )
          ],
        ),
      ),
      appBar: AppBar(
        title: Text(widget.title),
        bottom: TabBar(
          controller: _tabController,
          tabs: [
            Tab(text: 'Tab 1'),
            Tab(text: 'Tab 2'),
            Tab(text: 'Tab 3'),
          ],
        ),
      ),
      body: TabBarView(
        controller: _tabController,
        children: [
          Card(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                ListTile(
                  leading: Icon(Icons.album),
                  title: Text('Hello 1'),
                  subtitle: Text('Click on Next Button to go to Tab 2.'),
                ),
              ],
            ),
          ),
          Card(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                ListTile(
                  leading: Icon(Icons.album),
                  title: Text('Hello 2'),
                  subtitle: Text('Click on Next Button to go to Tab 3'),
                ),
              ],
            ),
          ),
          Card(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                ListTile(
                  leading: Icon(Icons.album),
                  title: Text('Hello 3'),
                  subtitle: Text('The End'),
                ),
              ],
            ),
          ),
        ],
      ),
    ));
  }
}

Upvotes: 3

Related Questions