如何在Flutter中滚动或跳转到PageView.builder或PageController的位置?

16

问题:在使用PageController加载页面视图后无法滚动到指定位置 *

就像在Android中的ViewPager滚动到特定页面

Widget _buildCarousel(BuildContext context, int selectedIndex) {

    PageController controller = PageController(viewportFraction: 1, keepPage: true);
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        SizedBox(
          // you may want to use an aspect ratio here for tablet support
          height: 400.0,
          width: 240,
          child: PageView.builder(
            itemCount: assetImageList.length,
            controller: controller,
            itemBuilder: (BuildContext context, int itemIndex) {
              return _buildCarouselItem(context, selectedIndex, itemIndex);
            },
          ),
        )
      ],
    );
  }
5个回答

15

终于找到了答案。只需设置initialPage:mSelectedPosition属性,如下:

child: PageView.builder(
        itemCount: mTemplateModelList.length,
        controller: PageController(initialPage: mSelectedPosition, keepPage: true, viewportFraction: 1),
        itemBuilder: (BuildContext context, int itemIndex) {
          return _buildCarouselItem(context, selectedIndex, itemIndex);
        },
      ),

如果您希望在单击按钮后滚动页面,那么可以使用jumpTo()方法,使用下面由另一位用户@android清楚说明的PageController


mSelectedPosition 是什么? - Felipe Sales

6

目前有两种处理您请求的选项:

PageView.builder(
  controller: _pageController,
  itemCount: _list.length,
  itemBuilder: (context, index) {
    return GestureDetector(
      onTap: () {
        _pageController.jumpToPage(index); // for regular jump
        _pageController.animateToPage(_position, curve: Curves.decelerate, duration: Duration(milliseconds: 300)); // for animated jump. Requires a curve and a duration
      },
      child: Container();
    );
  }
),

1
位置,我们如何获取这个值? - Abhishek Thapliyal
那将是您想要从一个索引移动到另一个索引的变量。 - Mariano Zorrilla

3

您可以使用jumpTo()方法来滚动PageView的位置。

在下面的示例中,我创建了一个changePageViewPostion()方法:

import 'package:flutter/material.dart';

class MyPageView extends StatefulWidget {
  createState() {
    return StateKeeper();
  }
}

class StateKeeper extends State<MyPageView> {

  PageController controller = PageController(viewportFraction: 1, keepPage: true);
  var currentPageValue = 0.0;
  var mItemCount = 10;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    controller.addListener(() {
      setState(() {
        currentPageValue = controller.page;
      });
    });
  }

  void changePageViewPostion(int whichPage) {
    if(controller != null){
      whichPage = whichPage + 1; // because position will start from 0
      double jumpPosition = MediaQuery.of(context).size.width / 2;
      double orgPosition = MediaQuery.of(context).size.width / 2;
      for(int i=0; i<mItemCount; i++){
        controller.jumpTo(jumpPosition);
        if(i==whichPage){
          break;
        }
        jumpPosition = jumpPosition + orgPosition;
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('PageView position change'),
      ),
      body: PageView.builder(
        controller: controller,
        itemBuilder: (context, position) {
          return Container(
            color: position % 2 == 0 ? Colors.blue : Colors.pink,
            child: Column(
              children: <Widget>[

                Center(
                  child: Text(
                    "Page " + (position + 1).toString(),
                    style: TextStyle(color: Colors.white, fontSize: 22.0),
                  ),
                ),

                Align(
                  alignment: FractionalOffset.bottomCenter,
                  child: Padding(padding: EdgeInsets.only(bottom: 20),
                    child: FloatingActionButton(
                        elevation: 0.0,
                        child: new Icon(Icons.check),
                        backgroundColor: new Color(0xFFE57373),
                        onPressed: (){
                          changePageViewPostion(5);
                        }
                    ),),
                ),

              ],
            ),
          );
        },
        itemCount: mItemCount,
      )
    );
  }


}

我们可以通过以下控制器获取当前位置:
controller.addListener(() {
      setState(() {
        currentPageValue = controller.page.toInt();
        print((currentPageValue + 1).toString());
      });
    });

希望对您有所帮助 :)

我需要在用户查看页面时立即执行此操作,而不是在用户点击按钮时执行。你能帮我吗? - jazzbpn
意思是当用户查看或滚动页面时,您需要滚动位置,例如在第一页或第二页。对吗? - android
如果我们能监听页面变化,那么我们就可以做到这一点。所以,有没有PageChangeListener? - jazzbpn
当然。谢谢!! - jazzbpn
我刚刚找到并发布了上面的答案。感谢你的帮助! - jazzbpn
很高兴你找到了它。但是我还是更新了我的答案。 - android

0

如果您只想使用按钮滚动到下一页,可以简单地使用以下方法。

  //Create a PageController variable
  late PageController _pageController;
  
  //Initialize the variable in the init method.
  @override
  void initState() {
    _pageController = PageController(
        initialPage: _activePage, keepPage: true, viewportFraction: 1);
    super.initState();
  }

  //Use this nextPage() method in the onPressed() method.
  onPressed: () {
    setState(() {
      _activePage < 2
         ? _activePage++
         : Navigator.pushReplacementNamed(
             context, LoginScreen.id);
    });

    _pageController.nextPage(
      duration: const Duration(milliseconds: 300),
      curve: Curves.decelerate,
    );
  }

0

记住,当进入页面视图中的特定屏幕时,不要使用

child: PageView.builder( physics: const NeverScrollableScrollPhysics(), )

它会禁用滚动功能


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接