Flutter
Tutorials
- Basics: https://www.youtube.com/watch?v=1xipg02Wu8s
- REST API: https://www.youtube.com/watch?v=c09XiwOZKsI
- https://www.youtube.com/watch?v=ncEuhsq4KAg
Product Details
- Part 1: https://www.youtube.com/watch?v=cdPG0ETbC-c
- Part 2: https://www.youtube.com/watch?v=R4TNm9dLr9k
Clickable List με Navigation
Το Flutter παρέχει έναν απλό τρόπο για να δημιουργήσεις μια clickable λίστα (π.χ. προϊόντα) που πλοηγεί σε detail view με tap, χρησιμοποιώντας ListView.builder και Navigator.push. Αυτό το pattern είναι ιδανικό για product catalogs, όπου κάθε list item περνάει data σε μια νέα οθόνη.
Model Class
Ορίζουμε ένα απλό data model για προϊόντα, με name, description και price.
class Product {
final String name;
final String description;
final double price;
const Product(this.name, this.description, this.price);
}
Products List Screen
Χρησιμοποιούμε ListView.builder για εμφάνιση λίστας, με onTap σε κάθε ListTile για πλοήγηση και αποστολή του επιλεγμένου προϊόντος.
class ProductsScreen extends StatelessWidget {
final List<Product> products = List.generate(
20,
(i) => Product(
'Product $i',
'Description for Product $i',
29.99 + i,
),
);
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Products')),
body: ListView.builder(
itemCount: products.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(products[index].name),
subtitle: Text('\$${products[index].price}'),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ProductDetailScreen(product: products[index]),
),
);
},
);
},
),
);
}
}
Πατώντας ένα tile κάνει push ένα νέο route με τα δεδομένα του προϊόντος.
Detail View Screen
Δημιουργούμε μια οθόνη που δέχεται και εμφανίζει τα details του προϊόντος.
class ProductDetailScreen extends StatelessWidget {
final Product product;
const ProductDetailScreen({super.key, required this.product});
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(product.name)),
body: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Price: \$${product.price}', style: Theme.of(context).textTheme.headlineSmall),
const SizedBox(height: 16),
Text(product.description),
],
),
),
);
}
}
Ο constructor δέχεται το product, επιτρέποντας δυναμικό περιεχόμενο. Χρησιμοποίησε pop() στο app bar για επιστροφή.