Я пытаюсь выбрать несколько компонентов в этом Wrap.toList(), но каждый первый выбранный мной индекс не меняет свой цвет, указывая на то, что он выбран. Он выбран в списке, но не отображается. См. 4 компонента, которые я выбрал.
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: GridView.count(
crossAxisCount: 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
shrinkWrap: true,
children: cC.allCommodityList.map((order) {
return InkWell(
onTap: () {
setState(() {
selectedItems.contains(order)
? selectedItems.remove(order)
: selectedItems.add(order);
commodityName = order.commodityName;
commodityid = order.commodityID;
// }
});
},
child: Card(
child: Column(
children: [
Expanded(
child: selectedItems.contains(order)
? SvgPicture.asset(
'assets/toiletpaper.svg',
color: Color.fromRGBO(0, 76, 32, 1),
)
: SvgPicture.asset(
'assets/toiletpaper.svg',
)),
selectedItems.contains(order)
? TopBorderNoTap(
listColor: [
Color.fromRGBO(229, 229, 229, 1),
Color.fromRGBO(0, 76, 32, 1),
],
text: order.commodityName.toString(),
color: Colors.white,
textColor: Colors.white)
: TopBorderNoTap(
listColor: [
Color.fromRGBO(229, 229, 229, 1),
Colors.white
],
text: order.commodityName.toString(),
textColor: Colors.black,
)
],
)),
);
}).toList(),
))),
Это мой модельный класс, а не полный код, он просто возвращается из json в json.
CommodityModel({
this.commodityID,
this.commodityName,
this.commodityImage,
});
CommodityModel.fromJson(Map<String, dynamic> json) {
commodityID = json['commodityID'];
commodityName = json['commodityName'];
commodityImage = json['commodityImage'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['commodityID'] = commodityID;
data['commodityName'] = commodityName;
data['commodityImage'] = commodityImage;
В случае, если вышеуказанное не работает, имеет ли ваш класс модели переопределение == и хэш-код (либо каким-либо плагином, либо вашим кодом)?
Каким-то образом `selectedItems.contains(order)` эта строка не перенастраивается верно для первого элемента, если вы можете понять, что это решит вашу проблему
@Rahul, ValueKey не работает. Я не думаю, что у меня есть что-то из этого, у меня нет плагина для моего класса модели. Вы можете иметь в моем обновленном посте.
@Ruchit да, я разбираюсь в этой части. Я все еще не мог это исправить.
Попробуйте переопределить == и hashCode в своем модальном классе. Или вы можете использовать пакет equatable для того же самого. contains лучше всего работает, когда свойства равенства реализованы в классе.
@Rahul, как мне реализовать == и хэш-код в моем классе модели?
Каким-то образом выбирается первый индекс, когда я перезапускаю симулятор. После этого вообще не выбирает.
Вот хороший ресурс: stackoverflow.com/a/22999113/16569443
@Рахул Это работает. Можете ли вы добавить свой ответ, чтобы я мог отметить его как решенный?
Вы можете попробовать этот подход, чтобы выбрать элемент списка модели d-select.
class MyNewWidget extends StatefulWidget {
const MyNewWidget({super.key});
@override
State<MyNewWidget> createState() => _MyNewWidgetState();
}
class _MyNewWidgetState extends State<MyNewWidget> {
final List<CommodityModel> allCommodityList = [
CommodityModel(
commodityID: 1,
commodityName: "Toilet Paper",
commodityImage: "commodityImage"),
CommodityModel(
commodityID: 2,
commodityName: "Paper Towels",
commodityImage: "commodityImage"),
CommodityModel(
commodityID: 3,
commodityName: "Hand shop",
commodityImage: "commodityImage"),
CommodityModel(
commodityID: 4,
commodityName: "Air freshner",
commodityImage: "commodityImage")
];
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(8.0),
child: GridView.builder(
shrinkWrap: true,
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200,
childAspectRatio: 3 / 2,
crossAxisSpacing: 20,
mainAxisSpacing: 20,
),
itemCount: allCommodityList.length,
itemBuilder: (BuildContext ctx, index) {
final order = allCommodityList[index];
return Container(
alignment: Alignment.center,
child: InkWell(
onTap: () {
setState(() {
order.isSelected = !order.isSelected;
});
},
child: Card(
child: Column(
children: [
Expanded(
child: SvgPicture.asset(
'assets/toiletpaper.svg',
color: order.isSelected
? const Color.fromRGBO(0, 76, 32, 1)
: null,
)),
Row(
children: [
Expanded(
child: Container(
color: order.isSelected
? const Color.fromRGBO(0, 76, 32, 1)
: null,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Text(
order.commodityName ?? "",
style: TextStyle(
color: order.isSelected
? Colors.white
: Colors.black),
)),
),
),
),
],
)
],
)),
),
);
}),
),
);
}
}
class CommodityModel {
int? commodityID;
String? commodityName;
String? commodityImage;
bool isSelected =
false; // Add key for selection handle. You can also handle with single orderID Array
CommodityModel({this.commodityID, this.commodityName, this.commodityImage});
CommodityModel.fromJson(Map<String, dynamic> json) {
commodityID = json['commodityID'];
commodityName = json['commodityName'];
commodityImage = json['commodityImage'];
isSelected = json['isSelected'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['commodityID'] = commodityID;
data['commodityName'] = commodityName;
data['commodityImage'] = commodityImage;
data['isSelected'] = isSelected;
return data;
}
}
Я получаю allCommodityList из API сервера, поэтому isSelected нет.
Это локальный ключ, добавленный для обработки select и d-select для нас. его легко обрабатывать вместо использования новой переменной массива.
Попробуйте переопределить == и hashCode в своем модальном классе. Или вы можете использовать пакет equatable для того же самого. contains работает лучше всего, когда свойства равенства реализованы в классе.
Вот хороший ресурс: stackoverflow.com/a/22999113/16569443
Предоставьте ключ каждой чернильнице. Что-то вроде ValueKey(order.id).