flutter pub add google_fonts
flutter pub add uuid
Adding a Place Model
// place.dart
import 'package:uuid/uuid.dart';
const uuid = Uuid();
class Place {
Place({required this.title}) : id = uuid.v4();
final String id;
final String title;
}
Places Screen
// places.dart
import 'package:favorite_places_app/screens/add_place.dart';
import 'package:favorite_places_app/widgets/Places_list.dart';
import 'package:flutter/material.dart';
class PlacesScreen extends StatelessWidget {
const PlacesScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Your Places'), actions: [
IconButton(
icon: const Icon(Icons.add),
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (ctx) => const AddPlaceScreen(),
),
);
},
),
]),
body: PlacesList(
places: [],
),
);
}
}
Add Place Screen
// add_place.dart
import 'package:flutter/material.dart';
class AddPlaceScreen extends StatefulWidget {
const AddPlaceScreen({super.key});
@override
State<AddPlaceScreen> createState() {
return _AddPlaceScreenState();
}
}
class _AddPlaceScreenState extends State<AddPlaceScreen> {
final _titleController = TextEditingController();
@override
void dispose() {
_titleController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Add new Place'),
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(12),
child: Column(
children: [
TextField(
decoration: const InputDecoration(labelText: 'Title'),
controller: _titleController,
style: TextStyle(
color: Theme.of(context).colorScheme.onBackground,
),
),
const SizedBox(
height: 16,
),
ElevatedButton.icon(
onPressed: () {},
icon: const Icon(Icons.add),
label: const Text('Add Place'),
)
],
),
),
);
}
}
Add Riverpod & a Provider
flutter pub add flutter_riverpod
// user_places.dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:favorite_places_app/models/place.dart';
****class **UserPlacesNotifier** extends **StateNotifier**<List<Place>> {
UserPlacesNotifier() : super(const []); // initial state []
void addPlace(String title) {
final newPlace = Place(title: title);
state = [
newPlace,
...state,
];
}
}
final userPlacesProvider = **StateNotifierProvider**(
(ref) => **UserPlacesNotifier**(),
);
// main.dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
...
void main() {
runApp(
const **ProviderScope**(
child: MyApp(),
),
);
}
...
Adding Places with Provider & Displaying Places
Through ref after changing to ConsumerStatefulWidget and ConsumerState,
Accessible to riverpod provider to use method and so on.
use riverpod provider data!
To let flutter know the type to be yield..!!
Adding a Place Details Screen
// place_detail.dart
import 'package:flutter/material.dart';
import 'package:favorite_places_app/models/place.dart';
class PlaceDetailScreen extends StatelessWidget {
const PlaceDetailScreen({super.key, required this.place});
final Place place;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(place.title),
),
body: Center(
child: Text(
place.title,
style: Theme.of(context).textTheme.bodyLarge!.copyWith(
color: Theme.of(context).colorScheme.onBackground,
),
),
),
);
}
}
// places_list.dart
...
return ListView.builder(
itemCount: places.length,
itemBuilder: (ctx, index) => ListTile(
title: Text(
places[index].title,
style: Theme.of(context).textTheme.titleMedium!.copyWith(
color: Theme.of(context).colorScheme.onBackground,
),
),
**onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (ctx) => PlaceDetailScreen(
place: places[index],
),
),
);
},**
),
);