1.
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override Widget build(BuildContext context) {
return MultiProvider(providers: [
ChangeNotifierProvider.value(
value: Products(),
),
ChangeNotifierProvider.value(
value: Cart(),
),
ChangeNotifierProvider.value(
value: Order(),
),
],
child: MaterialApp(
title: 'My Shop',
theme: ThemeData(
primarySwatch: Colors.purple,
accentColor: Colors.deepOrange,
fontFamily: 'Lato',
textTheme: ThemeData.light().textTheme.copyWith(
body1: TextStyle(
color: Color.fromRGBO(20, 51, 51, 1),
),
title: TextStyle(
fontSize: 24,
fontFamily: 'Anton',
)
)
),
home: ProductsOverview(),
routes: {
ProductDetails.routeName : (context)=>ProductDetails(),
CartScreen.routeName : (context)=>CartScreen(),
OrdersScreen.routeName:(ctx)=>OrdersScreen(),
UserProductScreen.routeName : (ctx)=>UserProductScreen(),
EditProductScreen.routeName : (ctx)=>EditProductScreen(),
},
),
);
// и мне нужно прослушайте изменения на экране редактирования ниже
Экран
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import. '../providers/Product.dart';
import '../providers/Products.dart';
class EditProductScreen extends StatefulWidget { static const
routeName = '/EditProduct';
@override _EditProductScreenState createState() =>
_EditProductScreenState(); }
class _EditProductScreenState extends State<EditProductScreen> {
final _imageUrlController = TextEditingController();
final _imageFocusNode = FocusNode();
final _form = GlobalKey<FormState>();
var _editProduct = Product(id: null, title: '', price: 0, description: '', imageUrl: '');
void _saveForm(){
final isValid = _form.currentState.validate();
if(!isValid){
return ;
}
_form.currentState.save();
Provider.of<Products>(context, listen: false).addProduct(_editProduct);
Navigator.of(context).pop(); }
@override void initState() {
_imageFocusNode.addListener(updateImageUrl);
super.initState(); } void updateImageUrl(){
if(!_imageFocusNode.hasFocus){
setState(() {
});
} }
@override void dispose() {
_imageFocusNode.dispose();
_imageUrlController.dispose();
super.dispose(); }
@override Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Edit Product'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.save),
onPressed: _saveForm,)
],
),
body: Form(
key: _form,
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(16),
child: Column(
children: <Widget>[
TextFormField(
decoration: InputDecoration(
labelText: 'title',
),
textInputAction: TextInputAction.next,
onFieldSubmitted: (_)=>FocusScope.of(context).nextFocus(),
validator: (value){
if(value.isEmpty){
return 'please enter a title';
}
return null;
},
onSaved: (value){
_editProduct = Product(
title: value,
price: _editProduct.price,
description: _editProduct.description,
imageUrl: _editProduct.imageUrl);
},
),
TextFormField(
decoration: InputDecoration(
labelText: 'price'
),
textInputAction: TextInputAction.next,
keyboardType: TextInputType.number,
onFieldSubmitted: (_)=>FocusScope.of(context).nextFocus(),
validator: (value){
if(value.isEmpty){
return 'please enter a price';
}
if(double.tryParse(value) == null){
return 'please enter a number';
}
if(double.parse(value)<=0){
return 'please enter a number bigger than Zero';
}
return null;
},
onSaved: (value){
_editProduct = Product(
title: _editProduct.title,
price: double.parse(value),
description: _editProduct.description,
imageUrl: _editProduct.imageUrl);
},
),
TextFormField(
decoration: InputDecoration(
labelText: 'Description'
),
textInputAction: TextInputAction.newline,
keyboardType: TextInputType.multiline,
maxLines: 3,
onFieldSubmitted:(_)=>FocusScope.of(context).nextFocus(),
validator: (value){
if(value.isEmpty){
return 'please enter a valid description';
}
if(value.length<10){
return 'Should be at least 10 characters long';
}
return null;
},
onSaved: (value){
_editProduct = Product(
title: _editProduct.title,
price: _editProduct.price,
description: value,
imageUrl: _editProduct.imageUrl);
},
),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Container(
width: 100,
height: 100,
margin: EdgeInsets.only(top: 8, right: 10),
decoration: BoxDecoration(border: Border.all(width: 1),
color: Colors.grey),
child:
_imageUrlController.text.isEmpty
? Text('Enter Image Url')
: FittedBox(child: Image.network(_imageUrlController.text, fit: BoxFit.cover,),
),
),
Expanded(
child: TextFormField(
decoration: InputDecoration(
labelText: 'Image Url',
),
keyboardType: TextInputType.url,
textInputAction: TextInputAction.done,
controller: _imageUrlController,
focusNode: _imageFocusNode,
onFieldSubmitted: (_)=>_saveForm(),
validator: (value){
if(value.isEmpty){
return 'please enter a an Image Url';
}
if((!value.startsWith('http')) && (!value.startsWith('https'))){
return 'please enter a valid image url';
}
return null;
},
onSaved: (value){
_editProduct = Product(
title: _editProduct.title,
price: _editProduct.price,
description: _editProduct.description,
imageUrl: value);
},
),
)
],
)
],
),
),
),
),
); } }
// и это класс модели
import 'package:flutter/material.dart';
import 'Product.dart';
class Products with ChangeNotifier{
List<Product> _items = [
Product(
id: 'p1',
title: 'Red Shirt',
description: 'A red shirt - it is pretty red!',
price: 29.99,
imageUrl:
'https://cdn.pixabay.com/photo/2016/10/02/22/17/red-t-shirt-1710578_1280.jpg',
),
Product(
id: 'p2',
title: 'Trousers',
description: 'A nice pair of trousers.',
price: 59.99,
imageUrl:
'https://upload.wikimedia.org/wikipedia/commons/thumb/e/e8/Trousers%2C_dress_%28AM_1960.022-8%29.jpg/512px-Trousers%2C_dress_%28AM_1960.022-8%29.jpg',
),
Product(
id: 'p3',
title: 'Yellow Scarf',
description: 'Warm and cozy - exactly what you need for the winter.',
price: 19.99,
imageUrl:
'https://live.staticflickr.com/4043/4438260868_cc79b3369d_z.jpg',
),
Product(
id: 'p4',
title: 'A Pan',
description: 'Prepare any meal you want.',
price: 49.99,
imageUrl:
'https://upload.wikimedia.org/wikipedia/commons/thumb/1/14/Cast-Iron-Pan.jpg/1024px-Cast-Iron-Pan.jpg',
),
];
List<Product> get items{ return [..._items]; }
List<Product> get favoriteItems{
return items.where((prodItems)=>prodItems.isFavorite).toList();
} void addProduct (Product product){
final newProduct = Product(
id: DateTime.now().toString(),
title: product.title,
price: product.price,
description: product.description,
imageUrl: product.imageUrl
);
_items.add(newProduct);
notifyListeners(); } Product findById(String id){
return items.firstWhere((product){
return product.id == id;
}); }
}