滑动时向 PageView 添加新页面

2024-05-10

我目前正在制作一个日历应用程序,我想向右或向左滑动以转到下个月或上个月。我使用 PageView 时首先设置了一个包含 3 个项目的数组,第一个页面是第二个项目。我想向右滑动并在末尾添加一个页面。我想向左滑动并在开头添加一个页面。目前,如果您转到右侧(将页面添加到末尾),效果会很好。但是,如果您转到左侧(在开头添加页面),则会出现一些奇怪的行为,并且根本不起作用。

我在下面粘贴了一个带有计数器的简单示例。我不确定我是否做得对或者我的逻辑是否错误。谁能让我知道执行此操作的正确方法?

import 'package:flutter/material.dart';

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

class LimeApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Pageview Test',
      home: MainPage(),
    );
  }
}

int _lowerCount = -1;
int _upperCount = 1;

class MainPage extends StatelessWidget {
  final List<Widget> _pages = <Widget>[
    new Center(child: new Text("-1", style: new TextStyle(fontSize: 60.0))),
    new Center(child: new Text("0", style: new TextStyle(fontSize: 60.0))),
    new Center(child: new Text("1", style: new TextStyle(fontSize: 60.0)))
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        margin: EdgeInsets.symmetric(
          vertical: 50.0,
        ),
        child: PageView(
          onPageChanged: (pageId){
            if(pageId == _pages.length - 1){
              print("Last page, add page to end");
              _upperCount = _upperCount + 1;
              _pages.add(new Center(child: new Text(_upperCount.toString(), style: new TextStyle(fontSize: 60.0))));
            }
            if(pageId == 0){
              print("First page, add page to start");
              _lowerCount = _lowerCount - 1;
              _pages.insert(0, new Center(child: new Text(_lowerCount.toString(), style: new TextStyle(fontSize: 60.0))));
            }
          },
          controller: PageController(
            initialPage: 1,
          ),
          children: _pages,
        ),
      ),
    );
  }
}

我想我已经成功了。我没有使用onPageChange事件。相反,我聆听了控制器中的变化。


import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  static const Widget _home = HomePage();
  @override
  Widget build(BuildContext context) => MaterialApp(
        home: _home,
      );
}

class HomePage extends StatefulWidget {
  const HomePage();

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

class _HomePageState extends State<HomePage> {
  late PageController _controller;

  // This points always to the mid-element in _list
  late int _initialIndex;

  // This should work with 3, 7, 11, ... odd elements. Mind the pattern!!!
  List<int> _list = [-2, -1, 0, 1, 2];
  

  @override
  void initState() {
    super.initState();
    // Calculate mid.
    _initialIndex = (_list.length / 2).floor();
    
    _controller = PageController(initialPage: _initialIndex, viewportFraction: 0.8);

    // This is where we listen to changes.
    _controller.addListener(() {
      // Get index according to the direction
      // _controller.page! > _initialIndex => swiping to the right, going to the left / previous element
      // _controller.page! < _initialIndex => swiping to the left, going to the right / next element
      final index = _controller.page! > _initialIndex ? _controller.page!.floor() : _controller.page!.ceil();
      

      if (index == _initialIndex) return;
      if (index == _initialIndex - 1) {
        _prev();
      } else if (index == _initialIndex + 1) {
        _next();
      }

    });
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  // Update list and jump to the middle element
  void _next() {
    setState(() {
      _list
        ..removeAt(0)
        ..insert(_list.length, _list.last + 1);
      // Update current DateTime here
    });
    _controller.jumpToPage(_initialIndex);
  }

  // Update list and jump to the middle element
  void _prev() {
    setState(() {
      _list
        ..insert(0, _list.first - 1)
        ..removeLast();
      // Update current DateTime here
    });
    _controller.jumpToPage(_initialIndex);
  }

  @override
  Widget build(BuildContext context) => Scaffold(
    appBar: AppBar(
          actions: <Widget>[
            Padding(
              padding: const EdgeInsets.only(right: 20.0),
              child: IconButton(
                icon: const Icon(Icons.arrow_back),
                onPressed: () {
                  _prev();
                },
              ),
            ),
            Padding(
              padding: const EdgeInsets.only(right: 20.0),
              child: IconButton(
                icon: const Icon(Icons.arrow_forward),
                onPressed: () {
                  _next();
                },
              ),
            ),
          ],
        ),
    body: PageView.builder(
      controller: _controller,
      itemCount: _list.length,
      itemBuilder: (context, i) {
        // This is where you should put your widget that generates
        // the view of the month.
        // Calculate DateTime like so 'DateTime(initialDate.year, initialDate.month + _list[index], initialDate.day)'
        return Padding(
          padding: const EdgeInsets.all(32.0),
          child: Container(
            color: Colors.blueAccent[100],
            alignment: Alignment.center,
            child: Text(
              '${_list[i]}',
              style: const TextStyle(fontSize: 32),
            ),
          ),
        );
      }
    ),
  );
}




本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

滑动时向 PageView 添加新页面 的相关文章