how to set CupertinoSegmentedControl height?
Asked Answered
P

3

5

I am trying to use CupertinoSegmentedControl from the flutter Cupertino library in the AppBar using the bottom attribute to achieve the following design (height = 32)

cupertino segmented control

so I tried the following :

@override
    Widget build(BuildContext context) {
        return Scaffold(
                appBar: AppBar(
                    elevation: 2,
                    backgroundColor: Colors.white,
                    centerTitle: true,
                    title: Text(this.widget.title, style: TextStyle(color: Colors.black)),
                    bottom: PreferredSize(
        child: Padding(
          padding: const  EdgeInsets.only(top: 8, bottom: 12),
          child: Row(
            children: <Widget>[
              SizedBox(width: 24),
              Expanded(
                child: CupertinoSegmentedControl(
                  children: this.widget.tabs,
                  groupValue: this._selectedTab,
                  onValueChanged: (value) {
                    this.setState(() => this._selectedTab = value);
                    this._tabController.animateTo(value);
                  }
                ),
              ),
              SizedBox(width: 24)
            ],
          ),
        ),
        preferredSize: Size(double.infinity, 48)
      )
                ),
                body: new TabBarView(
                    controller: this._tabController,
                    children: this.widget.views,
                ));
    } 
Pedicab answered 29/12, 2018 at 13:46 Comment(1)
Look at my answer. I don't know if did understand what you actually want, If it's not of any help, I'm going to remove it.Kulseth
K
6

Is something like that similar to the layout that you want? (Removing the green color of course ^_^)

Play around with the Container and PreferredSize heights to adjust the height to fit your needs.

enter image description here

Scaffold(
    appBar: AppBar(
        elevation: 2,
        backgroundColor: Colors.white,
        centerTitle: true,
        title:
            Text(this.widget.title, style: TextStyle(color: Colors.black)),
        bottom: PreferredSize(
            child: Row(
              children: [
                Expanded(
                  child: Container(
                    height: 48,
                    color: Colors.lightGreenAccent,
                    child: CupertinoSegmentedControl(
                        children: children,
                        groupValue: this._selectedTab,
                        onValueChanged: (value) {
                          this.setState(() => this._selectedTab = value);
                        }),
                  ),
                )
              ],
            ),
            preferredSize: Size(double.infinity, 48))),
    body: Center(
        child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Text('hello')
        ]
        )
    )
);

UPDATE:

enter image description here

As kazimad pointed out, if you want to increase the segmented control height and not only add padding to it insiede the app bar, you can add a Padding widget to your tabs, like that:

@override
Widget build(BuildContext context) {
  return Scaffold(
      appBar: AppBar(
          elevation: 2,
          backgroundColor: Colors.white,
          centerTitle: true,
          title:
              Text(this.widget.title, style: TextStyle(color: Colors.black)),
          bottom: PreferredSize(
              child: Padding(
                padding: const EdgeInsets.only(top: 8, bottom: 12),
                child: Row(
                  children: <Widget>[
                    SizedBox(width: 24),
                    Expanded(
                      child: CupertinoSegmentedControl(
                          children: const <int, Widget>{
                            0: Padding(
                                padding: EdgeInsets.all(8.0),
                                child: Text('Midnight')),
                            1: Padding(
                                padding: EdgeInsets.all(8.0),
                                child: Text('Viridian')),
                            2: Padding(
                                padding: EdgeInsets.all(8.0),
                                child: Text('Cerulean'))
                          },
                          groupValue: this._selectedTab,
                          onValueChanged: (value) {
                            // TODO: - fix it
                          }),
                    ),
                    SizedBox(width: 24)
                  ],
                ),
              ),
              preferredSize: Size(double.infinity, 48))),
      body: Center(
          child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [Text('hello')])));
}
Kulseth answered 29/12, 2018 at 16:50 Comment(2)
sorry, but it doesn't work. CupertinoSegmentedControl doesn't expands it's heightReider
@Reider You're right. I've totally forgot this answer, but reding it again I realized what the OP really asked. I've updated my answer accordingly.Kulseth
R
5

just add Padding widget, or margin property to Container and wrap your Widgets in your "tabs" collection (in you case it is this.widget.tabs) with it

in my case

CupertinoSegmentedControl<int>(
            children: segmentTextWidgets,
            ...
          ),


final Map<int, Widget> segmentTextWidgets = <int, Widget>{
    0: Container(
      margin: const EdgeInsets.symmetric(vertical: 16),
      child: Text("Tab 1 title"),
    ),
    1: Container(
      margin: const EdgeInsets.symmetric(vertical: 16),
      child: Text("Tab 2 title"),
    ),
  };
Reider answered 3/4, 2020 at 13:31 Comment(1)
Your answer is correct, but you could improve it with a minimal functioning sample code and images so that it's more educational for the future readers.Kulseth
C
0

Here is full example based on @shadowsheep 's answer but improve version.

my_cupertino_segmented_control.dart

class MyCupertinoSegmentedControl extends StatelessWidget {
  final Map<int, Widget> children;
  final int? groupValue;
  final Function(int)? onValueChanged;

  const MyCupertinoSegmentedControl(
      {required this.children,
      this.groupValue,
      this.onValueChanged,
      super.key});

  @override
  Widget build(BuildContext context) {
    return PreferredSize(
        preferredSize: const Size(double.infinity, 48),
        child: Padding(
          padding: const EdgeInsets.only(top: 8, bottom: 12),
          child: Row(
            children: <Widget>[
              const SizedBox(width: 24),
              Expanded(
                child: CupertinoSegmentedControl<int>(
                    children: children,
                    groupValue: groupValue,
                    onValueChanged: (value) {
                      onValueChanged?.call(value);
                    }),
              ),
              const SizedBox(width: 24)
            ],
          ),
        ));
  }
}

It wrapped the annoying details to a simple widgets.

example.dart

import 'package:flutter/cupertino.dart';
import 'package:my_project/views/my_cupertino_segmented_control.dart';

class HomePageScaffold extends StatelessWidget {
  const HomePageScaffold({super.key});

  @override
  Widget build(BuildContext context) {
    return const CupertinoPageScaffold(
      navigationBar: CupertinoNavigationBar(
        middle: Text('Segmented Control Example'),
      ),
      child: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

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

class HomePageState extends State<HomePage> {
  Map<int, Widget> segmentedWidgets = {};
  List<Widget> tabWidgets = [];
  int selectedIndex = 0;

  @override
  void initState() {
    super.initState();
    _loadSegmentedWidgets();
    _loadTabWidgets(); //Method to add the Children as user selected.
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Column(
        children: <Widget>[
          MyCupertinoSegmentedControl(
              children: segmentedWidgets,
              groupValue: selectedIndex,
              onValueChanged: (value) {
                setState(() {
                  selectedIndex = value;
                });
              }),
          tabWidgets[selectedIndex],
        ],
      ),
    );
  }

  void _loadSegmentedWidgets() {
    for (int i = 0; i < 4; i++) {
      segmentedWidgets[i] = Padding(
        padding: const EdgeInsets.all(8.0),
        child: Text("Tab ${i + 1}"),
      );
    }
  }

  void _loadTabWidgets() {
    for (int i = 0; i < 4; i++) {
      tabWidgets.add(
        Center(
          child: Text("Detail ${i + 1}"),
        ),
      );
    }
  }
}

It's initialize the CupertinoPageScaffold and 4 tabs with tab details.

Here's preview

preview

Clevis answered 13/7 at 22:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.