Pagination 如何在flatter-bloc模式中实现分页

Pagination 如何在flatter-bloc模式中实现分页,pagination,flutter,bloc,built-value,Pagination,Flutter,Bloc,Built Value,我正在尝试使用bloc模式在Flatter中实现分页。我想要的是,当列表视图到达末尾时,它会使用新内容更新当前列表视图,但它正在使用新内容创建新列表视图 内置的\u valueModel.dart abstract class Verces implements Built<Verces, VercesBuilder> { static Serializer<Verces> get serializer => _$vercesSerializer; Bu

我正在尝试使用bloc模式在Flatter中实现分页。我想要的是,当列表视图到达末尾时,它会使用新内容更新当前列表视图,但它正在使用新内容创建新列表视图

内置的\u valueModel.dart


abstract class Verces implements Built<Verces, VercesBuilder> {
  static Serializer<Verces> get serializer => _$vercesSerializer;

  BuiltList<Madni> get verses;

  Meta get meta;

  Verces._();

  factory Verces([updates(VercesBuilder b)]) = _$Verces;
}

abstract class Madni implements Built<Madni, MadniBuilder> {
  static Serializer<Madni> get serializer => _$madniSerializer;

  int get id; //1,
  int get verse_number; //: 1,
  int get chapter_id; //: 1,
  String get verse_key; // "1:1",
  String get text_madani; //: "بِسْمِ اللَّهِ الرَّحْمَٰنِ الرَّحِيمِ",
  String get text_indopak; //: "بِسۡمِ اللهِ الرَّحۡمٰنِ الرَّحِيۡمِ",
  String get text_simple; //: "بسم الله الرحمن الرحيم",
  int get juz_number; //: 1,
  int get hizb_number; //: 1,
  int get rub_number; // 1,
//  "sajdah": null,
//  "sajdah_number": null,
  int get page_number; // 1,

  BuiltList<Translations> get translations; //": [],

  Madni._();

  factory Madni([updates(MadniBuilder b)]) = _$Madni;
}

abstract class Translations
    implements Built<Translations, TranslationsBuilder> {
  static Serializer<Translations> get serializer => _$translationsSerializer;

  int get id; //: 104845,
  String get language_name; //: "english",
  String get text; //: "Alif Lam Mim.",
  String get resource_name; // "Shakir",
  int get resource_id; //: 21

  Translations._();

  factory Translations([updates(TranslationsBuilder b)]) = _$Translations;
}

abstract class Meta implements Built<Meta, MetaBuilder> {
  static Serializer<Meta> get serializer => _$metaSerializer;

  @nullable
  int get current_page; //": 1,
  @nullable
  int get next_page; //": 2,
  @nullable
  int get prev_page; //": null,
  @nullable
  int get total_pages; //": 6,
  @nullable
  int get total_count; //": 286

  Meta._();

  factory Meta([updates(MetaBuilder b)]) = _$Meta;
}

List<Madni> getmadni(String jsonStr) {
  final res = json.jsonDecode(jsonStr);
  Verces verces = standardSerializers.deserializeWith(Verces.serializer, res);
  //print(verces);
  return verces.verses.map((Madni mad) => mad).toList();
}

Meta getmeta(String jsonStr) {
  final res = json.jsonDecode(jsonStr);
  Verces verces = standardSerializers.deserializeWith(Verces.serializer, res);
  return verces.meta;
}

抽象类Verces实现构建{
静态序列化程序get Serializer=>\u$vercesSerializer;
建造者得到诗句;
元得到元;
韦尔斯;
工厂版本([更新(版本生成器b)])=\u$Verces;
}
抽象类Madni实现{
静态序列化程序get Serializer=>u$madniSerializer;
int get id;//1,
int get verse_number;//:1,
int get章_id;/:1,
字符串获取韵文_key;//“1:1”,
字符串get text_madani;/:“ب,
字符串get text_indopak;/:“㶖,
字符串获取文本非常简单;/:“字符串获取文本”,
int get juz_number;/:1,
int获取hizb_编号;/:1,
int get rub_number;//1,
//“sajdah”:空,
//“sajdah_编号”:空,
int get page_number;//1,
BuiltList获取翻译;/“:[],
马德尼;
工厂Madni([更新(MadniBuilder b)])=\uu$Madni;
}
抽象类翻译
制造工具{
静态序列化程序get Serializer=>\u$TranslationSerializer;
int get id;/:104845,
字符串get language_name;/:“english”,
字符串get text;/:“Alif Lam Mim.”,
字符串get resource_name;//“Shakir”,
int get resource_id;//:21
翻译;
工厂翻译([更新(TranslationBuilder b)])=翻译;
}
构建抽象类元实现{
静态序列化程序get Serializer=>$metaSerializer;
@可空
int获取当前页面;/“:1,
@可空
int get next_page;/“:2,
@可空
int get prev_page;/“:null,
@可空
int获取总页数;/“:6,
@可空
int get total_count;/“:286
元;
工厂元([更新(元生成器b)])=\u$Meta;
}
列表getmadni(字符串jsonStr){
final res=json.jsonDecode(jsonStr);
Verces Verces=standardSerializers.deserializeWith(Verces.serializer,res);
//印刷品(verces);
return verces.verses.map((Madni-mad)=>mad.toList();
}
Meta getmeta(字符串jsonStr){
final res=json.jsonDecode(jsonStr);
Verces Verces=standardSerializers.deserializeWith(Verces.serializer,res);
返回verces.meta;
}
团镖

import 'dart:async';
import 'package:quran_app/src/chapters/model/model.dart';
import 'dart:collection';
import 'package:http/http.dart' as http;

class Verses_bloc {
  var _chap = <Madni>[];
  var _meta = Meta();

  HashMap<int, List<Madni>> _cashedChapters;

  // Verses bloc start
  final Verses_blocController = StreamController<List<Madni>>();

  StreamSink<List<Madni>> get _incontroller => Verses_blocController.sink;

  Stream<List<Madni>> get output_verses => Verses_blocController.stream;

  // Verses bloc End

  // Pages bloc start
  final pages_blocController = StreamController<Meta>();

  StreamSink<Meta> get _inpageController => pages_blocController.sink;

  Stream<Meta> get output_pages => pages_blocController.stream;

  // Pages bloc start

  int chap;
  int page;

  Verses_bloc(this.chap, this.page) {
    _cashedChapters = HashMap<int, List<Madni>>();

    update(this.chap, this.page);
  }

  // Future which will return value to UI when the data is fetched
  Future<void> update(int chap, int page) async {
     _chap = await getVerses(chap, page);

    _meta = await getPages();

    _incontroller.add(_chap);
    _inpageController.add(_meta);
  }

  // Get Verses Method Which will return pages with limit of 50 pages

  Future<List<Madni>> getVerses(int chap, int page) async {
    if (!_cashedChapters.containsKey(1)) {
      final storiesUrl =
          'http://staging.quran.com:3000/api/v3/chapters/${chap}/verses?recitation=1&translations=21&language=en&page=${page}&text_type=words';
      final storyRes = await http.get(Uri.parse(storiesUrl));

      if (storyRes.statusCode == 200) {
        _cashedChapters[1] = getmadni(storyRes.body);
      } else {
        throw Exception("Error");
      }
    }
    return _cashedChapters[1];
  }

  // Get Meta Quantities Method
  Future<Meta> getPages() async {
    final storiesUrl =
        'http://staging.quran.com:3000/api/v3/chapters/${chap}/verses?recitation=1&translations=21&language=en&page=2&limit=50&text_type=words';
    final storyRes = await http.get(Uri.parse(storiesUrl));

    if (storyRes.statusCode == 200) {
      return getmeta(storyRes.body);
    } else {
      throw Exception("Error");
    }
  }

  void dispose() {
    Verses_blocController.close();
  }
}

导入'dart:async';
导入“package:quran_app/src/chapters/model/model.dart”;
导入“dart:集合”;
将“package:http/http.dart”导入为http;
阶级诗集{
var _chap=[];
var_meta=meta();
HashMap _cashedChapters;
//诗集开始
最后一节\u blocController=StreamController();
StreamSink get _InControl=>vs_blocController.sink;
Stream get output_verses=>verses_blocController.Stream;
//诗集结束
//页面组开始
最终页面\u blocController=StreamController();
StreamSink get\u inpageController=>pages\u blocController.sink;
Stream get output_pages=>pages\u blocController.Stream;
//页面组开始
int chap;
整版;
诗句(this.chap,this.page){
_cashedChapters=HashMap();
更新(this.chap,this.page);
}
//Future,它将在获取数据时向UI返回值
未来更新(int chap,int page)异步{
_chap=等待获取版本(chap,第页);
_meta=等待getPages();
_InControl智能驭享者。添加(\u章);
_inpageController.add(_meta);
}
//Get Verses方法将返回限制为50页的页面
未来的getverse(int-chap,int-page)异步{
如果(!\u兑现章节。容器(1)){
最后的故事URL=
'http://staging.quran.com:3000/api/v3/chapters/${chap}/verses?背诵=1&translations=21&language=en&page=${page}&text_type=words';
final-storyRes=wait-http.get(Uri.parse(storiesUrl));
if(storyRes.statusCode==200){
_cashedChapters[1]=getmadni(storyRes.body);
}否则{
抛出异常(“错误”);
}
}
返回已兑现的章节[1];
}
//获取元量方法
将来的getPages()异步{
最后的故事URL=
'http://staging.quran.com:3000/api/v3/chapters/${chap}/verses?背诵=1,翻译=21,语言=en&page=2,限制=50,文本类型=words';
final-storyRes=wait-http.get(Uri.parse(storiesUrl));
if(storyRes.statusCode==200){
返回getmeta(storyRes.body);
}否则{
抛出异常(“错误”);
}
}
无效处置(){
关闭()节;
}
}
主飞镖

import 'package:flutter/material.dart';
import 'package:quran_app/src/chapters/model/bloc/Verses_bloc.dart';
import 'package:quran_app/src/chapters/model/model.dart';

class Surah extends StatefulWidget {
  final String name;
  final int id;
  final int verses_count;

  const Surah({Key key, this.name, this.id, this.verses_count})
      : super(key: key);

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

class _SurahState extends State<Surah> {
  var _bloc = Verses_bloc(0, 0);
  ScrollController _controller;
  int n = 1;

  _scrollListener() {
    if (_controller.offset >= _controller.position.maxScrollExtent &&
        !_controller.position.outOfRange) {
      setState(() {
        print("Reached end");

        // _bloc=Verses_bloc(widget.id,2);
        // This line is creating a new listview
        // instead of updating current listview

      });
    }
  }

  @override
  void initState() {
    _bloc = Verses_bloc(widget.id, n);
    _controller = ScrollController();
    _controller.addListener(_scrollListener);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.name),
      ),
      body: Container(
        child: StreamBuilder(
          stream: _bloc.output_verses,
          initialData: List<Madni>(),
          builder: (BuildContext context,
              AsyncSnapshot<List<Madni>> snapshot_Madni) {
            if (snapshot_Madni.connectionState == ConnectionState.waiting) {
              return Center(
                child: CircularProgressIndicator(),
              );
            } else if (snapshot_Madni.data.isEmpty) {
              return Center(
                child: Text("The End"),
              );
            } else {
              return ListView.builder(
                controller: _controller,
                padding: EdgeInsets.all(8.0),
                itemCount: n,
                addAutomaticKeepAlives: false,
                itemBuilder: (BuildContext context, index) {
                  return ListView(
                      physics: ClampingScrollPhysics(),
                      shrinkWrap: true,
                      children: snapshot_Madni.data.map(_buildList).toList());
                },
              );
            }
          },
        ),
      ),
    );
  }

  Widget _buildList(Madni e) {
    return ListView(
      children: e.translations
          .map<ListTile>((a) => ListTile(
                contentPadding: EdgeInsets.all(10),
                title: Text(
                  e.text_madani,
                  style: TextStyle(fontSize: 22.0),
                  textAlign: TextAlign.right,
                ),
                subtitle: Text(a.text),
              ))
          .toList(),
      physics: ClampingScrollPhysics(),
      shrinkWrap: true,
    );
  }

//  Get List Pages
  String getMeta() {
    StreamBuilder(
        stream: _bloc.output_pages,
        builder: (BuildContext context, AsyncSnapshot<Meta> snapshot) {
          return Center(
            child: Text('${snapshot.data.next_page}'),
          );
        });
  }


  @override
  void dispose() {
    super.dispose();
    _bloc.dispose();
    _controller.dispose();
  }
}
导入“包装:颤振/材料.省道”;
导入“package:quran_app/src/chapters/model/bloc/Verses_bloc.dart”;
导入“package:quran_app/src/chapters/model/model.dart”;
类Surah扩展了StatefulWidget{
最后的字符串名;
最终int id;
最后的整数对数;
const Surah({Key,this.name,this.id,this.verses_count})
:super(key:key);
@凌驾
_SurahState createState()=>\u SurahState();
}
类_SurahState扩展状态{
var _bloc=相对集团(0,0);
滚动控制器(u控制器),;
int n=1;
_scrollListener(){
如果(_controller.offset>=_controller.position.maxScrollExtent&&
!\u控制器。位置。超出范围){
设置状态(){
打印(“到达末端”);
//_bloc=Verses_bloc(widget.id,2);
//此行正在创建一个新的listview
//而不是更新当前的listview
});
}
}
@凌驾
void initState(){
_bloc=Verses_bloc(widget.id,n);
_控制器=滚动控制器();
_controller.addListener(_scrollListener);
super.initState();
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:文本(widget.name),
),
主体:容器(
孩子:StreamBuilder(
流:_bloc.output_verses,
initialData:List(),
建筑商:(建筑控制)