禁用网页浏览向上滚动

Disable pageview upward scroll

我在脚手架的正文中添加了综合浏览量(带有快照)。我希望用户只向下滚动页面,而不是向上滚动。你能帮忙吗?谢谢

您可以使用自定义滚动物理轻松实现,如下所示,

添加 CustomScrollPhysics() 作为您的 PageView()

的物理学
PageView(
      scrollDirection: Axis.vertical,
      physics: CustomScrollPhysics(),  <--- here!!
      controller: controller,
      children: <Widget>[
       //childrens
      ],
    );

创建仅向下滚动的 CustomScrollPhysycs()

 class CustomScrollPhysics extends ScrollPhysics {
              CustomScrollPhysics({ScrollPhysics parent}) : super(parent: parent);

              bool isGoingDown = false;

              @override
              CustomScrollPhysics applyTo(ScrollPhysics ancestor) {
                return CustomScrollPhysics(parent: buildParent(ancestor));
              }

              @override
              double applyPhysicsToUserOffset(ScrollMetrics position, double offset) {
                isGoingDown = offset.sign < 0;
                return offset;
              }

              @override
              double applyBoundaryConditions(ScrollMetrics position, double value) {
                //print("applyBoundaryConditions");
                assert(() {
                  if (value == position.pixels) {
                    throw FlutterError(
                        '$runtimeType.applyBoundaryConditions() was called redundantly.\n'
                        'The proposed new position, $value, is exactly equal to the current position of the '
                        'given ${position.runtimeType}, ${position.pixels}.\n'
                        'The applyBoundaryConditions method should only be called when the value is '
                        'going to actually change the pixels, otherwise it is redundant.\n'
                        'The physics object in question was:\n'
                        '  $this\n'
                        'The position object in question was:\n'
                        '  $position\n');
                  }
                  return true;
                }());
                if (value < position.pixels && position.pixels <= position.minScrollExtent)
                  return value - position.pixels;
                if (position.maxScrollExtent <= position.pixels && position.pixels < value)
                  // overscroll
                  return value - position.pixels;
                if (value < position.minScrollExtent &&
                    position.minScrollExtent < position.pixels) // hit top edge

                  return value - position.minScrollExtent;

                if (position.pixels < position.maxScrollExtent &&
                    position.maxScrollExtent < value) // hit bottom edge
                  return value - position.maxScrollExtent;

                if (!isGoingDown) {
                  return value - position.pixels;
                }
                return 0.0;
              }
            }

通过使自定义滚动物理从 ScrollPhysics 扩展,您可以像下面一样。

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  void initState() {
    super.initState();
  }

  emailAuthSheet(BuildContext context) {
    return showModalBottomSheet(
      context: context,
      isScrollControlled: true,
      builder: (context) {
        return Container(
          child: Wrap(
            children: [
              Padding(
                padding: const EdgeInsets.symmetric(horizontal: 150.0),
                child: Divider(
                  thickness: 4.0,
                ),
              ),
              Container(height: 450, color: Colors.blue[100]),
              // Provider.of<LandingService>(context,listen: false).passwordLessSignIn(context),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                  MaterialButton(
                      child: Text(
                        'Log in',
                        style: TextStyle(
                            fontSize: 18.0, fontWeight: FontWeight.bold),
                      ),
                      onPressed: () {}),
                  MaterialButton(
                      child: Text(
                        'Sign in',
                        style: TextStyle(
                            fontSize: 18.0, fontWeight: FontWeight.bold),
                      ),
                      onPressed: () {})
                ],
              ),
            ],
          ),
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: _buildBody(),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          emailAuthSheet(context);
        },
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }

  Widget _buildBody() {
    return PageView(
      scrollDirection: Axis.vertical,
      physics: CustomScrollPhysics(),
      children: [
        Container(
          height: 500,
          color: Colors.red,
          child: Center(
            child: Text(
              'Page index : 0',
              style: TextStyle(fontSize: 20),
            ),
          ),
        ),
        Container(
          height: 500,
          color: Colors.yellow,
          child: Center(
            child: Text(
              'Page index : 1',
              style: TextStyle(fontSize: 20),
            ),
          ),
        ),
        Container(
          height: 500,
          color: Colors.red,
          child: Center(
            child: Text(
              'Page index : 2',
              style: TextStyle(fontSize: 20),
            ),
          ),
        ),
        Container(
          height: 500,
          color: Colors.yellow,
          child: Center(
            child: Text(
              'Page index : 3',
              style: TextStyle(fontSize: 20),
            ),
          ),
        ),
      ],
    );
  }
}

class CustomScrollPhysics extends ScrollPhysics {
  CustomScrollPhysics({ScrollPhysics parent}) : super(parent: parent);

  bool isUp = false;

  @override
  CustomScrollPhysics applyTo(ScrollPhysics ancestor) {
    return CustomScrollPhysics(parent: buildParent(ancestor));
  }

  @override
  double applyPhysicsToUserOffset(ScrollMetrics position, double offset) {
    isUp = offset.sign < 0;
    return offset;
  }

  @override
  double applyBoundaryConditions(ScrollMetrics position, double value) {
    assert(() {
      if (value == position.pixels) {
        throw FlutterError(
            '$runtimeType.applyBoundaryConditions() was called redundantly.\n'
            'The proposed new position, $value, is exactly equal to the current position of the '
            'given ${position.runtimeType}, ${position.pixels}.\n'
            'The applyBoundaryConditions method should only be called when the value is '
            'going to actually change the pixels, otherwise it is redundant.\n'
            'The physics object in question was:\n'
            '  $this\n'
            'The position object in question was:\n'
            '  $position\n');
      }
      return true;
    }());
    if (value < position.pixels && position.pixels <= position.minScrollExtent)
      return value - position.pixels;
    if (position.maxScrollExtent <= position.pixels && position.pixels < value)
      return value - position.pixels;
    if (value < position.minScrollExtent &&
        position.minScrollExtent < position.pixels)
      return value - position.minScrollExtent;

    if (position.pixels < position.maxScrollExtent &&
        position.maxScrollExtent < value)
      return value - position.maxScrollExtent;

    if (!isUp) {
      return value - position.pixels;
    }
    return 0.0;
  }
}