- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在我的flutter应用程序中,我正在使用具有清晰体系结构的mvp,当我的服务器命中api时,我的服务器返回5个项目,当我再次滚动它时,再次命中api并获得了下5个项目。而且我将这些项目保存在列表中,这样我就无法为已经获取的项目一次又一次地调用api,并且此列表已在listview.builder中使用。我使用了底部导航栏,当我从“产品项”选项卡移至任何其他选项卡,并且从那里来到产品项时,它再次从api获取产品,这不是我想要的。每当我返回时,我想在产品列表选项卡中显示该列表已获取的列表。
Video of my problem。
import 'dart:async';
import 'package:bakery_application/Bloc/TECartBloc.dart';
import 'package:bakery_application/Singleton/CartManager.dart';
import 'package:bakery_application/data/dataSource/product/remote/ProductRemoteDataSource.dart';
import 'package:bakery_application/data/model/responseDTO/ProductResponseDTO.dart';
import 'package:bakery_application/data/model/responseDTO/models/products.dart';
import 'package:bakery_application/data/model/responseDTO/models/productsList.dart';
import 'package:bakery_application/domain/repository/product/ProductRepo.dart';
import 'package:bakery_application/ui/productdetailscreeen/ProductDetailScreen.dart';
import 'package:bakery_application/ui/productscreen/IProductPresenter.dart';
import 'package:bakery_application/ui/productscreen/IProductView.dart';
import 'package:connectivity/connectivity.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:bakery_application/localmodels/ProductModel.dart';
import 'package:bakery_application/widgets/TEProductIncrementor.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';
import 'package:provider/provider.dart';
import 'ProductPresenter.dart';
class ProductScreen extends StatefulWidget {
Key key;
List<Products> myList = new List<Products>();
int _pageNumber = 1;
ProductScreen({
this.key,
}) : super(key: key);
@override
_ProductScreenState createState() => _ProductScreenState();
}
class _ProductScreenState extends State<ProductScreen> implements IProductView {
_ProductScreenState() {
productPresenter = ProductPresenter(
this,
ProductRepo(
ProductRemoteDataSource(),
),
);
}
bool circularindicator = false;
Color circularColor;
double circularOpacity;
IProductPresenter productPresenter;
AsyncSnapshot snapshotList;
var _connectionStatus = 'Unknown';
Connectivity connectivity;
StreamSubscription<ConnectivityResult> subscription;
ScrollController _scrollController = ScrollController();
bool cupertinoProgress;
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
backgroundColor: Colors.orange,
automaticallyImplyLeading: false,
title: Text(
'Product',
style: TextStyle(color: Colors.white),
),
),
body:
StreamBuilder(
stream: productPresenter.getProducts,
builder: (context, AsyncSnapshot<ProductsList> snapshot) {
if (snapshot.hasData) {
return productListView(widget.myList);
} else if (snapshot.hasError) {
return Text(snapshot.error.toString());
}
return Center(
child: Container(
child: CircularProgressIndicator(),
),
);
},
),
);
}
Future<Null> refreshList() async {
await Future.delayed(Duration(seconds: 2));
setState(() {});
return null;
}
Widget productListView(List snapshot) {
return RefreshIndicator(
onRefresh: refreshList,
child:
ListView.builder(
key: widget.key,
controller: _scrollController,
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemBuilder: (BuildContext context, int index) {
if(index+1 == widget.myList.length) {
CupertinoActivityIndicator();
}
var plist = widget.myList[index];
return GestureDetector(
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ProductDetailScreen(
product: plist,
),
),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
width: 120,
height: 130,
child: Image(
image: NetworkImage(plist.image),
),
),
Container(
child: Flexible(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text(
plist.name,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
Text(
plist.description,
softWrap: true,
textAlign: TextAlign.left,
),
SizedBox(
height: 7,
),
Row(
children: <Widget>[
Text(plist.price.toString(),
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
)),
Spacer(),
Text(plist.brand),
],
),
TEProductIncrementor(
product: plist,
),
//TODO reverse it alse
],
),
),
),
),
],
),
Row(
children: <Widget>[
Expanded(
child: Divider(
color: Colors.grey.shade300,
),
),
],
)
],
),
),
);
},
itemCount: widget.myList.length,
),
);
}
productlist(BuildContext context, int index
}
@override
hideProgress(ProductsList response) {
setState(() {
// Here you can write your code for open new view
cupertinoProgress=false;
});
for (var c in response.products) {
widget.myList.add(c);
}
}
@override
showError(String error) {
// TODO: implement showError
return null;
}
@override
showProgress() {
print('Successful');
setState(() {
cupertinoProgress=true;
});
}
@override
void initState() {
super.initState();
connectivity = new Connectivity();
print('Init state called');
print('Init state called');
print('Init state called');
subscription =
connectivity.onConnectivityChanged.listen((ConnectivityResult result) {
_connectionStatus = result.toString();
print(_connectionStatus);
if (result == ConnectivityResult.wifi ||
result == ConnectivityResult.mobile) {
widget.myList.isEmpty
? productPresenter.fetchProducts(widget._pageNumber.toString())
:
widget._pageNumber = widget._pageNumber + 1;
productPresenter.fetchProducts(widget._pageNumber.toString(),);
_scrollController.addListener(() {
if (_scrollController.position.pixels ==
_scrollController.position.maxScrollExtent) {
widget._pageNumber = widget._pageNumber + 1;
print(widget._pageNumber);
productPresenter.fetchProducts(widget._pageNumber.toString(),);
}
});
} else {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Center(
child: Container(
child: Icon(
Icons.add_alert,
color: Colors.orange,
size: 20,
),
),
),
content: Text('Check your internet'),
actions: <Widget>[
new FlatButton(
child: new Text('Ok'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
});
}
@override
void dispose() {
subscription.cancel();
super.dispose();
}
getMoreData() async {
}
}
最佳答案
您面临的主要问题是,每当用户滚动您所在的标签页并返回该标签页时,该应用程序都会重新获取数据。
您可以使用IndexedStack
使数据仅加载一次,因为您可以通过这种方式编辑代码。
class BaseScreenState extends State<BaseScreen> {
List<Widget> _pages = [Page1(), Page2(), Page3()];
@override
Widget build(BuildContext context) {
return Scaffold(
body: IndexedStack(
index: currentIndex,
children: _pages,
),
);
}
}
关于list - 如何将我的数据保存在列表中,以便在Flutter应用程序的整个生命周期中都可以使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59134404/
如标题所示,ans_list是一个答案列表,ans_index是一个数字(答案在词汇表中的索引,但与atm无关) 这里生成的 tree.anslist 是什么? (例如,仅针对第一个),忽略迭代。 f
我目前将用户的输入存储在逗号分隔的列表中,如下所示: Userid | Options 1 | 1,2,5 用户在一个数组形式中勾选一组选项,然后用逗号连接起来 1,2,5 然后 MySQ
我目前将用户的输入存储在逗号分隔的列表中,如下所示: Userid | Options 1 | 1,2,5 用户在一个数组形式中勾选一组选项,然后用逗号连接起来 1,2,5 然后 MySQ
我想知道如何完全展平列表和包含它们的东西。除其他外,我想出了一个解决方案,它可以将具有多个元素的东西滑倒并将它们放回原处,或者在滑倒后将具有一个元素的东西拿走。 这与 How do I “flatte
我想知道如何完全展平列表和包含它们的东西。除其他外,我想出了一个解决方案,它可以将具有多个元素的东西滑倒并将它们放回原处,或者在滑倒后将带有一个元素的东西拿走。 这与 How do I “flatte
这个问题已经有答案了: Convert nested list to 2d array (3 个回答) 已关闭 7 年前。 java中有没有快捷方式可以转换 List> 到 String[][] ?
我在排序时遇到问题 List> 。我创建了一个自定义比较器,在其中编写了对数据进行排序的代码。 public class CustomComparator implements Comparator
这个问题已经有答案了: 已关闭10 年前。 Possible Duplicate: Java Generics: Cannot cast List to List? 我只是想知道为什么下面的java代
试图想出一个 LINQy 方法来做到这一点,但我什么也没想到。 我有一个对象列表<>,其中包含一个属性,该属性是逗号分隔的字母代码列表: lst[0].codes = "AA,BB,DD" lst[1
假设我有这些任务: points = [] point = (1, 2) 我怎么会这样做: points += point 它工作得很好,并且给了我点 = [1, 2]。但是,如果我这样做: poin
如何在 scala 中将 List[Task[List[Header]]] 类型转换为 Task[List[Header]]。 我有一个方法返回 Task[List[Header]] 并多次调用 do
如何在 Java 中查找二维列表的元素? 我有一个参数为 List> 的函数我想知道如何找到这个列表的行和列。 最佳答案 如果你喜欢 List> obj 然后你就可以像这样访问 obj.get(cur
分配 List到 List工作正常。 分配 List>到 List>不编译。 代码 public class Main { public static void main(String[] a
我正在用 Java 编写一个方法,该方法必须接收并迭代 Serializable 的 List。 有什么区别: public void myMethod(List list) { } 和 public
我看到很多人想用 mvvm 更新网格/列表/树的一部分,但他们不想刷新整个列表。 对于所有遇到此问题的人,我做了以下示例。 希望这对你有用。 最佳答案 这是一个简单的例子。整个代码中最重要的是: Bi
我正在为现有的 C++ 库编写包装器,该库使用列表,其中 T 是自定义结构。我被建议使用 vector 而不是列表,但我试图避免修改库。 为了更好地理解这个场景,我做了一个简单的应用程序,使用一个列表
List list List list 这两种声明有什么区别吗? 谢谢, 最佳答案 是的。 List可以包含所有派生自 Base 的不同事物的混合物. List包含同质项(从某种意义上说,它们必须全部
有人可以尽可能详细地解释以下类型之间的区别吗? List List List 让我更具体一点。我什么时候想使用 // 1 public void CanYouGiveMeAnAnswer(List l
我有一个元组列表,每个元组都是一对列表。所以我的数据看起来像: mylist = [(['foo', 'bar'], ['bar', 'bar']),(['bar', 'bar'],['bar', '
也许是一个时髦的标题,但我遇到了以下问题: 给定一个类型为 (a * b) list 的列表,我想创建一个类型为 (a * b list) list 的新列表。一个例子: 给定列表 let testL
我是一名优秀的程序员,十分优秀!