简体   繁体   English

如何在颤振块模式中实现分页

[英]How to implement pagination in flutter bloc pattern

I am trying to implement pagination in flutter with bloc pattern.What i want is when the list_view reached the end it update the current list_view with new content but what it is doing is creating a new list_view with new content我正在尝试使用 bloc 模式在颤振中实现分页。我想要的是当 list_view 到达末尾时,它会用新内容更新当前的 list_view,但它正在做的是用新内容创建一个新的 list_view

Built_valueModel.dart Built_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;
}

Bloc.dart Bloc.dart

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();
  }
}

Main_UI.dart Main_UI.dart

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();
  }
}

When the list_view reached its ends instead of updating current list_view it is creating a new list_view , which is obvious because it i am creating a new bloc with different parameters.当 list_view 到达终点而不是更新当前 list_view 时,它正在创建一个新的 list_view ,这很明显,因为我正在创建一个具有不同参数的新块。

I'm unable to run your minimal repro, but I've previously created a sample app on Flutter demonstrating pagination with BLoC pattern .我无法运行您的最小重现,但我之前在 Flutter上创建了一个示例应用程序,演示了使用 BLoC 模式进行分页 What I did here was display data gradually, loading more data when scrolled at the bottom of the list.我在这里做的是逐渐显示数据,在列表底部滚动时加载更多数据。 The BLoC pattern that I've followed was based from this guide .我遵循的 BLoC 模式基于本指南

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM