projet debut

This commit is contained in:
felix-vi
2025-10-14 12:29:11 +02:00
parent c642a6f914
commit 5d1d2f4498
16 changed files with 256 additions and 20 deletions

View File

@@ -1,12 +1,31 @@
import 'package:flutter/material.dart';
void main() {
runApp(
Container(
color: Colors.red,
alignment: Alignment.center,
margin: const EdgeInsets.all(100),
child: const Text("Hello world", textDirection: TextDirection.ltr),
class CardWithImage extends StatelessWidget {
const CardWithImage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Card + Image de fond')),
body: Padding(
padding: const EdgeInsets.all(10),
child: Card(
elevation: 5,
clipBehavior: Clip.antiAlias,
child: SizedBox(
height: 150,
child: Stack(
fit: StackFit.expand, // l'enfant occupe toute la carte
children: [
// Image locale déclarée dans pubspec.yaml
Image.asset(
'assets/images/paris.jpg',
fit: BoxFit.cover, // couvre toute la surface, quitte à rogner
),
],
),
),
),
),
);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

View File

@@ -0,0 +1,29 @@
// lib/data/data.dart
import '../models/activity.model.dart';
List<Activity> activities = [
Activity(
image: 'assets/images/activities/louvre.jpg',
name: 'Le Louvre',
id: 'a1',
city: 'Paris',
),
Activity(
image: 'assets/images/activities/chaumont.jpg',
name: 'Les buttes Chaumont',
id: 'a2',
city: 'Paris',
),
Activity(
image: 'assets/images/activities/dame.jpg',
name: 'Notre Dame',
id: 'a3',
city: 'Paris',
),
Activity(
image: 'assets/images/activities/defense.jpg',
name: 'La Défense',
id: 'a4',
city: 'Paris',
),
];

View File

@@ -1,22 +1,15 @@
import 'package:flutter/material.dart';
import 'views/city/city.dart';
void main() => runApp(const DrEvaristenTrip());
class DrEvaristenTrip extends StatelessWidget {
const DrEvaristenTrip({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
leading: const Icon(Icons.home),
title: const Text('DrEvaristen Trip'),
actions: const <Widget>[Icon(Icons.more_vert)],
),
body: const Text('DrEvaristen'),
),
home: City(), // affichage direct pour développement
);
}
}

View File

@@ -0,0 +1,13 @@
// lib/models/activity.model.dart
class Activity {
String name;
String image;
String? id;
String city;
Activity({
required this.name,
required this.city,
this.id,
required this.image,
});
}

View 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(),
),
),
);
}
}

View 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
),
],
),
),
);
}
}

View 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,
),
);
}
}

View 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,
),
),
],
),
],
),
),
],
),
),
);
}
}

View File

@@ -58,7 +58,9 @@ flutter:
uses-material-design: true
# To add assets to your application, add an assets section, like this:
# assets:
assets:
- assets/images/
- assets/images/activities/
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg