Как включить полосу прокрутки для вертикальной прокрутки и отключить для горизонтальной?

Я строил макет как с горизонтальной, так и с вертикальной прокруткой. Вертикальная прокрутка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}"),
    );
  }
}

Обратите внимание на низ при горизонтальной прокрутке

2 ответа

Решение
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 вокруг виджета прокрутки, вы же не хотите, чтобы полоса прокрутки появлялась. Это решило проблему для меня!

Ответ Никласа не сработал для меня во Flutter 2.5. Я не знаю, потому что у меня другой макет или что-то в этом роде. Но если у вас есть PageView (например, карусель) внутри ListView, я нашел способ удаления полосы прокрутки PageView следующим образом.

Добавить к Scrollbar виджет notificationPredicate:

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

Полоса прокрутки будет отображаться только для вертикальных взаимодействий.

Документация Flutter о notificationPredicate .

Другие вопросы по тегам