Использование SingleChildScrollView внутри PageView - PullRequest
0 голосов
/ 04 апреля 2020

В моем приложении у меня есть PageView, где каждая страница содержит страницу книги. Естественно, все страницы больше, чем область просмотра, поэтому я использовал SingleChildScrollView внутри каждой страницы, чтобы прокручивать содержимое страницы. Проблема в том, что я не могу перейти к следующей странице PageView, когда попадаю в нижнюю часть страницы (он пытается продолжить прокрутку самой страницы, а не просмотра страницы). Есть ли способ заставить мое приложение прокручивать страницу при достижении вертикальных границ страницы? (и верхняя, и нижняя границы.)

Вот мой код

import 'package:flutter/material.dart';
import 'package:flutter_html/flutter_html.dart';
import 'package:penguinovel/core/source/chapter.dart';

class ChapterPage extends StatelessWidget {

  final List<Chapter> chapters;
  final int initialIndex;

  ChapterPage(this.chapters, this.initialIndex);

  @override
  Widget build(BuildContext context){

    return Scaffold(
        appBar: AppBar(title: Text(this.chapters[this.initialIndex].name, style: TextStyle(color: Colors.white),), backgroundColor: Colors.black,),
        body: PageView.builder(
          controller: PageController(initialPage: this.initialIndex),
          scrollDirection: Axis.vertical,
          itemCount: this.chapters.length,
          itemBuilder: (BuildContext context, int index) => buildChapter(this.chapters[index]),
        )
      );

  }

  Widget buildChapter(Chapter chapter) {
    return FutureBuilder<String>(future: chapter.getContent(), builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
      if(snapshot.hasData){
          return SingleChildScrollView(child: Html(data: snapshot.data));
      } else if (snapshot.hasError) {
          return Center(child: Text(snapshot.error.toString()));
      } else {
        return Center(child: CircularProgressIndicator());
      }
    });
  }
}

Заранее спасибо:)

Ответы [ 2 ]

0 голосов
/ 12 апреля 2020

После попытки flutter_easyrefre sh и другой библиотеки под названием pull_to_refre sh (я думаю). Я сталкивался со многими ошибками, которые пытался исправить. В ходе этого процесса я узнал о вещи, называемой BouncingScrollPhysics.

. Это дает прокручиваемому объекту некоторое количество содержимого за пределами границ, которое возвращается в исходное состояние, когда пользователь перестает держать палец.

Использование этого Я создал ScrollController и слушатель, который ждет, когда прокрутка выйдет за пределы и после некоторых настроек ... это сработало:)

Вот фрагмент кода

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_html/flutter_html.dart';
import 'package:penguinovel/core/source/chapter.dart';



class ChapterPage extends StatefulWidget {

  final List<Chapter> chapters;
  final int initialIndex;

  ChapterPage(this.chapters, this.initialIndex);

  _ChapterPageState createState() => _ChapterPageState(this.initialIndex);
}


class _ChapterPageState extends State<ChapterPage> {

  int _index;
  PageController _pageController;
  ScrollController _scrollController;

  _ChapterPageState(this._index);

  @override
  void initState(){
    super.initState();
    _pageController = PageController(initialPage: widget.initialIndex);
    _scrollController = ScrollController();
    _scrollController.addListener(this.swapPageListener);
  }

  @override
  Widget build(BuildContext context){

    return Scaffold(
      appBar: AppBar(title: Text(widget.chapters[this._index].name, style: TextStyle(color: Colors.white),), backgroundColor: Colors.black,),
      body: PageView.builder(
        controller: _pageController,
        scrollDirection: Axis.vertical,
        itemBuilder: (BuildContext context, int index) {
        return FutureBuilder<String>(future: widget.chapters[index].getContent(), builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
          if(snapshot.hasData){
              return this.buildSingleChapterPage(snapshot.data);
          } else if (snapshot.hasError) {
              return Center(child: Text(snapshot.error.toString()));
          } else {
            return Center(child: CircularProgressIndicator());
          }
        });
      }));

  }

  Widget buildSingleChapterPage(String data){
    return SingleChildScrollView(
        child: Html(data: data),
        physics: BouncingScrollPhysics(),
        controller: _scrollController
      );
  }

  void swapPageListener() {
    if (_scrollController.offset > _scrollController.position.maxScrollExtent + 170) {
      if (this._index < widget.chapters.length - 1 ){
        setState(() {
          this._index ++;
          _pageController.jumpToPage(this._index);
        });
      }
   }

   if (_scrollController.offset < _scrollController.position.minScrollExtent - 170) {
      if (this._index > 0){
        setState(() {
          this._index --;
          _pageController.jumpToPage(this._index);
        });
      }
   }
  }
}

Спасибо за ваши предложения, и я надеюсь, что это поможет и другим людям.

0 голосов
/ 06 апреля 2020

Попробуйте использовать flutter_easyrefre sh, реализует переходную страницу просмотра страницы контроллером в onRefre sh (предыдущая страница) и onLoad (следующая страница).

...