projet debut
This commit is contained in:
37
my_travel/lib/views/city/city.dart
Normal file
37
my_travel/lib/views/city/city.dart
Normal file
@@ -0,0 +1,37 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../data/data.dart' as data;
|
||||
import '../../models/activity.model.dart';
|
||||
import '../widgets/activity_card.dart';
|
||||
|
||||
class City extends StatefulWidget {
|
||||
final List<Activity> activities = data.activities;
|
||||
City({super.key});
|
||||
@override
|
||||
State<City> createState() => _CityState();
|
||||
}
|
||||
|
||||
class _CityState extends State<City> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: const Icon(Icons.chevron_left),
|
||||
title: const Text('Paris'),
|
||||
actions: const [Icon(Icons.more_vert)],
|
||||
),
|
||||
|
||||
// ==================== GridView.extent (taille max par item) - VERSION ACTIVE ✅ ====================
|
||||
body: Container(
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: GridView.extent(
|
||||
maxCrossAxisExtent: 150, // largeur max d'un item
|
||||
mainAxisSpacing: 2,
|
||||
crossAxisSpacing: 5,
|
||||
children: widget.activities
|
||||
.map((a) => ActivityCard(activity: a))
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
53
my_travel/lib/views/home/home.dart
Normal file
53
my_travel/lib/views/home/home.dart
Normal file
@@ -0,0 +1,53 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../widgets/city_card.dart';
|
||||
|
||||
class Home extends StatefulWidget {
|
||||
const Home({super.key});
|
||||
|
||||
@override
|
||||
State<Home> createState() => _HomeState();
|
||||
}
|
||||
|
||||
class _HomeState extends State<Home> {
|
||||
// Liste "source de vérité" affichée dans l'UI
|
||||
final List<Map<String, dynamic>> cities = [
|
||||
{'name': 'Paris', 'image': 'assets/images/paris.jpg', 'checked': false},
|
||||
{'name': 'Lyon', 'image': 'assets/images/lyon.jpg', 'checked': false},
|
||||
{'name': 'Nice', 'image': 'assets/images/nice.jpg', 'checked': false},
|
||||
];
|
||||
|
||||
// Fonction pour basculer l'état favori d'une ville
|
||||
void switchChecked(Map<String, dynamic> city) {
|
||||
setState(() {
|
||||
city['checked'] = !(city['checked'] ?? false);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: const Icon(Icons.home),
|
||||
title: const Text('DrEvaristen Trip'),
|
||||
actions: const [Icon(Icons.more_vert)],
|
||||
),
|
||||
body: Container(
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
// On transforme chaque map en CityCard
|
||||
children: [
|
||||
for (final city in cities)
|
||||
CityCard(
|
||||
name: city['name'],
|
||||
image: city['image'],
|
||||
checked: city['checked'] ?? false,
|
||||
updateChecked: () =>
|
||||
switchChecked(city), // capture la bonne ville
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
23
my_travel/lib/views/widgets/activity_card.dart
Normal file
23
my_travel/lib/views/widgets/activity_card.dart
Normal file
@@ -0,0 +1,23 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../models/activity.model.dart';
|
||||
|
||||
class ActivityCard extends StatelessWidget {
|
||||
final Activity activity;
|
||||
const ActivityCard({super.key, required this.activity});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListTile(
|
||||
leading: CircleAvatar(backgroundImage: AssetImage(activity.image)),
|
||||
title: Text(activity.name),
|
||||
subtitle: Text(activity.city),
|
||||
trailing: Checkbox(
|
||||
value: true,
|
||||
tristate: true,
|
||||
onChanged: (e) {}, // nécessite un état pour évoluer
|
||||
activeColor: Colors.black,
|
||||
checkColor: Colors.red,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
67
my_travel/lib/views/widgets/city_card.dart
Normal file
67
my_travel/lib/views/widgets/city_card.dart
Normal file
@@ -0,0 +1,67 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class CityCard extends StatelessWidget {
|
||||
final String name;
|
||||
final String image;
|
||||
final bool checked; // devient requis
|
||||
final VoidCallback updateChecked;
|
||||
const CityCard({
|
||||
super.key,
|
||||
required this.name,
|
||||
required this.image,
|
||||
required this.checked,
|
||||
required this.updateChecked,
|
||||
});
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Card(
|
||||
elevation: 5,
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: SizedBox(
|
||||
height: 150,
|
||||
child: Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
Ink.image(
|
||||
image: AssetImage(image),
|
||||
fit: BoxFit.cover,
|
||||
child: InkWell(onTap: updateChecked), // notifie le parent
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: Column(
|
||||
children: [
|
||||
// Icône favori : pleine si checked, sinon contour
|
||||
Expanded(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
checked ? Icons.star : Icons.star_border,
|
||||
size: 30,
|
||||
color: Colors.white,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
name,
|
||||
style: const TextStyle(
|
||||
fontSize: 30,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user