【发布时间】:2020-10-20 01:22:07
【问题描述】:
你好,我有一个简单的应用程序,它从网络服务器获取图像,然后在网格视图构建器中显示它们
我正在尝试做的是上拉重建所有图像注意我已经实现了 RefreshIndicator() 及其 OnRefresh 功能在数据库发生更改时正常工作,它将新图像添加到视图中,
我还希望它重建所有图像,因为和我一起想象一下这种情况:
您打开了应用程序,未来的构建器获取了数据,现在它正在显示它们,但是当它显示它们时,您突然与互联网断开连接,这将给您留下空白空间(它应该是图像,但现在它们是空白的) 所以我想做的是在上拉时重建这些图像,这样如果用户发现任何丢失的图像,他就可以拉起来刷新页面并再次重建所有图像
这是我的代码,只是 RefreshCompanies() 需要修改
import 'dart:convert';
import 'package:app/exceptions/connection_error.dart';
import 'package:app/exceptions/empty_db.dart';
import 'package:app/reusable_widgets/interfaces/Companies/Companies_interface.dart';
import 'package:app/reusable_widgets/interfaces/LoadingIndicator.dart';
import 'package:app/reusable_widgets/interfaces/Main_Layout.dart';
import 'package:app/reusable_widgets/logic/Check_version.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:http/http.dart' as http;
import 'Categories.dart';
import 'package:app/reusable_widgets/globals.dart';
class Companies {
final int id;
final String name;
final String companyLogo;
Companies({this.id, this.name, this.companyLogo});
factory Companies.fromJson(Map<String, dynamic> json) {
return Companies(
id: json['id'],
name: json['name'],
companyLogo: json['company_logo'],
);
}
}
Future<List<Companies>> fetchCompanies() async {
final response = await http.get('$webSiteUrl/company/api/fetch');
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
return parseCompanies(response.body);
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load the companies');
}
}
List<Companies> parseCompanies(String responseBody) {
final parsed = json.decode(responseBody).cast<Map<String, dynamic>>();
return parsed.map<Companies>((json) => Companies.fromJson(json)).toList();
}
class CompaniesPage extends StatefulWidget{
@override
_CompaniesState createState() => _CompaniesState();
}
class _CompaniesState extends State<CompaniesPage> {
Future<List<Companies>> _companies;
var refreshKey = GlobalKey<RefreshIndicatorState>();
@override
void initState() {
super.initState();
checkVersion(context);
_companies = fetchCompanies();
}
Future<Null> refreshCompanies() async{
await DefaultCacheManager().emptyCache();
await Future.delayed(Duration(seconds: 2)).then((value) =>
setState(() {
_companies = fetchCompanies();
})
);
}
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: FutureBuilder<List<Companies>>(
future: _companies,
builder: (context, snapshot) {
if (snapshot.hasData) {
List<Companies> companies = snapshot.data;
if(companies.length >= 1){
return MainLayout(
RefreshIndicator(
onRefresh: refreshCompanies,
key: refreshKey,
child: GridView.count(
crossAxisCount: 2 ,
children: List.generate(companies.length, (index) {
return GestureDetector(
onTap: () => {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Categories(companies[index].id, companies[index].name)),
)},
child: CompaniesInterface(companies[index].id , companies[index].name , companies[index].companyLogo),
);
}),
),
),
);
}else{
return EmptyDataBase();
}
} else if (snapshot.hasError) {
return ConnectionError();
}
// By default, show a loading spinner.
return LoadingIndicator();
},
),
),
);
}
}
我的公司界面
class CompaniesInterface extends StatelessWidget{
final companyId;
final companyName;
final companyLogo;
CompaniesInterface(this.companyId , this.companyName ,this.companyLogo);
@override
Widget build(BuildContext context) {
return Align(
child : Container(
margin: EdgeInsets.all(20),
height: DeviceInformation(context).height * 0.7,
width: DeviceInformation(context).width * 0.9,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
shape: BoxShape.rectangle,
image: DecorationImage(
image: NetworkImage('$webSiteUrl$companyLogo'),
fit: BoxFit.fill,
),
),
),
);
}
}
从我尝试调用 EmptyCache() 的代码中可以看出,它没有重建网格视图
建议的解决方案:如果您可以找到以编程方式热重载应用程序的功能,那么热重载正在正确执行所需的操作,那么我认为这将解决问题
更新: 对于将来会带着同样问题来的人 恐怕我的问题没有直接的答案,所以我授予了我认为最好的答案
【问题讨论】:
-
为什么不用缓存网络图片呢?它可以让您灵活地为每个图像显示加载器,并在重新加载页面时节省一些带宽,因为它会缓存图像以供将来使用。此外,如果图像无法加载,它会给您一个错误,您可以使用它来相应地更新 UI。
-
我正在考虑使用它,但现在不行,我稍后会使用它