本文介绍了如何处理Flutter PageView中的滚动视图手势?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  1. 我的问题摘要

目标

我的目标是呈现一个长页面的轮播.因此,我将PageView与scrollviews一起使用.PageView水平滚动.滚动视图(子级)垂直滚动.

My goal is to present a carousel with long pages.So I use a PageView with scrollviews.The PageView scrolls horizontally.The scrollviews (children) scroll vertically.

预期结果

水平滑动并垂直滚动.

实际结果

如果我水平滑动到下一页,则无法立即垂直滚动.我需要等待1秒钟.看来用户必须等待动画完成才能与新的当前页面进行交互.

If I swipe horizontally to the next page, I can't scroll it vertically right away.I need to wait for 1 second.It seems the user must wait the animation completion to be able to interact with the new current page.

到目前为止我尝试过什么:

  • 我尝试了手势识别器来传递拖动事件,但是我没有使它起作用.
  • 我尝试了不同的小部件来替换PageView,但效果相同.
  • 我用wantKeepAlive = true尝试过AutomaticKeepAliveClientMixin
  • 我尝试了PageView.physics = AlwaysScrollableScrollPhysics()

这是重现问题所需的最少代码

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

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

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: carousel(),
    );
  }

  Widget carousel() {
    return PageView(
      children: <Widget>[
        page(Colors.pinkAccent),
        page(Colors.blueAccent),
        page(Colors.orangeAccent)
      ],
    );
  }

  Widget page(Color color) {
    return Container(
        decoration: BoxDecoration(
          color: color,
        ),
        child: SingleChildScrollView(
          child: Column(
              children: pageContent()),
        ));
  }

  List<Widget> pageContent() {
    return <Widget>[
      Row(children: <Widget>[Text("Hop", textScaleFactor: 5,)]),
      Row(children: <Widget>[Text("Hop", textScaleFactor: 5,)]),
      Row(children: <Widget>[Text("Hop", textScaleFactor: 5,)]),
      Row(children: <Widget>[Text("Hop", textScaleFactor: 5,)]),
      Row(children: <Widget>[Text("Hop", textScaleFactor: 5,)]),
      Row(children: <Widget>[Text("Hop", textScaleFactor: 5,)]),
      Row(children: <Widget>[Text("Hop", textScaleFactor: 5,)]),
      Row(children: <Widget>[Text("Hop", textScaleFactor: 5,)]),
      Row(children: <Widget>[Text("Hop", textScaleFactor: 5,)]),
      Row(children: <Widget>[Text("Hop", textScaleFactor: 5,)]),
      Row(children: <Widget>[Text("Hop", textScaleFactor: 5,)]),
      Row(children: <Widget>[Text("Hop", textScaleFactor: 5,)]),
      Row(children: <Widget>[Text("Hop", textScaleFactor: 5,)]),
      Row(children: <Widget>[Text("Hop", textScaleFactor: 5,)]),
      Row(children: <Widget>[Text("Hop", textScaleFactor: 5,)]),
      Row(children: <Widget>[Text("Hop", textScaleFactor: 5,)]),
    ];
  }
}

推荐答案

我成功找到了一种解决方案,可以使PageView在水平和垂直方向上都非常平滑.

I succeeded to find a solution to make my PageView really smooth horizontally and vertically.

我禁用PageView.pageSnapping以使轮播非常平滑.但是,我失去了磁性效果,因此我使用NotificationListener来捕获ScrollEndNotification事件.滚动结束时,我计算出对用户来说最可见的页面,并调用PageController.animateToPage()完成该工作.

I disable PageView.pageSnapping to make the carousel very smooth.However I lost the magnetic effect, so I use a NotificationListener to catch the ScrollEndNotification event.When the scrolling ends, I calculate the most visible page to the user and call PageController.animateToPage() to finish the job.

代码如下:

Widget getCarousel() {

  return NotificationListener<ScrollNotification>(
  onNotification: (scrollNotification) {

    if (scrollNotification is ScrollEndNotification) {
      print("ScrollEndNotification");

      Future.delayed(const Duration(milliseconds: 0), () {
        int newPage = pageController.page.round();
        print("end at $newPage");
        pageController.animateToPage(newPage, duration: Duration(milliseconds: 400), curve: Curves.fastOutSlowIn);
      });
    }
    return true;
  },
  child: PageView.builder(
    scrollDirection: Axis.horizontal,
    pageSnapping: false,
    controller: pageController,
    itemBuilder: (BuildContext context, int index) {
      return myPages[index];
    },
  )
);
}

这篇关于如何处理Flutter PageView中的滚动视图手势?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-04 21:48