我有一张卡片列表,每张卡片都有一个长按功能,点击后会弹出一个警告对话框。我希望卡片根据警报对话框中选择的选项更改颜色。我的警报对话框有 3 个选项:已完成(卡片应变为绿色)、进行中(橙色)、取消(灰色)。
首先,当屏幕加载时,它应该显示一张卡片列表,每张卡片都根据保存在数据库中的值涂上颜色。然后,当用户长按卡片并从警报对话框中选择一个选项时,卡片的颜色应根据所选选项而改变。只有该特定卡的颜色应该改变。
我在某处读到这可能可以使用 valuechangenotifier 来实现。所以这是我到目前为止所做的:
首先,我创建了我的 changenotifier 类,如下所示:
import 'package:flutter/material.dart';
class ColorChanger with ChangeNotifier{
Color _color = Colors.white;
ColorChanger(this._color);
getColor() => _color;
setTheme (Color color) {
_color = color;
notifyListeners();
}
}
然后我在我的飞镖课上使用了它。但是,颜色似乎没有改变。我在这里想念什么?
class OrderItem extends StatefulWidget {
final ord.OrderItem order;
OrderItem(this.order);
@override
_OrderItemState createState() => _OrderItemState();
}
class _OrderItemState extends State<OrderItem> {
var _expanded = false;
var mycolor = Colors.white;
@override
Widget build(BuildContext context) {
ColorChanger _color = Provider.of<ColorChanger>(context);
var listProducts = widget.order.products;
return Card(
color: widget.order.orderStatus=='completed'
?Colors.lightGreen:widget.order.orderStatus=='inprogress'?
Colors.orangeAccent:
widget.order.orderStatus=='cancelled'?Colors.grey:mycolor,
margin: EdgeInsets.all(10),
child: Column(
children: <Widget>[
ListTile(
title: RichText(
text: new TextSpan(
style: new TextStyle(
fontSize: 14.0,
color: Colors.black,
),
children: <TextSpan>[
new TextSpan(
text: 'Order Number : ',
style: new TextStyle(fontWeight: FontWeight.bold)),
new TextSpan(text: widget.order.uniqueOrderNumber),
],
),
),
trailing: IconButton(
icon: Icon(_expanded ? Icons.expand_less : Icons.expand_more),
onPressed: () {
setState(() {
_expanded = !_expanded;
});
},
),
onLongPress: toggleSelection,
),
],
),
);
}
void toggleSelection() {
ColorChanger _color = Provider.of<ColorChanger>(context,listen:false);
Widget completeOrder = FlatButton(
child: Text('Completed'),
onPressed: () async {
try {
Navigator.of(context).pop(true);
// setState(() {
_color.setTheme(Colors.lightGreen);
// });
await Provider.of<Orders>(context, listen: false)
.updateOrder(widget.order,'completed');
} catch (error) {
}
});
Widget startOrder = FlatButton(
child: Text('In progress'),
onPressed: () async {
try {
Navigator.of(context).pop(true);
// setState(() {
_color.setTheme(Colors.orangeAccent);
//});
//Update Db to mark order in progress
await Provider.of<Orders>(context, listen: false)
.updateOrder(widget.order,'inprogress');
} catch (error) {
}
});
Widget cancelOrder = FlatButton(
child: Text('Cancel'),
onPressed: () async {
try {
Navigator.of(context).pop(false);
// setState(() {
_color.setTheme(Colors.grey);
// });
//Update Db to mark order as cancelled
await Provider.of<Orders>(context, listen: false)
.updateOrder(widget.order,'cancelled');
} catch (error) {
}
});
showDialog(
context: context,
builder: (ctx) => AlertDialog(
title: Text('Take Action'),
content: Text('What do you want to do with the order?'),
actions: <Widget>[
startOrder,
completeOrder,
cancelOrder
],
),
);
});
}
}
根据 Loren 的回答进行第二次尝试。
import 'package:flutter/material.dart';
class ColorChanger with ChangeNotifier{
Color color = Colors.white;
setTheme (Color newColor) {
color = newColor;
notifyListeners();
}
}
class OrderItem extends StatefulWidget {
final ord.OrderItem order;
OrderItem(this.order);
@override
_OrderItemState createState() => _OrderItemState();
}
class _OrderItemState extends State<OrderItem> {
var _expanded = false;
//Set the color based on what was last saved in the DB
void didChangeDependencies() async {
var colorChanger = Provider.of<ColorChanger>(context, listen: false);
if(widget.order.orderStatus=='completed')
colorChanger.setTheme(Colors.lightGreen);
else if(widget.order.orderStatus=='inprogress')
colorChanger.setTheme(Colors.orangeAccent);
else if(widget.order.orderStatus=='cancelled')
colorChanger.setTheme(Colors.grey);
super.didChangeDependencies();
}
@override
Widget build(BuildContext context) {
var listProducts = widget.order.products;
return Consumer<ColorChanger>(
builder: (context, colorChanger, child) {
return Card(
color: widget.order.orderStatus=='completed'
?Colors.lightGreen:widget.order.orderStatus=='inprogress'?
Colors.orangeAccent:
widget.order.orderStatus=='cancelled'?Colors.grey:mycolor,
margin: EdgeInsets.all(10),
child: Column(
children: <Widget>[
ListTile(
title: RichText(
text: new TextSpan(
style: new TextStyle(
fontSize: 14.0,
color: Colors.black,
),
children: <TextSpan>[
new TextSpan(
text: 'Order Number : ',
style: new TextStyle(fontWeight: FontWeight.bold)),
new TextSpan(text: widget.order.uniqueOrderNumber),
],
),
),
trailing: IconButton(
icon: Icon(_expanded ? Icons.expand_less : Icons.expand_more),
onPressed: () {
setState(() {
_expanded = !_expanded;
});
},
),
onLongPress: toggleSelection,
),
],
),
)};
}
void toggleSelection() {
ColorChanger _color = Provider.of<ColorChanger>(context,listen:false);
Widget completeOrder = FlatButton(
child: Text('Completed'),
onPressed: () async {
try {
Navigator.of(context).pop(true);
// setState(() {
_color.setTheme(Colors.lightGreen);
// });
await Provider.of<Orders>(context, listen: false)
.updateOrder(widget.order,'completed');
} catch (error) {
}
});
Widget startOrder = FlatButton(
child: Text('In progress'),
onPressed: () async {
try {
Navigator.of(context).pop(true);
// setState(() {
_color.setTheme(Colors.orangeAccent);
//});
//Update Db to mark order in progress
await Provider.of<Orders>(context, listen: false)
.updateOrder(widget.order,'inprogress');
} catch (error) {
}
});
Widget cancelOrder = FlatButton(
child: Text('Cancel'),
onPressed: () async {
try {
Navigator.of(context).pop(false);
// setState(() {
_color.setTheme(Colors.grey);
// });
//Update Db to mark order as cancelled
await Provider.of<Orders>(context, listen: false)
.updateOrder(widget.order,'cancelled');
} catch (error) {
}
});
showDialog(
context: context,
builder: (ctx) => AlertDialog(
title: Text('Take Action'),
content: Text('What do you want to do with the order?'),
actions: <Widget>[
startOrder,
completeOrder,
cancelOrder
],
),
);
});
}
}
当我这样做时,它会改变所有卡片的颜色,而不仅仅是一张卡片。我在这里做错了什么?
分享order.dart
class OrderItem {
final String id;
final double amount;
final int deliveryFee;
final List<CartItem> products;
final DateTime dateTime;
final String deliveryMethod;
final String uniqueOrderNumber;
final String orderStatus;
final String userId;
final String customMessage;
final String customerName;
final String phoneNumber;
OrderItem(
{@required this.id,
@required this.amount,
@required this.products,
@required this.dateTime,
@required this.deliveryMethod,
@required this.uniqueOrderNumber,
@required this.isOrderComplete,
this.orderStatus,
@required this.customMessage,
@required this.deliveryFee,
this.customerName,
this.phoneNumber,
@required this.userId});
}
class Orders with ChangeNotifier {
final String authToken;
final String userId;
Orders(this.authToken, this.userId);
List<OrderItem> _orders = [];
List<OrderItem> get orders {
return [..._orders];
}
Future<void> updateOrder(OrderItem order,String orderStatus) async {
final id = order.id;
final customerId = order.userId;
final url =
'https://cv.firebaseio.com/orders/$customerId/$id.json?auth=$authToken';
try {
await http.patch(url,
body: json.encode({
'orderStatus':orderStatus
}));
} catch (error) {
print(error);
}
notifyListeners();
}