【问题标题】:How to constraints width and height of `Scaffold` (useful for Web and Desktop)如何限制 `Scaffold` 的宽度和高度(适用于 Web 和桌面)
【发布时间】:2021-07-31 07:48:26
【问题描述】:

下面的截图是桌面上的Scaffold(在浏览器上应该是类似的):

是否可以将Scaffold 限制为最小尺寸(宽度和高度)?

如果屏幕宽度小于最小宽度,会出现水平滚动条左右移动。

如果屏幕高度小于最小高度,则会出现一个上下移动的垂直滚动条。

例如。我们项目中的设计师希望浏览器上的最小宽度为 960 像素。

【问题讨论】:

  • 您可以使用布局构建器并拥有一个自定义响应类,该类根据您提供的约束呈现不同的小部件。
  • 能否给我一份代码草稿 sn-p?

标签: flutter flutter-layout


【解决方案1】:

这是一个 main.dart 示例,它使用LayoutBuilder 将脚手架(body 和 appBar)限制为最小 480dp,如果宽度限制小于该值,则将脚手架包裹在水平的 @987654324 内@ 和 ScrollBar。如果约束高度小于 480dp,它会将脚手架(可能已经被包裹,也可能没有)包裹在垂直滚动中。

如果宽度和高度都小于 480dp,则可以看到 2 个滚动条。在这种情况下,小部件树必须是ScrollBar > ScrollBar > ScrollView > ScrollView。如果widget tree是ScrollBar > ScrollView > ScrollBar > ScrollView,则嵌套的Scrollbar只有在父ScrollBar滚动到边缘时才可见。

import 'package:flutter/material.dart';

main() {
  runApp(MaterialApp(
    // set default isAlwaysShown, so don't need to set for individual Scrollbar.
    theme: ThemeData(scrollbarTheme: ScrollbarThemeData(isAlwaysShown: true)),
    home: App(),
  ));
}

class App extends StatefulWidget {
  @override
  AppState createState() => AppState();
}

class AppState extends State<App> {
  final minWidth = 480.0;
  final minHeight = 480.0;

  ScrollController _horizontalController = ScrollController();
  ScrollController _verticalController = ScrollController();

  @override
  void dispose() {
    _horizontalController.dispose();
    _verticalController.dispose();
    super.dispose();
  }

  Widget _buildScaffold() {
    return Scaffold(
      appBar: AppBar(title: Text('2D Scrollbars')),
      body: Container(color: Colors.amber),
      bottomNavigationBar: BottomNavigationBar(
        items: [
          BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
          BottomNavigationBarItem(icon: Icon(Icons.school), label: 'School'),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    final scaffold = _buildScaffold();
    return LayoutBuilder(
      builder: (context, constraints) {
        final horizontalScrollbarEnabled = constraints.minWidth < minWidth;
        final verticalScrollbarEnabled = constraints.minHeight < minHeight;

        if (horizontalScrollbarEnabled && verticalScrollbarEnabled) {
          return Scrollbar(
            controller: _horizontalController,
            child: Scrollbar(
              // IMPORTANT: this scrollbar only handle notification of the vertical ScrollView.
              // The first ScrollView (depth = 0), is the horizontal one.
              // The second ScrollView (depth = 1), is the vertical one.
              // If notification.depth != 1, the notification is bubble up to horizontal Scrollbar.
              notificationPredicate: (notification) => notification.depth == 1,
              controller: _verticalController,
              child: SingleChildScrollView(
                controller: _horizontalController,
                scrollDirection: Axis.horizontal,
                child: SingleChildScrollView(
                  controller: _verticalController,
                  child: Container(
                    width: minWidth,
                    height: minHeight,
                    child: scaffold,
                  ),
                ),
              ),
            ),
          );
        } else if (horizontalScrollbarEnabled) {
          return Scrollbar(
            controller: _horizontalController,
            child: SingleChildScrollView(
              controller: _horizontalController,
              scrollDirection: Axis.horizontal,
              child: Container(
                width: minWidth,
                child: scaffold,
              ),
            ),
          );
        } else if (verticalScrollbarEnabled) {
          return Scrollbar(
            controller: _verticalController,
            child: SingleChildScrollView(
              controller: _verticalController,
              child: Container(
                height: minHeight,
                child: scaffold,
              ),
            ),
          );
        }

        return scaffold;
      },
    );
  }
}

【讨论】:

  • 谢谢@benjamin-lee!它适用于水平约束。我试图让它也适用于垂直约束。
  • @XuanDaiNguyen,我编辑了我的答案,使其同时使用水平和垂直滚动
  • 我暂时把这两个问题留在那里。我认为更好的解决方案是等待github.com/flutter/flutter/issues/64210
  • 我编辑了您的代码以修复嵌套滚动条问题。
猜你喜欢
  • 1970-01-01
  • 2012-05-03
  • 2013-04-25
  • 2016-09-11
  • 2011-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-03
相关资源
最近更新 更多