我幾乎嘗試了一切。我的功能異步,我的快照異步。我正在使用未來的建設者,我的輪播滑塊作業正常。我不需要為輪播滑塊熱重新加載或重繪 。但是對于我的串列視圖構建器,我每次都需要重繪 以獲取資料。我嘗試了 if 陳述句的連接狀態狀態,但連接狀態很快完成(在資料完全加載之前)。所以我的圖片和資料不會在沒有重繪 或熱多載的情況下出現。
import 'package:cached_network_image/cached_network_image.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:video_games/model.dart';
import 'package:flutter/material.dart';
import 'package:video_games/send_models.dart';
import 'package:video_games/views/details_view.dart';
import 'package:get/get.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
class HomePage extends StatefulWidget {
HomePage({
Key? key,
}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Future<Autogenerated> apiCall() async {
final response = await http.get(Uri.parse(
'https://api.rawg.io/api/games?key=5ac29048d12d45d0949c77038115cb56&page=1'));
return Autogenerated.fromJson(jsonDecode(response.body));
}
int slideractiveindex = 0;
var urlImages = [];
var uniqueImages = [];
var growableList = [];
var listId = [];
@override
Widget build(BuildContext context) {
clearCache();
return SingleChildScrollView(
child: Column(
children: [
FutureBuilder<Autogenerated>(
future: apiCall(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
List<Results>? data = snapshot.data!.results;
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CarouselSlider.builder(
itemCount: 20,
itemBuilder: (context, index, realIndex) {
urlImages.add(data![index].backgroundImage);
uniqueImages = urlImages.toSet().toList();
final urlImage = uniqueImages[index];
return buildImage(urlImage, index);
},
options: CarouselOptions(
autoPlay: true,
enlargeCenterPage: true,
onPageChanged: (index, reason) {}),
),
const SizedBox(height: 32),
],
);
},
),
FutureBuilder<Autogenerated>(
future: apiCall(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
print(snapshot.connectionState);
print(urlImages.length);
List<Results>? data = snapshot.data!.results;
return ListView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (BuildContext context, index) {
growableList.add(data![index].name);
listId.assign(data[index].id);
// String? id = data[index].id.toString();
// urlImages.add(data[index].backgroundImage);
uniqueImages = urlImages.toSet().toList();
final urlImage = uniqueImages[index 1];
return Padding(
padding: const EdgeInsets.all(10.0),
child: ListTile(
tileColor: Colors.black12,
leading: InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailsPage(
id: '${data[index].id}',
),
));
},
child: buildImage2(urlImage, index)),
title: Column(
children: [
Text(
'${data[index].name}',
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Rating : ${data[index].rating}'),
SizedBox(
width: 20,
),
Text('Release : ${data[index].released}'),
],
)
],
),
),
);
},
itemCount: 19,
);
} else {
return CircularProgressIndicator();
}
},
),
],
),
);
}
Widget buildImage(String? urlImage, int index) {
return Container(
margin: EdgeInsets.symmetric(horizontal: 12),
color: Colors.grey,
child: CachedNetworkImage(
imageUrl: urlImage!,
fit: BoxFit.cover,
key: UniqueKey(),
errorWidget: (context, url, error) => Icon(Icons.error),
placeholder: (context, url) => Container(
child: Center(
child: CircularProgressIndicator(),
),
),
));
}
Widget buildImage2(String? urlImage, int index) {
return Container(
height: 100,
width: 100,
child: CachedNetworkImage(
imageUrl: urlImage!,
key: UniqueKey(),
fit: BoxFit.cover,
errorWidget: (context, url, error) => Icon(Icons.error),
placeholder: (context, url) => Container(
child: Center(
child: CircularProgressIndicator(),
),
),
));
}
void clearCache() {
DefaultCacheManager().emptyCache();
imageCache!.clear();
imageCache!.clearLiveImages();
setState(() {});
}
}
這是我的錯誤部分
════════ Exception caught by widgets library ═══════════════════════════════════
RangeError (index): Invalid value: Valid value range is empty: 17
════════════════════════════════════════════════════════════════════════════════
════════ Exception caught by widgets library ═══════════════════════════════════
RangeError (index): Invalid value: Valid value range is empty: 18
════════════════════════════════════════════════════════════════════════════════

uj5u.com熱心網友回復:
FutureBuilder洗掉樣板代碼。看
假設您想在頁面啟動時從后端獲取一些資料并顯示一個加載器,直到資料到來。
ListBuilder 的任務:
有兩個狀態變數,
dataFromBackend并且isLoadingFlag On啟動,設定
isLoadingFlag = true,并基于此,顯示loader。資料到達后,使用從后端獲取的資料設定資料并設定
isLoadingFlag = false(setState顯然是內部)我們需要
if-else創建一個小部件。如果isLoadingFlag是true,則顯示,loader否則顯示data。失敗時,顯示錯誤訊息。
FutureBuilder 的任務:
- 給
futureFuture Builder的異步任務 - 基于
connectionState,顯示訊息(加載active(streams),,,done) - 基于
data(snapshot.hasError),顯示視圖
FutureBuilder 的優點
- 不使用兩個狀態變數和 setState
- 反應式編程(FutureBuilder 將負責在資料到達時更新視圖)
例子:
FutureBuilder<String>(
future: _fetchNetworkCall, // async work
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting: return Text('Loading....');
default:
if (snapshot.hasError)
return Text('Error: ${snapshot.error}');
else
return Text('Result: ${snapshot.data}');
}
},
)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/428079.html
上一篇:如何在NodeAPI(Express)中執行延遲作業
下一篇:基于另一個屬性值的動態屬性型別
