imr*_*fat 0 dart flutter flutter-http
我想无限滚动我的产品。我总共有 412 页。当我滚动到最后时,我想显示下一页的更多项目。这意味着无限滚动。这个怎么做?我已经实现了 ScrollController。
\n这是我的 Api:\n https://www.moharaj.com.bd/api/new/collection/products?page=1
\n这是我的模型类:
\n// To parse this JSON data, do\n//\n// final newCollectionProductModel = newCollectionProductModelFromJson(jsonString);\n\nimport \'dart:convert\';\n\nNewCollectionProductModel newCollectionProductModelFromJson(String str) =>\n NewCollectionProductModel.fromJson(json.decode(str));\n\nString newCollectionProductModelToJson(NewCollectionProductModel data) =>\n json.encode(data.toJson());\n\nclass NewCollectionProductModel {\n NewCollectionProductModel({\n required this.currentPage,\n required this.data,\n required this.firstPageUrl,\n required this.from,\n required this.lastPage,\n required this.lastPageUrl,\n required this.nextPageUrl,\n required this.path,\n required this.perPage,\n required this.prevPageUrl,\n required this.to,\n required this.total,\n });\n\n final int currentPage;\n final List<Datum> data;\n final String firstPageUrl;\n final int from;\n final int lastPage;\n final String lastPageUrl;\n final String nextPageUrl;\n final String path;\n final int perPage;\n final dynamic prevPageUrl;\n final int to;\n final int total;\n\n factory NewCollectionProductModel.fromJson(Map<String, dynamic> json) =>\n NewCollectionProductModel(\n currentPage: json["current_page"],\n data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),\n firstPageUrl: json["first_page_url"],\n from: json["from"],\n lastPage: json["last_page"],\n lastPageUrl: json["last_page_url"],\n nextPageUrl: json["next_page_url"],\n path: json["path"],\n perPage: json["per_page"],\n prevPageUrl: json["prev_page_url"],\n to: json["to"],\n total: json["total"],\n );\n\n Map<String, dynamic> toJson() => {\n "current_page": currentPage,\n "data": List<dynamic>.from(data.map((x) => x.toJson())),\n "first_page_url": firstPageUrl,\n "from": from,\n "last_page": lastPage,\n "last_page_url": lastPageUrl,\n "next_page_url": nextPageUrl,\n "path": path,\n "per_page": perPage,\n "prev_page_url": prevPageUrl,\n "to": to,\n "total": total,\n };\n}\n\nclass Datum {\n Datum({\n required this.id,\n required this.name,\n required this.price,\n required this.salePrice,\n required this.slug,\n required this.discount,\n required this.thumnail,\n required this.productImage,\n });\n\n final int id;\n final String name;\n final String price;\n final String salePrice;\n final String slug;\n final int discount;\n final String thumnail;\n final List<ProductImage> productImage;\n\n factory Datum.fromJson(Map<String, dynamic> json) => Datum(\n id: json["id"],\n name: json["name"],\n price: json["price"],\n salePrice: json["sale_price"],\n slug: json["slug"],\n discount: json["discount"],\n thumnail: json["thumnail"],\n productImage: List<ProductImage>.from(\n json["product_image"].map((x) => ProductImage.fromJson(x))),\n );\n\n Map<String, dynamic> toJson() => {\n "id": id,\n "name": name,\n "price": price,\n "sale_price": salePrice,\n "slug": slug,\n "discount": discount,\n "thumnail": thumnail,\n "product_image":\n List<dynamic>.from(productImage.map((x) => x.toJson())),\n };\n}\n\nclass ProductImage {\n ProductImage({\n required this.id,\n required this.productId,\n required this.productImage,\n required this.createdAt,\n required this.prefixUrl,\n required this.updatedAt,\n });\n\n final int id;\n final int productId;\n final String productImage;\n final DateTime createdAt;\n final String prefixUrl;\n final DateTime updatedAt;\n\n factory ProductImage.fromJson(Map<String, dynamic> json) => ProductImage(\n id: json["id"],\n productId: json["product_id"],\n productImage: json["product_image"],\n createdAt: DateTime.parse(json["created_at"]),\n prefixUrl: json["prefix_url"],\n updatedAt: DateTime.parse(json["updated_at"]),\n );\n\n Map<String, dynamic> toJson() => {\n "id": id,\n "product_id": productId,\n "product_image": productImage,\n "created_at": createdAt.toIso8601String(),\n "prefix_url": prefixUrl,\n "updated_at": updatedAt.toIso8601String(),\n };\n}\nRun Code Online (Sandbox Code Playgroud)\n这是我的服务类代码:
\nimport \'dart:convert\';\nimport \'package:infinite_pagination/NewArrival.dart\';\nimport \'package:infinite_pagination/NewCollectionProductModel.dart\';\n\nimport \'package:http/http.dart\' as http;\n\n/**\n * This is a Service Class. \n * This Service Class is used for New COllection Product.\n * \n */\n\nclass NewCollectionProductService {\n static var product;\n static Future<NewCollectionProductModel>\n getNewCollectionProductService() async {\n try {\n final response = await http.get(Uri.parse(\n "https://www.moharaj.com.bd/api/new/collection/products?page=$pageNumber"));\n //print(response);\n if (response.statusCode == 200 || response.statusCode == 201) {\n final decode = jsonDecode(response.body);\n product = NewCollectionProductModel.fromJson(decode);\n return product;\n } else {\n return product;\n }\n } catch (error) {\n throw Exception();\n }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n这是产品类别:
\nimport \'package:flutter/material.dart\';\nimport \'package:cached_network_image/cached_network_image.dart\';\n\nvar size = 180.0;\nvar iconSize = 10.0;\n\nWidget Products(String ImgLocation, name, price, discountPrice, discountPercent,\n reviews, BuildContext context) {\n return Container(\n height: 300,\n child: Card(\n child: Padding(\n padding: EdgeInsets.all(5),\n child: Column(\n crossAxisAlignment: CrossAxisAlignment.start,\n mainAxisAlignment: MainAxisAlignment.start,\n children: [\n Expanded(\n child: ClipRRect(\n borderRadius: BorderRadius.circular(10),\n child: Image.network(\n \'$ImgLocation\',\n fit: BoxFit.cover,\n loadingBuilder: (context, child, loadingProgress) {\n return loadingProgress == null\n ? child\n : Center(\n child: LinearProgressIndicator(\n value: loadingProgress.expectedTotalBytes != null\n ? loadingProgress.cumulativeBytesLoaded /\n loadingProgress.expectedTotalBytes!\n : null,\n ));\n // : LinearProgressIndicator();\n },\n width: MediaQuery.of(context).size.width,\n height: size,\n ),\n ),\n ),\n Text(\n \'$name\',\n textAlign: TextAlign.start,\n ),\n Text(\n \'\xe0\xa7\xb3 $price\',\n style: TextStyle(\n fontSize: 15,\n color: Colors.red,\n fontWeight: FontWeight.bold),\n textAlign: TextAlign.left,\n ),\n Text.rich(\n TextSpan(\n children: <TextSpan>[\n // ignore: unnecessary_new\n TextSpan(\n text: \'\xe0\xa7\xb3 $discountPercent\',\n style: const TextStyle(\n color: Colors.grey,\n decoration: TextDecoration.lineThrough,\n ),\n ),\n TextSpan(\n text: \' -$discountPrice%\',\n ),\n ],\n ),\n ),\n Row(\n children: [\n Icon(\n Icons.star,\n color: Color(0xFFFfebf50),\n size: iconSize,\n ),\n Icon(\n Icons.star,\n color: Color(0xFFFfebf50),\n size: iconSize,\n ),\n Icon(\n Icons.star,\n color: Color(0xFFFfebf50),\n size: iconSize,\n ),\n Icon(\n Icons.star,\n color: Color(0xFFFfebf50),\n size: iconSize,\n ),\n Icon(\n Icons.star,\n color: Color(0xFFFfee9c3),\n size: iconSize,\n ),\n SizedBox(\n width: 5,\n ),\n Text(\n \'($reviews)\',\n style: TextStyle(fontSize: iconSize),\n )\n ],\n )\n ],\n )),\n ),\n );\n}\nRun Code Online (Sandbox Code Playgroud)\n这是我的主页:
\nimport \'package:flutter/material.dart\';\nimport \'package:get/get.dart\';\nimport \'package:infinite_pagination/NewArrivalController.dart\';\nimport \'package:infinite_pagination/NewCollectionProductModel.dart\';\nimport \'package:infinite_pagination/NewCollectionProductService.dart\';\nimport \'package:infinite_pagination/Products.dart\';\n\n//------------------------------------------------------------\n// this widget is for Upcoming categories\n//------------------------------------------------------------\n\nclass NewArrival extends StatefulWidget {\n @override\n State<NewArrival> createState() => _NewArrivalState();\n}\n\nvar pageNumber = 1;\n\nclass _NewArrivalState extends State<NewArrival> {\n NewArrivalController newArrivalController = Get.put(NewArrivalController());\n late Future<NewCollectionProductModel> getData;\n\n ScrollController scrollController = ScrollController();\n\n @override\n void initState() {\n getData = NewCollectionProductService.getNewCollectionProductService();\n // TODO: implement initState\n super.initState();\n scrollController.addListener(() {\n print(scrollController.position.pixels);\n if (scrollController.position.pixels ==\n scrollController.position.maxScrollExtent) {\n pageNumber++;\n\n print(pageNumber);\n }\n });\n }\n\n @override\n void dispose() {\n // TODO: implement dispose\n super.dispose();\n scrollController.dispose();\n }\n\n @override\n Widget build(BuildContext context) {\n return SafeArea(\n child: Scaffold(\n body: SingleChildScrollView(\n child: Column(\n crossAxisAlignment: CrossAxisAlignment.start,\n children: [\n Row(\n mainAxisAlignment: MainAxisAlignment.spaceBetween,\n children: [\n const Padding(\n padding: EdgeInsets.only(left: 10),\n child: Text(\'New Arrival\',\n style: TextStyle(\n fontSize: 17,\n fontWeight: FontWeight.bold,\n )),\n ),\n Padding(\n padding: const EdgeInsets.all(10.0),\n child: MaterialButton(\n color: Colors.red,\n child: Text("View All"),\n onPressed: () {}),\n )\n ],\n ),\n Container(\n // height: 200,\n child: collectionOfData())\n ],\n ),\n ),\n ),\n );\n }\n\n collectionOfData() {\n return FutureBuilder<NewCollectionProductModel>(\n future: getData,\n builder: (context, snapshot) {\n if (snapshot.hasData) {\n return ListView.builder(\n controller: scrollController,\n physics: NeverScrollableScrollPhysics(),\n // scrollDirection: Axis.horizontal,\n shrinkWrap: true,\n itemCount: snapshot.data!.data.length,\n // gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(\n // crossAxisCount: 2),\n itemBuilder: (context, int index) {\n var product = snapshot.data!.data[index];\n //slug = product.slug;\n String image = product.productImage[0].prefixUrl.toString() +\n product.productImage[0].productImage.toString();\n return GestureDetector(\n onTap: () {},\n child: Container(\n height: 300,\n width: 200,\n child: Products(\n image,\n product.name,\n product.price,\n product.discount,\n product.salePrice,\n product.id,\n context,\n ),\n ),\n );\n });\n } else {\n return Center(child: CircularProgressIndicator());\n }\n });\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n
您可以通过两种方式进行管理。
您还可以查看以下链接。
没有包的简单示例:
首先声明以下代码。
ScrollController _scrollController = new ScrollController();
var pageNumber = 1;// update in API CALL
total_page = 0; // update in API CALL
current_page = 0; // update in API CALL
List<ModelClass> arrList = [];
Run Code Online (Sandbox Code Playgroud)
添加以下代码 init 方法
_scrollController.addListener(() async {
if (_scrollController.position.pixels ==
_scrollController.position.maxScrollExtent) {
if (currentPage != total) { // on bottom scroll API Call until last page
currentPage += 1;
apiCall(page: currentPage);
}
}
});
Run Code Online (Sandbox Code Playgroud)
如果未找到数据并添加拉动以刷新小部件。
Widget noDataFound() {
return RefreshIndicator(
onRefresh: apiCall(),
child: Center(
child: Text('No Data Found!'),
),
);
}
Run Code Online (Sandbox Code Playgroud)
在构建小部件中
arrList.isNotEmpty ? ListView.separated(
padding: const EdgeInsets.all(16.0),
separatorBuilder: (c, index) {
return SizedBox(
height: 20.0,
);
},
physics: AlwaysScrollableScrollPhysics(),
controller: _scrollController,
itemCount: arrList.size + 1,
itemBuilder: (_, index) {
if (index == arrList.length) { // Always one widget 'Loading...' added end of list it will Hide/Show based on condtion.
return Visibility(
visible:
current_page != totalPage ? false:true,
child: Center(
child: Text('Loading...',),
);
} else {
return ... listViewItemWidget;
}
}) : noDataFound()
Run Code Online (Sandbox Code Playgroud)
API调用功能
apiCall(int page = 0){
// update all pagenation variables After API get & map data sucessfully
currentPage , Total page , list value
// Add one condition to store data
if (page == 0) { // If Pull to refresh.
arrList.clear();
arrList = [mapData list from API]; // New data load.
} else {
arrList.add([mapData list from API]); // Append new data in old list
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9451 次 |
| 最近记录: |