如何启用垂直滚动的滚动条并禁用水平滚动?

Posted

技术标签:

【中文标题】如何启用垂直滚动的滚动条并禁用水平滚动?【英文标题】:How do I enable scrollbar for vertical scroll and disable for horizontal? 【发布时间】:2020-06-07 20:55:06 【问题描述】:

我一直在构建具有水平和垂直滚动的布局。垂直可滚动的Column 用于主要内容,并由不同的视图填充,包括显示促销横幅的水平ListView。我想显示垂直滚动的滚动条,而不是水平滚动。我已经包裹了SingleChildScrollView,这使得Column 可以在ScrollBar 中滚动,但是该栏出现在水平滚动的两个垂直方向上。对这些事情有任何微调吗?

演示问题的示例

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      title: 'Scrollables',
      home: MyHomePage(),
    );
  


class MyHomePage extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return Scaffold(
      body: Scrollbar(
        child: new SingleChildScrollView(
            child: new Container(
          padding: EdgeInsets.only(top: 40.0),
          child: Column(children: <Widget>[
            HorizontalListView(),
            VerticalListView(),
          ]),
        )),
      ),
    );
  


class HorizontalListView extends StatelessWidget 
  var items = new List<String>();

  _addNewItem(int index) 
    items.add("Item $index");
  

  @override
  Widget build(BuildContext context) => Container(
      height: 120,
      child: ListView.builder(
          scrollDirection: Axis.horizontal,
          itemCount: 15,
          itemBuilder: (context, index) 
            return Card(child: ListItem(index));
          ));


class VerticalListView extends StatelessWidget 
  var items = new List<String>();

  _addNewItem(int index) 
    items.add("Item $index");
  

  @override
  Widget build(BuildContext context) => Container(
      child: ListView.builder(
          scrollDirection: Axis.vertical,
          itemCount: 50,
          shrinkWrap: true,
          physics: const NeverScrollableScrollPhysics(),
          itemBuilder: (context, index) 
            return ListItem(index);
          ));


class ListItem extends StatelessWidget 
  int _index;
  ListItem(this._index);
  @override
  Widget build(BuildContext context) 
    return Container(
      width: 280,
      child: Text("Item $this._index"),
    );
  


横向滚动注意底部

【问题讨论】:

你找到解决办法了吗? 很遗憾,我没有。仍在尝试解决这个问题。 【参考方案1】:
class NoScrollbar extends StatelessWidget 
  final Widget child;
  const NoScrollbar(Key key, this.child) : super(key: key);

  @override
  Widget build(BuildContext context) 
    return NotificationListener<ScrollNotification>(
      onNotification: (_) => true,
      child: child,
    );
  

只需将 NoScrollbar Widget 包裹在 Scrolling Widget 周围,您不想让 Scrollbar 出现。这为我解决了!

【讨论】:

我不明白这是如何工作的,但它确实有效 @MobileMon 颤动滚动条基于ScrollNotifications,并且因为从NotificationListener&lt;ScrollNotification&gt; onNotification 返回true 将防止通知冒泡,它不会到达Scrollbar 小部件和因此它不会出现【参考方案2】:

Niklas 的回答在 Flutter 2.5 中对我不起作用。我不知道是因为我的布局不同还是什么。但是,如果您在 ListView 中有一个 PageView(例如作为轮播),我发现删除 PageView 的滚动条的方式如下。

添加到Scrollbar 小部件notificationPredicate

notificationPredicate: (ScrollNotification notification) 
  return notification.depth == 0 && notification.metrics.axis == Axis.vertical;

这只会显示垂直交互的滚动条。

关于 notificationPredicate 的 Flutter 文档。

【讨论】:

以上是关于如何启用垂直滚动的滚动条并禁用水平滚动?的主要内容,如果未能解决你的问题,请参考以下文章

Java 在 JTextArea 中禁用水平自动滚动

禁用浏览器垂直和水平滚动条

如何隐藏窗口滚动条并使滚动仍然有效[重复]

Bootstrap:如何禁用垂直滚动条?

如何在Android应用程序中添加垂直滚动条? [关闭]

如何仅在 UITextView 上强制水平滚动