Повторная визуализация флаттера

#javascript #flutter

Вопрос:

Я разрабатываю прототип приложения с помощью flutter . Один из экранов позволяет пользователям обновлять количество, и он также вызывает конечную точку.

Я не хочу повторно отображать содержимое экрана после того, как пользователь увеличит количество, Вот мой код, любая помощь будет признательна

 import 'package:flutter/material.dart'; import 'dart:async'; import 'package:http/http.dart' as http; import 'dart:convert';  class ProductDetailScreen extends StatelessWidget{  @override   Widget build(BuildContext context)  {  return MaterialApp(   title: "Product #1",   home:Scaffold(  appBar: AppBar( title: const Text('Product #1', style: TextStyle(color: Colors.deepOrange)),  backgroundColor: Colors.white,  iconTheme: IconThemeData(color: Colors.deepOrange),  actions: lt;Widgetgt;[   IconButton(onPressed: (){  ScaffoldMessenger.of(context).showSnackBar(  const SnackBar(content: Text('This is a snackbar')));  },icon: const Icon(Icons.shopping_cart),color: Colors.deepOrange,)  ],  leading: BackButton(color: Colors.deepOrange,  onPressed: () =gt; Navigator.of(context).pop())  ),   body:  SafeArea(child: Center(  child: ProductsDetailsScreen()  ),   ),  ),  );  }  } class ProductsDetailsScreen extends StatefulWidget{  const ProductsDetailsScreen({Key? key}) : super(key: key);  @override  _ProductsDetailScreenState createState() =gt; _ProductsDetailScreenState(); }   class _ProductsDetailScreenState extends Statelt;ProductsDetailsScreengt; {  int qty = 0; void _increment(){  setState((){  qty = qty 1;  }); }    Futurelt;Listgt; fetchProduct() async{  final response = await http.get(Uri.parse('https://www.thecocktaildb.com/api/json/v1/1/random.php'));  final product = json.decode(response.body);  List prod = product['drinks'];  Listlt;Prodgt; prods = [];  print(response);  for(var p in prod){   Prod product = Prod(idDrink: p["idDrink"],strDrink: p['strDrink'],strDrinkThumb: p['strDrinkThumb'] );  prods.add(product);    }  return prods;   }  @override  Widget build(BuildContext context)  {  return  Container(  child:FutureBuilder(  future : fetchProduct(),  builder: (BuildContext context, AsyncSnapshot snapshot){   if(snapshot.data == null)  {  return Container(   child:Text("Loading...")  );  }else {  return  Column(  children: Listlt;Widgetgt;.generate(snapshot.data.length,(int index) {  return (   Column(  crossAxisAlignment: CrossAxisAlignment.center,  mainAxisAlignment: MainAxisAlignment.center,  children :lt;Widgetgt;[  Image.network(snapshot.data[index].strDrinkThumb,  fit: BoxFit.contain,  ),  Text(snapshot.data[index].strDrink.toUpperCase(),  style: TextStyle(color: Colors.black,fontFamily: "Verdana",  fontSize: 20,  ),   ),  Text('49.00',  style: TextStyle(color: Colors.deepOrange,fontFamily: "Verdana",  fontSize: 20,  ),   ),   Row(  //crossAxisAlignment: CrossAxisAlignment.center,  mainAxisAlignment: MainAxisAlignment.center,  children :lt;Widgetgt;[    Expanded(  flex:2,  child: ElevatedButton(  onPressed: (){},  child: Text('-'),  style: ElevatedButton.styleFrom(primary:Colors.deepOrange,  ),)   ),  Expanded(  flex:6,  child: Container(alignment: Alignment.center,  child:Text('$qty')),  ),   Expanded(  flex:2,  child:ChangeQuantity(_increment)  // child: ElevatedButton(  // onPressed:() =gt;{changeQty()},  // child: Text(' '),  // style: ElevatedButton.styleFrom(primary:Colors.deepOrange,  // ),)   ),  ]  ),  Column(  crossAxisAlignment: CrossAxisAlignment.stretch,  children:lt;Widgetgt; [  ElevatedButton.icon(  icon: Icon(Icons.shopping_basket_rounded),  onPressed: (){},  label: Text('Add to trolley'),  style: ElevatedButton.styleFrom(primary:Colors.deepOrange,  ),  )]  )   ],      )  );  }  )  );    }}   )   );   } }  class ChangeQuantity extends StatefulWidget {  final VoidCallback increment;   ChangeQuantity(this.increment);  @override  _ChangeQtyScreenState createState() =gt; _ChangeQtyScreenState(); }  class _ChangeQtyScreenState extends Statelt;ChangeQuantitygt; {  @override  Widget build(BuildContext context) {  return  ElevatedButton(  onPressed: widget.increment,  child: Text(' '),  style: ElevatedButton.styleFrom(primary:Colors.deepOrange));  } }  

Этот код работает, но не так, как я хочу. Я обнаружил, что при увеличении количества страница снова отображается, и выполняется вызов uri, который отображает

Ответ №1:

В _ProductsDetailScreenState, чтобы не выполнять повторную визуализацию, переместите List.generate в параметр statefulwidget. Передайте снимок.данные в этот параметр состояния. Таким образом, каждый раз, когда вы нажимаете на кнопку увеличения, этот параметр statefulwidget будет перезагружаться, а не метод сборки _ProductsDetailScreenState, избегающий попадания в API.

 class _ProductsDetailScreenState extends Statelt;ProductsDetailsScreengt; {  Listlt;intgt; qty = [];   ……..   @override Widget build(BuildContext context) { return Container(  child: FutureBuilder(  future: fetchProduct(),  builder: (BuildContext context, AsyncSnapshot snapshot) {  if (snapshot.data == null) {  return Container(child: Text("Loading..."));  } else {  qty = List.filled((snapshot.data as List).length, 0);  return CustomWidget(snapshot.data, qty);  }  }));  } }  class CustomWidget extends StatefulWidget { final Listlt;Drinksgt; drinks; final Listlt;intgt; qty;  CustomWidget(this.drinks, this.qty);  @override Statelt;StatefulWidgetgt; createState() =gt; _CustomWidgetState(); }  class _CustomWidgetState extends Statelt;CustomWidgetgt; { _increment(int index) {  setState(() {  widget.qty[index]  ;  print(widget.qty[index]);  }); }  @override Widget build(BuildContext context) { return Column(  children: Listlt;Widgetgt;.generate(widget.drinks.length, (int index) {  return Expanded(  child: (Column(  crossAxisAlignment: CrossAxisAlignment.center,  mainAxisAlignment: MainAxisAlignment.center,  children: lt;Widgetgt;[  Image.network(  widget.drinks[index].strDrinkThumb,  fit: BoxFit.contain,  width: 40,  height: 40,  ),  Text(  widget.drinks[index].strDrink.toUpperCase(),  style: TextStyle(  color: Colors.black,  fontFamily: "Verdana",  fontSize: 20,  ),  ),  Text(  '49.00',  style: TextStyle(  color: Colors.deepOrange,  fontFamily: "Verdana",  fontSize: 20,  ),  ),  Row(  //crossAxisAlignment: CrossAxisAlignment.center,  mainAxisAlignment: MainAxisAlignment.center,  children: lt;Widgetgt;[  Expanded(  flex: 2,  child: ElevatedButton(  onPressed: () {},  child: Text('-'),  style: ElevatedButton.styleFrom(  primary: Colors.deepOrange,  ),  )),  Expanded(  flex: 6,  child: Container(  alignment: Alignment.center,  child: Text('${widget.qty[index]}')),  ),  Expanded(flex: 2, child: ChangeQuantity(_increment, index)),  ]),  Column(  crossAxisAlignment: CrossAxisAlignment.stretch,  children: lt;Widgetgt;[  ElevatedButton.icon(  icon: Icon(Icons.shopping_basket_rounded),  onPressed: () {},  label: Text('Add to trolley'),  style: ElevatedButton.styleFrom(  primary: Colors.deepOrange,  ),  )  ])  ],  )),  ); })); } }  class ChangeQuantity extends StatefulWidget { final ValueChangedlt;intgt; increment; final int index;  ChangeQuantity(this.increment, this.index);  @override _ChangeQtyScreenState createState() =gt; _ChangeQtyScreenState(); }  class _ChangeQtyScreenState extends Statelt;ChangeQuantitygt; { @override Widget build(BuildContext context) { return ElevatedButton(  onPressed: () {  widget.increment(widget.index);  },  child: Text(' '),  style: ElevatedButton.styleFrom(primary: Colors.deepOrange)); } }