3

Im working on a Flutter app and trying to add a segment to my app. Is it possible to achieve it in Flutter. So i would like 2 different widgets for the 2 buttons. It is similar to the TabBar in Flutter or Segment in native apps

enter image description here

Praveen Kumar
  • 1,597
  • 3
  • 13
  • 14
  • Yes ofcourse it's possible, what have you tried so far? – Hemanth Raj Mar 19 '18 at 14:51
  • @HemanthRaj I have tried using the TabBar with no success – Praveen Kumar Mar 19 '18 at 14:58
  • Some visual ref of what you are trying to achieve like ref pic? The pic in question show only two button. This can be achieved by a row widget – Hemanth Raj Mar 19 '18 at 15:01
  • @HemanthRaj I have updated the pic in my question. So i would like 2 different widgets for the 2 buttons. It is similar to the TabBar in Flutter or Segment in native apps – Praveen Kumar Mar 19 '18 at 15:09
  • @HemanthRaj The flat buttons index do not change if we manually swipe between the tabs. Is it possible to restrict the swipe or update the buttons index when user swipe between the tabs? – Praveen Kumar Mar 20 '18 at 04:01

3 Answers3

6

CupertinoSegmentedControl is your friend

Example (inside StatefulWidget):

  int segmentedControlValue = 0;

  Widget _segmentedControl() => Container(
    width: 500,
    child: CupertinoSegmentedControl<int>(
      selectedColor: Colors.blue,
      borderColor: Colors.white,
      children: {
        0: Text('All'),
        1: Text('Recommendations'),
      },
      onValueChanged: (int val) {
        setState(() {
          segmentedControlValue = val;
        });
      },
      groupValue: segmentedControlValue,
    ),
  );

enter image description here

Andrew
  • 36,676
  • 11
  • 141
  • 113
5

As you tried, you can acheive it with TabBarView easily. The below code shows a very basic implementation of how it can be acheived.

Example:

class Example extends StatefulWidget {
  @override
  _ExampleState createState() => new _ExampleState();
}

class _ExampleState extends State<Example> with SingleTickerProviderStateMixin {
  // TabController to control and switch tabs
  TabController _tabController;

  // Current Index of tab
  int _currentIndex = 0;

  @override
  void initState() {
    super.initState();
    _tabController =
        new TabController(vsync: this, length: 2, initialIndex: _currentIndex);
  }

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

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Example"),
      ),
      body: new Column(
        children: <Widget>[
          new Padding(
            padding: const EdgeInsets.symmetric(vertical: 20.0),
            child: new Container(
              decoration:
                  new BoxDecoration(border: new Border.all(color: Colors.blue)),
              child: new Row(
                mainAxisAlignment: MainAxisAlignment.center,
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  // Sign In Button
                  new FlatButton(
                    color: _currentIndex == 0 ? Colors.blue : Colors.white,
                    onPressed: () {
                      _tabController.animateTo(0);
                      setState(() {
                        _currentIndex = 0;
                      });
                    },
                    child: new Text("SignIn"),
                  ),
                  // Sign Up Button
                  new FlatButton(
                    color: _currentIndex == 1 ? Colors.blue : Colors.white,
                    onPressed: () {
                      _tabController.animateTo(1);
                      setState(() {
                        _currentIndex = 1;
                      });
                    },
                    child: new Text("SignUp"),
                  )
                ],
              ),
            ),
          ),
          new Expanded(
            child: new TabBarView(
                controller: _tabController,
                // Restrict scroll by user
                physics: const NeverScrollableScrollPhysics(),
                children: [
                  // Sign In View
                  new Center(
                    child: new Text("SignIn"),
                  ),
                  // Sign Up View
                  new Center(
                    child: new Text("SignUp"),
                  )
                ]),
          )
        ],
      ),
    );
  }
}

Hope that helps!

Hemanth Raj
  • 32,555
  • 10
  • 92
  • 82
  • The flat buttons index do not change if we manually swipe between the tabs. Is it possible to restrict the swipe or update the buttons index when user swipe between the tabs? – Praveen Kumar Mar 20 '18 at 04:00
  • Yes, it is possible to restrict the user from manually scrolling between views. You can use pass a `new NeverScrollableScrollPhysics()` to `physics` property of the `TabBarView`. Updated my answer to to show how it can be done. – Hemanth Raj Mar 20 '18 at 04:05
0

Just use DefaultTabController

Scaffold(
      appBar: PreferredSize(
          preferredSize: const Size.fromHeight(kToolbarHeight),
          child: TabBar(
            isScrollable: false,
            indicator: BoxDecoration(
                borderRadius: BorderRadius.circular(8.0),
                color:
                    Theme.of(context).colorScheme.primary.withOpacity(0.3)),
            labelColor: Theme.of(context).colorScheme.primary,
            //Theme.of(context).brightness == Brightness.light ? Colors.black : Colors.white,
            unselectedLabelColor:
                Theme.of(context).brightness == Brightness.light
                    ? Colors.black54
                    : Colors.white60,
            tabs: _tabs,
          )),
      body: TabBarView(
        children: [
smedasn
  • 1,249
  • 1
  • 13
  • 16