【问题标题】:How can I build a responsive navbar using Flutter?如何使用 Flutter 构建响应式导航栏?
【发布时间】:2022-10-21 14:07:28
【问题描述】:

我在 Flutter 中为我的网站构建了一个导航栏,如下面的代码所示。我想做的就是让这个导航栏响应移动版本。我希望在移动版本中显示一个菜单图标,并且我的页面文本应该消失,当我点击这个菜单图标时我可以看到它。有谁知道我该怎么做?

import 'package:flutter/material.dart';

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

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: const Color(0xFF262533),
        body: ListView(
          children: [
            Stack(
              children: [
                Container(  
                  height: Get.height * .65, width: Get.width,       
                  color:  const Color(0xFF262533),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.start,
                    children: <Widget>[
                      const Padding(
                        padding: EdgeInsets.all(18.0),
                      ),
                      SizedBox(
                        height: 80,
                        width: 185,
                        child: Image.asset('assets/images/logo2.png'),
                      ),
                      const Spacer(),
                      const Text(
                        "Escorts",
                        style: TextStyle(
                          color: Colors.white,
                          fontSize: 24,
                          fontFamily: 'Poppins',
                        ),
                      ),
                      const SizedBox(
                        width: 32,
                      ),
                      const Text(
                        "Angenturen & Clubs",
                        style: TextStyle(
                          color: Colors.white,
                          fontSize: 24,
                          fontFamily: 'Poppins',
                        ),
                      ),
                      const SizedBox(
                        width: 32,
                      ),
                      const Text(
                        "Inserieren",
                        style: TextStyle(
                          color: Colors.white,
                          fontSize: 24,
                          fontFamily: 'Poppins',
                        ),
                      ),
                      const SizedBox(
                        width: 32,
                      ),
                      const Text(
                        "Werben",
                        style: TextStyle(
                          color: Colors.white,
                          fontSize: 24,
                          fontFamily: 'Poppins',
                        ),
                      ),
                      const SizedBox(
                        width: 32,
                      ),
                      const Text(
                        "Blog",
                        style: TextStyle(
                          color: Colors.white,
                          fontSize: 24,
                          fontFamily: 'Poppins',
                        ),
                      ),
                      const SizedBox(
                        width: 32,
                      ),
                      const Text(
                        "Kontakt",
                        style: TextStyle(
                          color: Colors.white,
                          fontSize: 24,
                          fontFamily: 'Poppins',
                        ),
                      ),
                      const Spacer(),
                      const Icon(
                        Icons.attach_money,
                        color: Colors.white,
                      ),
                      const SizedBox(
                        width: 20,
                      ),
                      const Icon(
                        Icons.chat,
                        color: Colors.white,
                      ),
                      const SizedBox(
                        width: 20,
                      ),
                      const Icon(
                        Icons.person,
                        color: Colors.white,
                      ),
                      const SizedBox(
                        width: 20,
                      ),
                      const Icon(
                        Icons.search,
                        color: Colors.white,
                      ),
                      const SizedBox(
                        width: 32,
                      ),
                    ],
                  ),
                ),
              ],
            ),

【问题讨论】:

    标签: flutter flutter-layout flutter-dependencies flutter-web flutter-animation


    【解决方案1】:

    - 更新

    我刚刚写了一篇关于响应式布局的文章。我们可以使用Padding、LayoutBuilder(如下面的回答),我最好的选择是extension context。

    在这里你可以阅读它:

    https://medium.easyread.co/3-options-for-creating-responsive-layouts-in-flutter-app-live-demo-68b0c0e955ab


    您使用LayoutBuilder() 并创建您需要的条件:

    例如:

    LayoutBuilder(builder: (context, constraints) {
      if (constraints.maxWidth >= 1500) {
        return desktopNavbar;
      } else if (constraints.maxWidth >= 650) {
        return tabletNavbar;
      } else {
        return mobileNavbar;
      }
    });
    

    为每个布局创建另一个组件:

    Widget mobileNavbar(){
     return Row(
      children: [ specific widget you want to show on mobile ]
     )
    }
    

    等等,适用于台式机或平板电脑。

    【讨论】:

    • 请你能用我的代码来解释一下吗?我真的很困惑。 @pmatatias
    • 更新你的代码,你把那个容器放在哪里了? ,我不能仅从该代码中给出具体示例
    • 你现在可以找到我更新的代码@pmatatias
    • 我在等你的回复@pmatatias
    【解决方案2】:

    您应该使用媒体查询来提供高度和宽度,因为它将根据设备大小设置这些属性。你应该这样做。

    喜欢:

    Container(
     height: MediaQuery.of(context).size.width * 0.65,
     width: MediaQuery.of(context).size.height * 0.65,
      ),
    

    【讨论】:

    • 不,它没有用@Nil Dervalia
    【解决方案3】:

    试试这个使用大小类配置

    class SizeConfig {
      SizeConfig._();
      static final SizeConfig _instance = SizeConfig._();
      factory SizeConfig() => _instance;
    
      late MediaQueryData _mediaQueryData;
      late double screenWidth;
      late double screenHeight;
      late double blockSizeHorizontal;
      late double blockSizeVertical;
      late double _safeAreaHorizontal;
      late double _safeAreaVertical;
      late double safeBlockHorizontal;
      late double safeBlockVertical;
      double? profileDrawerWidth;
      late double refHeight;
      late double refWidth;
    
      void init(BuildContext context) {
        _mediaQueryData = MediaQuery.of(context);
        screenWidth = _mediaQueryData.size.width;
        screenHeight = _mediaQueryData.size.height;
        refHeight = 1450;
        refWidth = 670;
    
        if (screenHeight < 1200) {
          blockSizeHorizontal = screenWidth / 100;
          blockSizeVertical = screenHeight / 100;
    
          _safeAreaHorizontal =
              _mediaQueryData.padding.left + _mediaQueryData.padding.right;
          _safeAreaVertical =
              _mediaQueryData.padding.top + _mediaQueryData.padding.bottom;
          safeBlockHorizontal = (screenWidth - _safeAreaHorizontal) / 100;
          safeBlockVertical = (screenHeight - _safeAreaVertical) / 100;
        } else {
          blockSizeHorizontal = screenWidth / 120;
          blockSizeVertical = screenHeight / 120;
    
          _safeAreaHorizontal =
              _mediaQueryData.padding.left + _mediaQueryData.padding.right;
          _safeAreaVertical =
              _mediaQueryData.padding.top + _mediaQueryData.padding.bottom;
          safeBlockHorizontal = (screenWidth - _safeAreaHorizontal) / 120;
          safeBlockVertical = (screenHeight - _safeAreaVertical) / 120;
        }
      }
    
      double getWidthRatio(double val) {
        double res = (val / refWidth) * 100;
        double temp = res * blockSizeHorizontal;
    
        return temp;
      }
    
      double getHeightRatio(double val) {
        double res = (val / refHeight) * 100;
        double temp = res * blockSizeVertical;
        return temp;
      }
    
      double getFontRatio(double val) {
        double res = (val / refWidth) * 100;
        double temp = 0.0;
        if (screenWidth < screenHeight) {
          temp = res * safeBlockHorizontal;
        } else {
          temp = res * safeBlockVertical;
        }
    
        return temp;
      }
    }
    
    extension SizeUtils on num {
      double get toWidth => SizeConfig().getWidthRatio(toDouble());
      double get toHeight => SizeConfig().getHeightRatio(toDouble());
      double get toFont => SizeConfig().getFontRatio(toDouble());
    }
    

    【讨论】:

    • 请问我在哪里可以在我的代码中使用它? @零
    • SizedBox(height: Get.height * .6, width: Get.width * .18, child: Image.asset('assets/images/logo.png'), ),使用getX或者直接使用class object或者final screenhight = SizeConfig().blockSizeVertical;然后使用
    • 我不明白@Nil
    • 请使用我的代码并告诉我如何在那里使用它@Nil
    • 检查此示例medium.com/flutter-community/… 根据要求更改
    【解决方案4】:

    要基于屏幕隐藏某些小部件,您只能在屏幕足够大时才包含它们。例如,只需替换

    const Text(
      "Escorts",
      style: TextStyle(
        color: Colors.white,
        fontSize: 24,
        fontFamily: 'Poppins'
      )
    )
    

    和

    if (Get.width > 1000) const Text(
      "Escorts",
      style: TextStyle(
        color: Colors.white,
        fontSize: 24,
        fontFamily: 'Poppins'
      )
    )
    

    同样,您只能在宽度足够小时才显示菜单图标

    【讨论】:

    • 它说未定义的名称“获取”@Ivo
    • @Amarildo 你的代码已经在另一个地方显示了Get.width,所以它应该可以工作。否则使用MediaQuery.of(context).size.width
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-13
    • 1970-01-01
    • 1970-01-01
    • 2021-11-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多