dart – 如何在Flutter的滚动视图中限制滚动距离?

dart – 如何在Flutter的滚动视图中限制滚动距离?,第1张

概述我创建了一个页面,其中包含一个列中的几个文本字段和按钮,该列包含在具有背景图像的容器中.而这个容器本身就是一个scrollview小部件的子代. 因此,当一个人点击其中一个字段时,他们的键盘会d出(占据屏幕的一部分),这意味着一些按钮/字段在屏幕外,这是scrollview小部件用于其目的的地方. 这里的问题是我想限制滚动视图允许用户滚动的距离. 最低按钮下面有一些空白区域,我不希望用户能够一直滚 我创建了一个页面,其中包含一个列中的几个文本字段和按钮,该列包含在具有背景图像的容器中.而这个容器本身就是一个scrollvIEw小部件的子代.

因此,当一个人点击其中一个字段时,他们的键盘会d出(占据屏幕的一部分),这意味着一些按钮/字段在屏幕外,这是scrollvIEw小部件用于其目的的地方.

这里的问题是我想限制滚动视图允许用户滚动的距离.

最低按钮下面有一些空白区域,我不希望用户能够一直滚动到那里.这也是让体验变得简单,并且不会让用户“过度滚动”超过他应该输入的字段.

但由于背景图像是滚动视图的一部分,因此视图将允许用户向下滚动到图像底部.我想限制这个.

作为后续工作,我试图弄清楚如何设置初始滚动位置. (因此,当单击某个字段时,滚动视图会向下滚动到第一个文本字段,因此所有字段都在视图中.用户无需向下滚动它们.但我不希望重新应用此滚动位置每当用户点击某个字段时,当然.)

这是相关的(如果我的任何代码看起来非常糟糕请说出来,我是一般的编程新手并接受任何建议改进):

class LoginPageConstructor extends StatelessWidget {  @overrIDe  Widget build(BuildContext context) {    Assetimage loginBackgroundAsset =        new Assetimage("assets/loginscreen/backgroundrock.png");//    var _scrollController = new ScrollController(//        initialScrollOffset: 200.0,//        keepScrollOffset: true);    return new Scaffold(        body: new Container(      child: new ListVIEw(key: new PageStorageKey("divIDer 1"),//        controller: _scrollController,children: <Widget>[          new Stack(children: <Widget>[            new Container(            constraints: new BoxConstraints.expand(height: 640.0),decoration: new Boxdecoration(                  image: new decorationImage(                      image: loginBackgroundAsset,fit: BoxFit.cover)),child: new Column(              children: <Widget>[                new divIDer(height: 300.0,),new Center(child: new UsernameText(),new divIDer(height: 8.0,new Center(child: new PasswordText(),new divIDer(),new Loginbutton(),new SignUpbutton(),],))          ])        ],));  }}
解决方法 对于自动滚动字段进入视图,听起来你正在和 issue 10826搏斗.我在这个问题上发布了 workaround.我将解决方法改为您的示例代码;见下文. (你可能想稍微调整一下.)

如果您想阻止用户滚动,您可能只想确保使用下面相同的技术可见所有字段,然后使用NeverScrollableScrollPhysics作为ListVIEw的物理.或者,如果你有野心,你可以实现自定义滚动物理,如Gallery example所示.如果我是你,我会坚持#10826被修复.

import 'package:Meta/Meta.dart';import 'dart:async';import 'package:Flutter/material.dart';import 'package:Flutter/rendering.dart';voID main() {  runApp(new MaterialApp(home: new LoginPage()));}/// A Widget that ensures it is always visible when focused.class EnsureVisibleWhenFocused extends StatefulWidget {  const EnsureVisibleWhenFocused({    Key key,@required this.child,@required this.focusNode,this.curve: Curves.ease,this.duration: const Duration(milliseconds: 100),}) : super(key: key);  /// The node we will monitor to determine if the child is focused  final FocusNode focusNode;  /// The child Widget that we are wrapPing  final Widget child;  /// The curve we will use to scroll ourselves into vIEw.  ///  /// Defaults to Curves.ease.  final Curve curve;  /// The duration we will use to scroll ourselves into vIEw  ///  /// Defaults to 100 milliseconds.  final Duration duration;  EnsureVisibleWhenFocusedState createState() => new EnsureVisibleWhenFocusedState();}class EnsureVisibleWhenFocusedState extends State<EnsureVisibleWhenFocused> {  @overrIDe  voID initState() {    super.initState();    Widget.focusNode.addListener(_ensureVisible);  }  @overrIDe  voID dispose() {    super.dispose();    Widget.focusNode.removeListener(_ensureVisible);  }  Future<Null> _ensureVisible() async {    // Wait for the keyboard to come into vIEw    // Todo: position doesn't seem to notify Listeners when metrics change,// perhaps a NotificationListener around the scrollable Could avoID    // the need insert a delay here.    await new Future.delayed(const Duration(milliseconds: 600));    if (!Widget.focusNode.hasFocus)      return;    final RenderObject object = context.findRenderObject();    final RenderAbstractVIEwport vIEwport = RenderAbstractVIEwport.of(object);    assert(vIEwport != null);    ScrollableState scrollableState = Scrollable.of(context);    assert(scrollableState != null);    Scrollposition position = scrollableState.position;    double alignment;    if (position.pixels > vIEwport.getoffsetToReveal(object,0.0)) {      // Move down to the top of the vIEwport      alignment = 0.0;    } else if (position.pixels < vIEwport.getoffsetToReveal(object,1.0)) {      // Move up to the bottom of the vIEwport      alignment = 1.0;    } else {      // No scrolling is necessary to reveal the child      return;    }    position.ensureVisible(      object,alignment: alignment,duration: Widget.duration,curve: Widget.curve,);  }  Widget build(BuildContext context) => Widget.child;}class LoginPage extends StatefulWidget {  LoginPageState createState() => new LoginPageState();}class LoginPageState extends State<LoginPage> {  FocusNode _usernameFocusNode = new FocusNode();  FocusNode _passwordFocusNode = new FocusNode();  @overrIDe  Widget build(BuildContext context) {    return new Scaffold(      appbar: new Appbar(        Title: new Text('Example App'),body: new Container(        child: new ListVIEw(          physics: new NeverScrollableScrollPhysics(),key: new PageStorageKey("divIDer 1"),children: <Widget>[            new Container(              constraints: new BoxConstraints.expand(height: 640.0),decoration: new Boxdecoration(                image: new decorationImage(                  image: new NetworkImage(                    'https://Flutter.io/images/Flutter-mark-square-100.png',fit: BoxFit.cover,child: new Column(                children: <Widget>[                  new Container(                    height: 300.0,new Center(                    child: new EnsureVisibleWhenFocused(                      focusNode: _usernameFocusNode,child: new TextFormFIEld(                        focusNode: _usernameFocusNode,decoration: new inputdecoration(                          labelText: 'Username',new Container(height: 8.0),new Center(                    child: new EnsureVisibleWhenFocused(                      focusNode: _passwordFocusNode,child: new TextFormFIEld(                        focusNode: _passwordFocusNode,obscureText: true,decoration: new inputdecoration(                          labelText: 'Password',new Container(),new Raisedbutton(                    onpressed: () {},child: new Text('Log in'),child: new Text('Sign up'),);  }}
总结

以上是内存溢出为你收集整理的dart – 如何在Flutter的滚动视图中限制滚动距离?全部内容,希望文章能够帮你解决dart – 如何在Flutter的滚动视图中限制滚动距离?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1001854.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存