Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to make tabBar item responsive? #139

Open
NTMS2017 opened this issue Mar 27, 2021 · 6 comments
Open

How to make tabBar item responsive? #139

NTMS2017 opened this issue Mar 27, 2021 · 6 comments
Labels
wait for reply Further information is requested

Comments

@NTMS2017
Copy link

NTMS2017 commented Mar 27, 2021

Hi,

With a custom appear sample I try to make tabBar item responsive but seems margin and StyleHook is not allow me to make a more responsive.

For my app I use flutter_screenutil and auto_size_text plugin for responsive ui design. But can't make to work with tabor item.

Without modification (still not work as expected) the appear item looks too small on iPad mini4.
With current modification image is below.

Also I couldn't find any "tabContent" example and usage in your example apps. It looks If I can modify tabContent I might be able to make tabor items more responsive.

Any idea?

Note: In main.dart I use ScreenUtilInit(designSize: Size(360, 690),... for my design draft. I can change a different UI draft but output still same.

import 'package:auto_size_text/auto_size_text.dart';
import 'package:convex_bottom_bar/convex_bottom_bar.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:ntms_test_app/PageC.dart';
import 'package:ntms_test_app/pageA.dart';
import 'package:ntms_test_app/pageB.dart';

double myWidth;

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await SystemChrome.setEnabledSystemUIOverlays([]);
  await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);

  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ScreenUtilInit(
        designSize: Size(360, 690),
        allowFontScaling: true,
        builder: () => MaterialApp(
            debugShowCheckedModeBanner: false,
            title: 'Flutter Demo',
            theme: ThemeData(
              primarySwatch: Colors.blue,
            ),
            home: HomePage()));
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  int _currentIndex = 0;
  List<Color> _myColors = [Colors.green, Colors.red, Colors.blue];

  List<TabItem> items = <TabItem>[
    TabItem(icon: Icons.home, title: 'Home'),
    TabItem(icon: Icons.map, title: 'Discovery'),
    TabItem(icon: Icons.plus_one, title: 'Add'),
  ];

  Color pageColor;

  List<Widget> listWidgets = [PageA(myColor: Colors.green), PageB(myColor: Colors.red), PageC(myColor: Colors.blue)];

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    myWidth = MediaQuery.of(context).size.width;
    return Scaffold(
      key: _scaffoldKey,
      appBar: AppBar(
        title: AutoSizeText(
          'Custom ConvexAppBar',
          style: TextStyle(color: Colors.black, fontSize: 18.0.ssp),
        ),
        backgroundColor: _myColors[_currentIndex],
      ),
      body: listWidgets[_currentIndex],
      bottomNavigationBar: StyleProvider(
        style: Style(),
        child: ConvexAppBar(
          disableDefaultTabController: false,
          height: MediaQuery.of(context).size.width > 360 ? 70 : 50,
          top: MediaQuery.of(context).size.width > 360 ? -60 : -30,
          curveSize: MediaQuery.of(context).size.width > 360 ? 100 : 75,
          style: TabStyle.react,
          items: [
            TabItem(
              title: '2019',
              icon: Icon(
                Icons.link,
                color: _myColors[0],
                size: MediaQuery.of(context).size.width > 360 ? 40 : 20,
              ),
            ),
            TabItem(
                title: '2020',
                icon: Icon(
                  Icons.contact_page,
                  color: _myColors[1],
                  size: MediaQuery.of(context).size.width > 360 ? 40 : 20,
                )),
            TabItem(
                title: "2021",
                icon: Icon(
                  Icons.work,
                  color: _myColors[2],
                  size: MediaQuery.of(context).size.width > 360 ? 40 : 20,
                )),
          ],
          backgroundColor: Colors.yellow,
          activeColor: Colors.red,
          color: Colors.black,
          onTap: (i) {
            debugPrint('click $i');
            setState(() {
              _currentIndex = i;
              pageColor = _myColors[i];
            });
          },
        ),
      ),
    );
  }
}

/// CLASS STYLE
class Style extends StyleHook {
  @override
  double get activeIconSize => 40;

  @override
  double get activeIconMargin => 10;

  @override
  double get iconSize => 20;

  @override
  TextStyle textStyle(Color color) {
    return TextStyle(fontSize: 20.0.ssp);
  }
}

Screenshot 2021-03-27 at 13 48 20

@NTMS2017
Copy link
Author

NTMS2017 commented Mar 28, 2021

This is best I can make it to responsive. But for iPad the icon size is not changing.

SDK:

environment:
  sdk: ">=2.7.0 <3.0.0"

Plugin:

  cupertino_icons: ^1.0.2
  flutter_screenutil: ^5.0.0-nullsafety.11
  auto_size_text: ^3.0.0-nullsafety.0
  convex_bottom_bar: ^3.0.0

CODE:

import 'package:auto_size_text/auto_size_text.dart';
import 'package:convex_bottom_bar/convex_bottom_bar.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:ntms_test_app/PageC.dart';
import 'package:ntms_test_app/pageA.dart';
import 'package:ntms_test_app/pageB.dart';

