gpt4 book ai didi

flutter - 为什么我的 AsyncMemoizer 在 Flutter 中无法正常运行,我想停止不必要地重建我的小部件

转载 作者:行者123 更新时间:2023-12-03 04:36:50 25 4
gpt4 key购买 nike

我正在开发一个像 Live TV 这样的应用程序,它基本上是一个基于视频的推荐平台
我注意到的是,当我在我的应用程序的“主页”中滚动时,状态小部件被一次又一次地调用(因为我正在使用 Future builder),因此它会导致大量数据消耗,这是一个严重的问题我希望它不要发生。
我根据这篇文章使用了内存的概念 https://medium.com/saugo360/flutter-my-futurebuilder-keeps-firing-6e774830bc2 .代码不会引发错误。但是使用它后我的主页没有加载。我不明白为什么会这样?
这是我 future builder 代码:

@override
Widget build(BuildContext context) {
print("Build function called......................");

body: SafeArea(
child: SingleChildScrollView(
controller: _scrollController,
child: FutureBuilder(
future: widgetLoadingFunctions(_selectedIndex),
builder:
(BuildContext context, AsyncSnapshot<String> snapshot) {
if (snapshot.hasData) {
return widgetOptions(_selectedIndex);
} else
return //Asset.image('assets/loading.gif');
Image.asset('assets/loading.gif');
})),
),
drawer: Drawer(),
bottomNavigationBar: BottomNavigationBar(
backgroundColor: Colors.black,
showUnselectedLabels: true,
type: BottomNavigationBarType.shifting,
currentIndex: _selectedIndex,
fixedColor: Colors.amber,
onTap: (int index) {
setState(() {
_selectedIndex = index;
});
},
items: <BottomNavigationBarItem>[
// Icon(
// FontAwesome.facebook_square,
// color: Colors.amber,
// ),
BottomNavigationBarItem(
backgroundColor: Colors.black,
icon: Icon(Icons.home),
title: Text('Home'),
),
BottomNavigationBarItem(
backgroundColor: Colors.black,
icon: Icon(
MaterialCommunityIcons.video_vintage,
),
title: Text(
'Movies',
),
),
BottomNavigationBarItem(
backgroundColor: Colors.black,
icon: Icon(Icons.live_tv),
title: Text(
'Tv shows',
),
),

BottomNavigationBarItem(
backgroundColor: Colors.black,
icon: Icon(Icons.music_video),
title: Text(
'Music',
),
),
BottomNavigationBarItem(
backgroundColor: Colors.black,
icon: Icon(Icons.radio),
title: Text(
'News',
),
),
BottomNavigationBarItem(
backgroundColor: Colors.black,
icon: Icon(
FontAwesome.heartbeat,
),
title: Text(
'LifeStyle',
),
),
BottomNavigationBarItem(
backgroundColor: Colors.black,
icon: Icon(
Ionicons.md_football,
),
title: Text(
'Sports',
),
),
],
),
);
负责加载的future函数如下:
 Future<String> widgetLoadingFunctions(int idx) async {
switch (idx) {
case 0:
return _memoizer.runOnce(() async {
var x = await functionsToBeLoadedForHomePage();
return x;
});

case 1:
return await functionsToBeLoadedForMoviesPage();

case 2:
return await functionsToBeLoadedForTvSHowsPage();

case 3:
return await functionsToBeLoadedForMusicPage();

case 4:
return await functionsToBeLoadedForNewsPage();

case 5:
return await functionsToBeLoadedForLifeStylePage();

case 6:
return await functionsToBeLoadedForSportsPage();
}
}
之后我将使用 memoizer 以相同的方式实现剩余的功能。
memoizer 的声明是:
class _LiveTvHomePageState extends State<LiveTvHomePage> {

final AsyncMemoizer _memoizer = AsyncMemoizer();
第一个函数,即functionsToBeLoadedForHomePage()如下:
Future<String> functionsToBeLoadedForHomePage() async {
String url =
"https://livetvapi.apyhi.com/api/v3/home?pageLocation=home&countries=IN&app_version=13&"
"user_id=44edc2c905ae163f&package_id=livetv.movies.freemovies.watchtv.tvshows&os_platform=android";

var res = await http
.get(url, headers: {'Authorization': dartJsonWebTokenGenerator()});
var _playListImgUrlsObjects = [];
List<String> _thumbNailList = [];
List<String> _titleNames = [];
List<String> _subtitleNames = [];
List<String> _noOfSongs = [];
List<String> _playListVideoLinks = [];

if (res.statusCode == 200) {
final _homePage = homePageFromJson(res.body);

for (var homeBannerObject in _homePage.homeBanners) {
for (var obj in homeBannerObject.thumbnail) {
_homeBannerObjectthumbnailList.add(obj.toString());
}

_homeBannerObjectMovieIdList.add(homeBannerObject.movieId.substring(8));
}

for (var homeBannerObject in _homePage.movies) {
for (var obj in homeBannerObject.thumbnail) {
_popularMoviesthumbNail.add(obj.toString());
}

_popularMoviesMovieId.add(homeBannerObject.movieId.substring(8));
}

for (var homeBannerObject in _homePage.series) {
for (var obj in homeBannerObject.thumbnail) {
_seriesData.add(obj.toString());

_seriesVideoLinks.add(homeBannerObject.posterLink.substring(23, 34) +
"&list=" +
homeBannerObject.seriesId.substring(8));
}
}

for (var everyObj in _homePage.musicCategories) {
for (var playlistsObj in everyObj.playlists) {
_titleNames.add(playlistsObj.playlistName);
_subtitleNames.add(playlistsObj.playlistDescription.substring(
0,
playlistsObj.playlistDescription.length <= 20
? playlistsObj.playlistDescription.length
: 20) +
"...");
_noOfSongs.add(playlistsObj.playlistTotalTracks.toString());
_playListVideoLinks.add(playlistsObj.playlistUrl);
for (var playlistImagesObj in playlistsObj.playlistImages) {
_thumbNailList.add(playlistImagesObj.url);
}
}

_detailsOfMusicInHomePage[everyObj.categoryName] = [
_thumbNailList,
_titleNames,
_subtitleNames,
_noOfSongs,
_playListVideoLinks
];

_thumbNailList = [];
_titleNames = [];
_subtitleNames = [];
_noOfSongs = [];
_playListVideoLinks = [];
}

for (var playListObj in _homePage.musicPlaylists.playlists) {
_musicCategories.add(playListObj.playlistName);
}

for (var publisherObj in _homePage.publishers) {
_popularNewsChannelNames.add(publisherObj.fullName);
_popularNewsChannelProfilePicUrl.add(publisherObj.profilePicUrl);
_popularNewsChanneldesc.add(publisherObj.content.description);
}

for (var liveChannelObj in _homePage.liveChannels) {
_liveNewsChannelProfilePicUrl.add(liveChannelObj.publisherProfilePic);
_liveNewsChannelNames.add(liveChannelObj.publisherName);
}

for (var playlistsObj in _homePage.musicPlaylists.playlists) {
_playListNames.add(playlistsObj.playlistName);
_playListTotalTracks.add(playlistsObj.playlistTotalTracks.toString());
_playListImgUrlsObjects.add(playlistsObj.playlistImages);
_playListVideoUrls.add(playlistsObj.playlistUrl);
}

for (var listObj in _playListImgUrlsObjects) {
for (var obj in listObj) {
_playListImgUrls.add(obj.url.toString());
}
}

_musicPlaylistThemeName = _homePage.musicPlaylists.categoryName;
return "Successfully Exectued";
} else
return null;
}
小部件加载功能是:
Widget widgetOptions(int idx) {
Widget _selectedWidget = CircularProgressIndicator();
switch (idx) {
case 0:
_selectedWidget = homePageForBottomNavigator();
break;
case 1:
_selectedWidget = MoviesPageForBottomNavigator();
break;
case 2:
_selectedWidget = TvSHowsPageOfBottomNavigator();
break;
case 3:
_selectedWidget = MusicPageofBottomNavigator();

break;
case 4:
_selectedWidget = NewsPageOfBottomNavigator();

break;
case 5:
_selectedWidget = LifeStylePageOfBottomNavigator();
break;
case 6:
_selectedWidget = SportsPageOfBottomNavigator();
}
return _selectedWidget;
}
所以基本上在future builder的 future ,必要页面的相应功能都会被加载,然后显示出来。
HomePageWidget 是这样的:
Widget homePageForBottomNavigator() {
return Stack(
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
_buildBody(MediaQuery.of(context).size.height * 0.35,
_homeBannerObjectthumbnailList, _homeBannerObjectMovieIdList),

HorizontalListView("Popular movies", _popularMoviesthumbNail,
_popularMoviesMovieId),
HorizontalListView(
"Popular Tv shows", _seriesData, _seriesVideoLinks),
//infinite list view to be implemented here
HorizontalGridViewOfCardsofGradientColorWithtitle(
1,
"Music",
_detailsOfMusicInHomePage.keys.toList(),
_detailsOfMusicInHomePage),
HorizontalListViewWithoutViewAll(
"_musicPlaylistThemeName,",
_playListImgUrls,
_playListNames,
_playListTotalTracks,
_playListVideoUrls),
HorizontalListViewWitCircularCards(
"Popular News channels",
_popularNewsChannelProfilePicUrl,
_popularNewsChannelNames,
_popularNewsChanneldesc,
_detailsNewsPage),
HorizontalListViewWithoutViewAllForLiveNewsChannels(
"Live News Channels",
_liveNewsChannelProfilePicUrl,
_liveNewsChannelNames,
_newsPageLiveNewsVideoUrls),

//VerticalListView(["Latest News"],false),
],
), //end of 1st Widget
Positioned(
bottom: MediaQuery.of(context).size.height * 0.01,
left: MediaQuery.of(context).size.width * 0.3,
child: returnToTopButton()),
],
);
}

最佳答案

这是因为您使用的是 FutureBuilder不正确,并且您链接的中篇文章为不正确使用引起的问题提供了过于复杂的解决方案。不要相信您阅读的所有内容,尤其是当它们不是官方文档时。
docs of FutureBuilder 状态:

The future must have been obtained earlier, e.g. during State.initState, State.didUpdateConfig, or State.didChangeDependencies. It must not be created during the State.build or StatelessWidget.build method call when constructing the FutureBuilder. If the future is created at the same time as the FutureBuilder, then every time the FutureBuilder's parent is rebuilt, the asynchronous task will be restarted.


您必须获得 Future早于 build ,如 initState .你现在正在做的是获取 Future build期间.
获取 Future initState期间,将其存储在变量中,并将其传递给 FutureBuilder .
Future storedFuture;

@override
void initState() {
super.initState();
storedFuture = widgetLoadingFunctions(_selectedIndex);
}

@override
Widget build(BuildContext context) {
...

body: SafeArea(
child: SingleChildScrollView(
controller: _scrollController,
child: FutureBuilder(
future: storedFuture,

关于flutter - 为什么我的 AsyncMemoizer 在 Flutter 中无法正常运行,我想停止不必要地重建我的小部件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63955152/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com