[英]Prevent Flutter Provider from rebuilding widgets in previous screen due updates on current screen
[英]flutter: Widgets are rebuilding even though `provider` is used
我正在使用provider
進行顫振狀態管理。 下面是我的代碼
家
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
//backgroundColor: Color.fromRGBO(0, 72, 100, 10),
backgroundColor: Color.fromRGBO(25, 72, 114, 10),
title: Text("something"),
bottom: TabBar(
indicatorColor: Colors.white70,
labelStyle: TextStyle(
fontFamily: 'Roboto-Regular',
fontSize: 16.0,
letterSpacing: 0.15),
labelColor: Colors.white,
labelPadding: EdgeInsets.all(5),
tabs: <Widget>[
Tab(
text: "Fresh Products",
),
Tab(
text: "Frozen Products",
),
],
),
),
body: Center(child: Home()),
),
);
}
}
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("Home build methof");
return TabBarView(
children: <Widget>[
Container(
height: double.infinity,
child: FutureBuilder(
future: Provider.of<ProductSpeciesImpl>(context, listen: false)
.getAllSpecies(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
CircularProgressIndicator(),
Container(
height: 10,
),
Text(
"Loading Data... Please Wait",
style: Theme.of(context).textTheme.body1,
)
],
),
),
);
} else {
if (snapshot.hasError) {
return Center(
child: Text("An error Occured"),
);
} else {
return Consumer<ProductSpeciesImpl>(
builder: (context, data, child) => GridView.builder(
physics:
ScrollPhysics(), // to disable GridView's scrolling
shrinkWrap: true,
itemCount: Provider.of<ProductSpeciesImpl>(context)
.productList
.length,
gridDelegate:
new SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio:
(MediaQuery.of(context).size.width *
.5 /
190),
crossAxisCount: 2),
itemBuilder: (BuildContext context, int index) {
return GestureDetector(
onTap: () {
//print("sdsdsdsd");
// print(snapshot.data[index].name + " " + snapshot.data[index].idProductSpecies.toString() + " "+ snapshot.data[index].photo);
Navigator.pushNamed(context, "/products",
arguments: {
"name": Provider.of<ProductSpeciesImpl>(
context,
listen: false)
.productList[index]
.name,
"id": Provider.of<ProductSpeciesImpl>(
context,
listen: false)
.productList[index]
.idProductSpecies,
"photo": Provider.of<ProductSpeciesImpl>(
context,
listen: false)
.productList[index]
.photo
});
},
child: Card(
elevation: 4.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0)),
clipBehavior: Clip.antiAlias,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
child: Text(
Provider.of<ProductSpeciesImpl>(context,
listen: false)
.productList[index]
.name,
),
)
],
),
),
);
}));
}
}
},
),
),
產品種類Impl
class ProductSpeciesImpl
with ChangeNotifier
implements ProductSpeciesInterface {
NavLinks navLinks = NavLinks();
List<ProductSpecies> productList = [];
@override
Future<void> getAllSpecies() async {
var data = await http.get(navLinks.getAllProductSpecies());
var jsonData = convert.json.decode(data.body).cast<Map<String, dynamic>>();
try {
productList = jsonData
.map<ProductSpecies>((json) => new ProductSpecies.fromJson(json))
.toList();
print("Product sIZE: " + productList.length.toString());
notifyListeners();
} catch (error) {
throw error;
}
}
}
該代碼工作正常。 問題是每次我訪問另一個頁面並返回此頁面時,UI 都會重新加載。 我用過consumer
,據我所知, consumer
只會在調用時加載相關部分。 這意味着我也不必在init
運行我的產品加載代碼。 所以,我不明白為什么會這樣。
感謝您對解決此問題的支持。
您在此處通過調用getAllSpecies()
在build()
函數中發起 HTTP 請求。 你不應該這樣做。
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
//...
child: FutureBuilder(
future: Provider.of<ProductSpeciesImpl>(context, listen: false)
.getAllSpecies(),
build()
函數應該沒有副作用。 請將小部件轉換為StatefulWidget
並在initState()
加載。 或者,讓父StatefulWidget
在其initState()
加載並在其構造函數中將數據傳遞給此小部件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.