Advanced Widgets in Flutter
ChoiceChip
return Scaffold(
appBar: AppBar(
leading: Image.network('${dotenv.env['API_URL']}/trek.png'),
title: Row(
children: _categories.map((Category item) => ChoiceChip(
label: Text(item.name),
avatar: Image.network('${dotenv.env["API_URL"]}/categories/${item.icon}', width: 64),
selected: _categoryId != null && _categoryId == item.id,
onSelected: (value) {
setState(() {
_categoryId = value ? item.id : null;
});
_loadData();
_loadBikes();
},
)).toList(),
),
)
);
FilterChip
final Set<int> _selected = <int>{};
return Scaffold(
body: Column(
children: [
Wrap(
spacing: 4,
runSpacing: 4,
children: _subCategories.map((SubCategory item) {
return FilterChip(
label: Text(item.name),
avatar: Image.network('$_url/subcategories/${item.imageUrl}', width: 64),
selected: _selected.contains(item.id),
onSelected: (val) {
setState(() {
if (val) {
_selected.add(item.id);
} else {
_selected.remove(item.id);
}
_loadBikes();
});
},
);
}).toList(),
)
)
)
);
GridView
return Scaffold(
body: Column(
children: [
Expanded(
child: GridView.builder(
itemCount: _bikes.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
itemBuilder: (context, index) {
Bike bike = _bikes[index];
return Column(
children: [
Text(bike.name),
Image.network('${dotenv.env['API_URL']}/bikes/${bike.imageUrl}', fit: BoxFit.contain),
Text('Price: ${bike.price}'),
Expanded(
child: ElevatedButton.icon(
onPressed: () => _details(bike),
label: Text('Details'),
icon: Icon(Icons.details),
),
),
],
);
},
),
),
]
)
)
AlertDialog
void _details(Bike item) async {
var result = await showDialog(
context: context,
builder: (context) {
return AlertDialog(
icon: Image.network('$_url/bikes/${item.imageUrl}', width: 128),
title: Text(item.name),
content: Table(
children: [
TableRow(children: [Text('Price'), Text(item.price.toString())]),
if (item.brakes != null)
TableRow(children: [Text('Brakes'), Text(item.brakes!)]),
if (item.fork != null)
TableRow(children: [Text('Fork'), Text(item.fork!)]),
if (item.wheels != null)
TableRow(children: [Text('Wheels'), Text(item.wheels!)]),
if (item.drivetrain != null)
TableRow(
children: [Text('Drivetrain'), Text(item.drivetrain!)],
),
if (item.frame != null)
TableRow(children: [Text('Frame'), Text(item.frame!)]),
if (item.tires != null)
TableRow(children: [Text('Tires'), Text(item.tires!)]),
],
),
actions: [
ElevatedButton.icon(
onPressed: () => _addToCart(item),
label: Text('Add to Cart'),
icon: Icon(Icons.shopping_bag),
),
ElevatedButton.icon(
onPressed: _cancel,
label: Text('Cancel'),
icon: Icon(Icons.cancel),
),
],
);
},
);
}
void _cancel() {
Navigator.pop(context, false);
}
void _addToCart(Bike obj) async {
String? token = await SessionHelper.token;
if (token != null) {
try {
int ret = await CartRepository.add(
Cart(
memberId: null,
bikeId: obj.id,
quantity: 1,
bikeName: null,
imageUrl: null,
price: null,
),
token,
);
if (!mounted) return;
if (ret > 0) {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('Add to Cart Success')));
Navigator.pop(context, true);
} else {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('Add to Cart Failed $ret')));
}
} catch (ex) {
debugPrint(ex.toString());
}
} else {
if (!mounted) return;
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('Please login')));
}
}