Untitled
unknown
plain_text
a year ago
4.3 kB
4
Indexable
import 'package:flutter/cupertino.dart'; import '../../classes/event_class.dart'; import '../../constants.dart'; import '../../db/database.dart'; class PlantTypesList extends StatelessWidget { const PlantTypesList({super.key}); AppDatabase get database => AppDatabase.instance; @override Widget build(BuildContext context) { // To continously listen to database content, it's necessary to use [StreamBuilder] // Stream is the function that watches [PlantTypes] table return StreamBuilder( stream: database.watchPlantTypes(), builder: ((context, snapshot) { // Snapshot data (a list of [PlantType]) are marked as 'plantTypes' final plantTypes = snapshot.data; if (plantTypes != null && plantTypes.isNotEmpty) { // The ListView builder uses a plantType, which is a single row from the snapshot, // and the 'index' paramether is needed to adress the proper query return ListView.builder( itemCount: plantTypes.length, itemBuilder: (context, index) { final plantType = plantTypes[index]; // Single record is passed to the [PlantTypeTile] widget as 'plantType' return PlantTypeTile(plantType: plantType); }, ); // Null-safety check } else { return noRecordsDisplay; } }), ); } } // ======================================================================= // [PlantTypeTile] is the building block of PlantTypeList. PlantTypes are // fetched from the database and forwarded to the widget as 'plantType' class PlantTypeTile extends StatelessWidget { final PlantType plantType; const PlantTypeTile({ super.key, required this.plantType }); @override Widget build(BuildContext context) { // Events declaration - [EventType] is needed to determine which map should // be used in order to get the proper [Frequency] attributes (label, days) Event wateringEvent = Event( plantType: plantType, eventType: EventType.watering ); Event fertilizingEvent = Event( plantType: plantType, eventType: EventType.fertilizing ); // Due to the need of converting db records to displayed values, there's a need of // using [FutureBuilder] - its results are stored as snapshot return FutureBuilder<List<EventInfo>>( // Functions that have to be done before build method is evoked future: Future.wait([ getEventInfo(wateringEvent, 'Watering'), getEventInfo(fertilizingEvent, 'Fertilizing'), ]), // Build method builder: (context, snapshot) { // Async snapshot handler if (snapshot.connectionState == ConnectionState.waiting) { return const CupertinoActivityIndicator(); } else if (snapshot.hasError) { return Text('Error: ${snapshot.error}'); // Build method if the snapshot is correct } else if (snapshot.hasData) { EventInfo wateringInfo = snapshot.data![0]; EventInfo fertilizingInfo = snapshot.data![1]; return CupertinoListTile.notched( title: Text(plantType.name), subtitle: FrequenciesInfoDisplay([ wateringInfo.description, fertilizingInfo.description ]) ); // Null-safety check } else { return noRecordsDisplay; } }, ); } } // ======================================================================= // Widget used to display descriptions (excluded to keep the code clean); it has // a positional parameter, that's a list of <Strings> class FrequenciesInfoDisplay extends StatelessWidget { final List<String> descriptions; const FrequenciesInfoDisplay(this.descriptions, {super.key}); @override Widget build(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: descriptions // Each child (labeled as 'description') is wrapped inside [Padding] // to ensure the right amount of space .map((description) => Padding( padding: const EdgeInsets.only(bottom: 5), child: Text(description), )) .toList(), ); } }
Editor is loading...