double myWidth;

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await SystemChrome.setEnabledSystemUIOverlays([]);
  await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);

  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ScreenUtilInit(
        designSize: Size(360, 690),
        allowFontScaling: true,
        builder: () => MaterialApp(
            debugShowCheckedModeBanner: false,
            title: 'Flutter Demo',
            theme: ThemeData(
              primarySwatch: Colors.blue,
            ),
            home: HomePage()));
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  int _currentIndex = 0;
  List<Color> _myColors = [Colors.green, Colors.red, Colors.blue];

  List<TabItem> items = <TabItem>[
    TabItem(icon: Icons.home, title: 'Home'),
    TabItem(icon: Icons.map, title: 'Discovery'),
    TabItem(icon: Icons.plus_one, title: 'Add'),
  ];

  Color pageColor;

  List<Widget> listWidgets = [PageA(myColor: Colors.green), PageB(myColor: Colors.red), PageC(myColor: Colors.blue)];

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    myWidth = 1.sw;
    print("WIDTH: $myWidth");
    return Scaffold(
      key: _scaffoldKey,
      appBar: AppBar(
        title: AutoSizeText(
          'Custom ConvexAppBar',
          style: TextStyle(color: Colors.black, fontSize: 18.0.ssp),
        ),
        backgroundColor: _myColors[_currentIndex],
      ),
      body: listWidgets[_currentIndex],
      bottomNavigationBar: StyleProvider(
        style: Style(),
        child: ConvexAppBar(
          disableDefaultTabController: true,
          height: myWidth > 320 ? 70 : 50,
          top: myWidth > 320 ? -50 : -30,
          curveSize: myWidth > 320 ? 150 : 100,
          style: TabStyle.react,
          items: [
            TabItem(
              title: '2019',
              icon: Icon(
                Icons.link,
                color: _myColors[0],
              ),
            ),
            TabItem(
                title: '2020',
                icon: Icon(
                  Icons.contact_page,
                  color: _myColors[1],
                )),
            TabItem(
                title: "2021",
                icon: Icon(
                  Icons.work,
                  color: _myColors[2],
                )),
          ],
          backgroundColor: Colors.yellow,
          activeColor: Colors.red,
          color: Colors.black,
          onTap: (i) {
            debugPrint('click $i');
            setState(() {
              _currentIndex = i;
              pageColor = _myColors[i];
            });
          },
        ),
      ),
    );
  }
}

/// CLASS STYLE
class Style extends StyleHook {
  @override
  double get activeIconSize => myWidth > 320 ? 70 : 40;

  @override
  double get activeIconMargin => myWidth > 320 ? 15 : 10;

  @override
  double get iconSize => myWidth > 320 ? 35.ssp : 25.ssp;

  @override
  TextStyle textStyle(Color color) {
    return TextStyle(fontSize: myWidth > 320 ? 18.0.ssp : 16.0.ssp, fontWeight: FontWeight.bold);
  }
}

listWidgets A

import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';

/// PAGE A
class PageA extends StatefulWidget {
  final Color myColor;

  const PageA({Key key, this.myColor}) : super(key: key);

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

class _PageAState extends State<PageA> {
  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        mainAxisSize: MainAxisSize.max,
        children: <Widget>[
          Center(
              child: AutoSizeText(
            'Entry A',
            style: TextStyle(fontSize: 20.0.ssp, fontWeight: FontWeight.bold, color: widget.myColor),
          )),
        ],
      ),
    );
  }
}

IMAGE:
Screenshot 2021-03-28 at 09 58 34

@avenwu
Copy link
Contributor

avenwu commented Apr 6, 2021

@NTMS2017 The default example look fine on iPad mini4, so are you trying to make icon bigger on iPad? One more thing, I would suggest you ti provide two different style class, such as StyleIPad, StlyePhone to simplify the hook.

/// CLASS STYLE
class Style2 extends StyleHook {
  @override
  double get activeIconSize => 40 ;

  @override
  double get activeIconMargin => 5;

  @override
  double get iconSize => 50;

  @override
  TextStyle textStyle(Color color) {
    return TextStyle(fontSize: 12.0, fontWeight: FontWeight.bold);
  }
}

Screen Shot 2021-04-06 at 11 27 14

The style feature is limited. So if you can not make the tab to satisfy your case, you can make a custom one with other constructor, which allow you to define the tab by yourself.

  /// Define a custom tab style by implement a [DelegateBuilder].
  ///
  /// ```dart
  /// ConvexAppBar(
  ///   count: 5,
  ///   itemBuilder: Builder(),
  /// )
  ///
  /// class Builder extends DelegateBuilder {
  ///   @override
  ///   Widget build(BuildContext context, int index, bool active) {
  ///     return Text('TAB $index');
  ///   }
  /// }
  /// ```
  const ConvexAppBar.builder({
    Key? key,
    required this.itemBuilder,
    required this.count,
    this.initialActiveIndex,
    this.disableDefaultTabController = false,
    this.onTap,
    this.onTapNotify,
    this.controller,
    this.backgroundColor,
    this.gradient,
    this.height,
    this.curveSize,
    this.top,
    this.elevation,
    this.cornerRadius,
    this.curve = Curves.easeInOut,
    this.chipBuilder,
  }) 

@avenwu avenwu added the wait for reply Further information is requested label Apr 6, 2021
@NTMS2017
Copy link
Author

NTMS2017 commented Apr 6, 2021

Yes I am trying to make icon bigger on iPad. I will try your suggestion to make 2 different style. And write here the result

@NTMS2017
Copy link
Author

NTMS2017 commented Apr 6, 2021

Sorry :( couldn't make it. Do you have any custom (Define a custom tab style by implement a [DelegateBuilder].) example? If you can provide I will appreciated. Thanks

@avenwu
Copy link
Contributor

avenwu commented Apr 6, 2021

@vytautas-pranskunas-
Copy link

vytautas-pranskunas- commented Sep 22, 2023

@avenwu you are saying there you can customize everything, yes you are right.. but alsmot from scratch because you are not exposing things like TransitionContainer. and similar.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wait for reply Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants