Flutter Navigator.pop 再次运行小部件构建方法
Posted
技术标签:
【中文标题】Flutter Navigator.pop 再次运行小部件构建方法【英文标题】:Flutter Navigator.pop running widget build method again 【发布时间】:2020-12-30 01:31:15 【问题描述】:我有两个小部件
-
类别小部件 - 我在其中显示类别的名称和图像
CategoryDetailsScreen 小部件 - 我在其中显示与该类别相关的项目列表
我在类别小部件上有 onTap 方法,从中我将一些路由参数传递到详细信息屏幕
onTap: ()
Navigator.of(context).pushNamed(
CategoryDetailScreen.routeName,
arguments:
'id': id,
'name': name,
'slug': slug,
,
);
在类别详细信息页面上,我得到了这些参数
final categoryArgs =
ModalRoute.of(context).settings.arguments as Map<String, String>;
现在,当我尝试使用应用栏后退按钮返回时,它会再次调用我的类别详细信息屏幕的构建方法。然后它再次调用我的 API。我想避免这种情况,并且不想在返回类别页面时再次调用我的 API。
这是我的两个小部件的完整代码 -
category.dart
import 'package:flutter/material.dart';
import 'dart:ui';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:captionsocial/screens/category_detail_screen.dart';
class Category extends StatelessWidget
final String id;
final String name;
final String image;
final String slug;
Category(this.id, this.name, this.image, this.slug);
@override
Widget build(BuildContext context)
return InkWell(
onTap: ()
Navigator.of(context).pushNamed(
CategoryDetailScreen.routeName,
arguments:
'id': id,
'name': name,
'slug': slug,
,
);
,
borderRadius: BorderRadius.circular(12),
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
alignment: Alignment.center,
fit: BoxFit.cover,
image: CachedNetworkImageProvider(
image,
),
),
borderRadius: BorderRadius.circular(12),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(12),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 0, sigmaY: 0),
child: Container(
alignment: Alignment.center,
color: Colors.black.withOpacity(0.5),
child: Text(
name,
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
),
),
),
);
类别详情屏幕
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../providers/posts.dart';
class CategoryDetailScreen extends StatelessWidget
static const routeName = 'category-detail';
@override
Widget build(BuildContext context)
print('running again');
final categoryArgs =
ModalRoute.of(context).settings.arguments as Map<String, String>;
final productsData = Provider.of<Posts>(context, listen: false);
final temp = productsData.getPostsBySlug(categoryArgs['slug']);
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back_ios),
onPressed: ()
Navigator.pop(context);
),
elevation: 1,
backgroundColor: Colors.white,
title: Text(
categoryArgs['name'],
style: TextStyle(color: Theme.of(context).primaryColor),
),
),
body: FutureBuilder(
future: temp,
builder: (ctx, snapShot) =>
snapShot.connectionState == ConnectionState.waiting
? Center(
child: CircularProgressIndicator(),
)
: Consumer<Posts>(
builder: (ct, postsData, child) => Padding(
padding: EdgeInsets.symmetric(horizontal: 0, vertical: 0),
child: ListView.builder(
padding: const EdgeInsets.all(10.0),
itemCount: postsData.posts.length,
itemBuilder: (ctx, i) => Text(postsData.posts[i].title),
),
),
),
),
);
导致问题的行是
final categoryArgs =
ModalRoute.of(context).settings.arguments as Map<String, String>;
如果我删除上面的行,那么当我使用 appbar 后退按钮返回时不会再次调用 build 方法。
【问题讨论】:
【参考方案1】:您需要在此处使用StatefulWidget
。据我所知,你无法控制flutter何时调用小部件的build
方法,即使是无状态的也是如此。
将涉及您的Future
的部分移动到StatefulWidget
的State
中的initState
。 initState
可能无法用于这种情况,因为需要 BuildContext
,因此如果这导致错误,请将其移至 didChangeDependencies
。
class CategoryDetailScreen extends StatefulWidget
@override
_CategoryDetailScreenState createState() => _CategoryDetailScreenState();
class _CategoryDetailScreenState extends State<CategoryDetailScreen>
var temp;
@override
void initState()
super.initState();
final categoryArgs =
ModalRoute.of(context).settings.arguments as Map<String, String>;
final productsData = Provider.of<Posts>(context, listen: false);
temp = productsData.getPostsBySlug(categoryArgs['slug']);
【讨论】:
以上是关于Flutter Navigator.pop 再次运行小部件构建方法的主要内容,如果未能解决你的问题,请参考以下文章
Navigator.pop(context) 不返回上一屏 Flutter
如何在 Flutter 中的 navigator.pop(context) 之后显示小吃栏?
Flutter BLoC:构建()方法中 StreamBuilder 中的 Navigator.pop
Flutter - 从 AppBar 返回上一页不会刷新页面,使用 Navigator.pop(context)