PageView:禁用默认滚动并将其替换为Tap事件

azi*_*iza 26 dart flutter

如果我有一个PageView,如何禁用默认滚动行为(滑动),并通过点击按钮使下一个项目滚动到视图中?

Chr*_*son 70

要禁用滑动,您可以设置:

PageView(physics:new NeverScrollableScrollPhysics())
Run Code Online (Sandbox Code Playgroud)

  • 只是要回答@SakchhamSharma的问题:这只会禁用滑动,并且您仍然可以通过控制器以编程方式为其他页面设置动画,以用于_controller.nextPage()。 (2认同)
  • 嗨@JannieTheunissen,我的意思是专门滚动。您可以更改页面,是的;但由于底层的“NeverScrollableScrollPhysics”,动画受到限制。 (2认同)

GIL*_*ILO 7

停止滚动的最佳方法是更改​​页面视图的物理参数

如果 PageView 处于开始或结束使用状态,则停止滚动越过边缘

physics: ClampingScrollPhysics()
Run Code Online (Sandbox Code Playgroud)

要完全停止滚动使用

physics: NeverScrollableScrollPhysics()
Run Code Online (Sandbox Code Playgroud)


小智 6

要禁用手势滑动,请将以下属性添加到您的 PageView:

PageView(physics:new NeverScrollableScrollPhysics())
Run Code Online (Sandbox Code Playgroud)

要导航到 PageView 中的下一页/小部件,请将以下代码添加到按钮的 onPressed 属性中:

_pageController.nextPage(
     duration: Duration(milliseconds: 1000),
     curve: Curves.easeIn
);
Run Code Online (Sandbox Code Playgroud)


azi*_*iza 5

因此,我尝试通过以下方式弄清楚这一点,如果有人有更好的解决方案,请与我们分享。

使一个按钮转到下一个项目PageView

一个添加PageController到您的PageView,并且这些方法animateTojumpTo当用户按下一个按钮转到所需的项目。我这样做的目的是使当前视图的整个宽度都是偏移量,因此可以成功过渡到下一个项目。

onPressed: () {
        c.animateTo(MediaQuery
            .of(context)
            .size
            .width, duration: new Duration(seconds: 1),
            curve: Curves.easeIn);
      }
Run Code Online (Sandbox Code Playgroud)

禁用默认的刷卡行为:

我所做的只是包裹我的PageView内部,IgnorePointer以忽略任何用户交互,我真的不喜欢这种解决方案,在这个示例中它可能工作得很好,但是,在其他情况下,我可能希望用户与内部的单个小部件进行交互。当前显示的页面。

这是我的示例代码:

在此处输入图片说明

class FirstPage extends StatefulWidget {
  @override
  _FirstPageState createState() => new _FirstPageState();
}

class _FirstPageState extends State<FirstPage> {
  ScrollController c;

  @override
  void initState() {
    super.initState();
    c = new PageController();
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      floatingActionButton: new Row(
        mainAxisAlignment: MainAxisAlignment.end,
        crossAxisAlignment: CrossAxisAlignment.end,

        children: <Widget>[
          new FloatingActionButton(
              child: new Icon(Icons.navigate_before), onPressed: () {
            //c.animateTo(MediaQuery.of(context).size.width, duration: new Duration(seconds: 1), curve: Curves.easeIn);
            c.jumpTo(0.0);
          }),
          new Container(width: 15.0,),
          new FloatingActionButton(
              child: new Icon(Icons.navigate_next), onPressed: () {
            c.animateTo(MediaQuery
                .of(context)
                .size
                .width, duration: new Duration(seconds: 1),
                curve: Curves.easeIn);
          }),
        ],),
      appBar: new AppBar(title: new Text("First Page")),
      body: new IgnorePointer(child: new PageView(
        controller: c,
        children: <Widget>[
          new Column (
              children: <Widget>[new Container (child: new Text("First Item"))
              ]),
          new Container (child: new Text("Second Item")),
        ],
      ),),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

欢迎对此解决方案提出任何建议或修改。


And*_*son 5

附加说明可能会对某些人有所帮助。

如果其中一个页面中有一个已停止对手势做出反应的动态 GoogleMap,则使用 PageView(physicals:new NeverScrollableScrollPhysics()) 非常有用。看来 PageView 优先并覆盖地图。

添加 NeverScrollablePhysics() 允许地图再次对手势做出反应。

谢谢