【问题标题】:SingleChildScrollView inside Row行内的 SingleChildScrollView
【发布时间】:2019-12-06 13:31:16
【问题描述】:

我有一个由 Column 组成的布局,其中一个元素是一行(因此它占据了屏幕的整个宽度)。在该行内,我有一个包装,它的内容非常大,我想放在 SingleChildScrollView 中。

@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Container(
          padding: const EdgeInsets.all(kPaddingMainContainer),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text('Title', style: Theme.of(context).textTheme.title)
                ],
              ),
              Padding(
                padding: const EdgeInsets.only(top: 10),
              ),
              Row(
                children: <Widget>[
                  Expanded(
                    child: SingleChildScrollView(
                      child: Wrap(
                        alignment: WrapAlignment.center,
                        runSpacing: 20.0, // distance between rows
                        spacing: 30.0, // distance between chips
                        children: _getWidgets(),
                      ),
                    ),
                  ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }

使用此代码,我无法让 SingleChildScrollView 使包装可滚动。相反,我收到了 RenderFlex 溢出错误。

但是,如果我从 Row 中提取包装,如下所示:

@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Container(
          padding: const EdgeInsets.all(kPaddingMainContainer),
          child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Text('Title', style: Theme.of(context).textTheme.title)
                  ],
                ),
                Padding(
                  padding: const EdgeInsets.only(top: 10),
                ),
                Expanded(
                  child: SingleChildScrollView(
                    child: Wrap(
                      alignment: WrapAlignment.center,
                      runSpacing: 20.0, // distance between rows
                      spacing: 30.0, // distance between chips
                      children: _getWidgets(),
                    ),
                  ),
                ),
              ]),
        ),
      ),
    );
  }

然后,卷轴开始工作了。

但是,现在包装不再扩展为全宽,这是我想要的。

如何在 Row 中使用 SingleChildScrollView ?

PS:我不想将 Column 包裹在 SingleChildScrollView 中,因为我希望我的标题保持固定,并且只有下面的包裹可以滚动。

【问题讨论】:

  • 为什么需要使用Row
  • Slivers 怎么样?
  • @AndreyTurkovsky:我的经验是,如果我不将换行放在行内,它不会扩展到全宽,因此用户只能通过触摸换行区域内来滚动,什么不是很人性化。他应该能够通过触摸水平轴上的任意位置(环绕)来滚动。所以这就是我将它包装成一行的原因。
  • @JulienLachal:我还没有考虑这个选项,我认为只有 SingleChildScrollView 应该可以。这是要走的路吗?
  • AFAIK SingleChildScrollView 在您想要滚动超过屏幕大小时很有用,而不是使用 ListView 并在它占据手机的整个高度时卡住。当它们出现在视口之外时,它还允许您保持所有小部件“活动”。看看Flutter video

标签: android ios layout flutter dart


【解决方案1】:

我找到了一个解决方案,将 Wrap 包装在一个 ConstrainedBox(而不是一行)中,其中 minWidth 是屏幕的宽度。

@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Container(
          padding: const EdgeInsets.all(kPaddingMainContainer),
          child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Text('Title', style: Theme.of(context).textTheme.title)
                  ],
                ),
                Padding(
                  padding: const EdgeInsets.only(top: 10),
                ),
                Expanded(
                  child: SingleChildScrollView(
                    child: ConstrainedBox(
                      constraints: BoxConstraints(
                        minWidth: MediaQuery.of(context).size.width,
                      ),
                      child: Wrap(
                        alignment: WrapAlignment.center,
                        runSpacing: 20.0, // distance between rows
                        spacing: 30.0, // distance between chips
                        children: _getWidgets(),
                      ),
                    ),
                  ),
                ),
              ]),
        ),
      ),
    );
  }

这解决了我的问题,现在我只能通过点击屏幕上的任意位置来滚动 Wrap 小部件,而第一行的标题保持不变。

【讨论】:

    猜你喜欢
    • 2021-11-23
    • 2021-10-28
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    • 2021-01-18
    • 2020-02-17
    • 1970-01-01
    • 2020-11-05
    相关资源
    最近更新 更多