Thinking & coding: Implementing the UI EventCard.
Deploying my EventCard.
After the last code session I got the StreamProvider of the Riverpod package up and running. And also be able to display the data from the backend using ListTile Widget, in the ListView.builder. And all this to test whether the code works so far. This includes the FirestoreFirebase service, the EventModel and the StreamProvider.
Now I am going to replace the ListTile with the EventCard I wrote earlier. Let's see what problems we will encounter with this action.
Normally, all of this should go pretty smoothly. Finally I bring the EventCard in the existing widget tree where the provider makes the data in stock. We will see.
First and foremost, I modified the EventCard Widget. When we implement the EventCard, we have to create a possibility to access the variables. So we declare the necessary variables and build a named constructor. Code lines 5 - 17
Then I entered my variables in the UI code. Code lines 42, 49, 72 have been changed and later we will also replace the testImage on line 89.
The error I kept getting was when inserting the variable subTitleCard.
The exeption message basically stated that I assigned a Null to a Text Widget and that is of course not allowed. I have then followed the entire data line. From the subTitleCard variable in the EventCard to the backend. And there appeared to be a writing error in the name of the data element. Instead of eventSubTitle, it said eventSubtitle. So the backend gave a Null because the data element supposedly did not exist. The compiler found the EventCard to be the culprit because the passed Null was placed here in a Text Widget. This mistake took me about 30 minutes. Learned a good lesson. I can't type fast so I shouldn't try it either hahaha.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | import 'package:flutter/material.dart'; import 'package:my_first_production/owner_data/owner_data.dart'; import 'package:my_first_production/owner_data/style.dart'; class EventCard extends StatelessWidget { final String titleCard; final String subTitleCard; final String dateCard; final String discriptionCard; final String imageCard; EventCard( {this.titleCard, this.dateCard, this.subTitleCard, this.discriptionCard, this.imageCard}); @override Widget build(BuildContext context) { return Center( child: Container( //the transparant card with border height: 190.0, width: 280.0, decoration: BoxDecoration( color: Colors.transparent, borderRadius: BorderRadius.circular(50.0), border: Border.all( color: colorPalletDark, width: 3.0, ),), child: Padding( //aligning the left side in the card padding: const EdgeInsets.only(left: 12.0), child: Column( mainAxisAlignment: MainAxisAlignment.start, children: [ SizedBox(height: 2.0), Text( titleCard, style: CardTitleTextStyle, ), SizedBox( height: 15.0, ), Row( children: [ Text(dateCard, style: CardTextStyle), SizedBox( width: 70.0, ), IconButton( icon: Icon(Icons.perm_device_info), color: colorPalletDarkButAndText, onPressed: () {} ) ], ), SizedBox( height: 2.0, ), Expanded( //use expanded to solve overflow child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( margin: EdgeInsets.only(top: 5.00), height: 70.0, width: 145.0, child: Text(subTitleCard , style: CardTextStyle)), SizedBox( width: 7.0, height: 80.0, ), Container( height: 120.0, width: 110.0, decoration: BoxDecoration( boxShadow: [ BoxShadow( blurRadius: 5.0, color: Colors.grey, offset: Offset(-2.0, -2.0), ) ], image: DecorationImage( image: AssetImage(testImage), fit: BoxFit.none), borderRadius: BorderRadius.only( topLeft: Radius.circular(50.0), bottomRight: Radius.circular(47.0)), //border: Border.all(color: Colors.blueAccent, width: 2.0), ), ), ], ), ), ], ), ), ), ); } } |
I also replaced the Icon in the EventCard with an Icon button. This is a bit easier to navigate to the EventDetailScreen later.
Not to forget, I also adjusted the code in the EvenScreen to be able to address the variables of the EventCard. And you can see that in the code below, in Code lines 56 -61.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/all.dart'; import 'package:my_first_production/models/event_model.dart'; import 'package:my_first_production/owner_data/owner_data.dart'; import 'package:my_first_production/providers/event_provider.dart'; import 'package:my_first_production/screens/screen%20widgets/event_card.dart'; class EventScreen extends HookWidget { const EventScreen({Key key}) : super(key: key); @override Widget build(BuildContext context) { Stream<List<Events>> lijstjes = useProvider(eventProvider.stream); return Container( decoration: BoxDecoration( //color: Colors.white, image: DecorationImage( image: AssetImage(eventScreenBackground), fit: BoxFit.fitWidth), ), child: SafeArea( child: Scaffold( backgroundColor: Colors.transparent, body: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox(height: 30.0), Container( padding: const EdgeInsets.only( left: 80.0), child: Text( eventScreenTitle, style: Theme.of(context).textTheme.headline1, ), ), SizedBox(height: 20.0,), StreamBuilder<List<Events>>( stream: lijstjes, builder: (BuildContext context, AsyncSnapshot<List<Events>> snapshot) { if (snapshot.hasError) { return Text('Something went wrong'); } if (snapshot.connectionState == ConnectionState.waiting) { return Text("Loading"); } return Expanded( child: ListView.builder( itemCount: snapshot.data.length, itemBuilder: (context, index) { return Padding( padding: const EdgeInsets.all(8.0), child: EventCard( titleCard: snapshot.data[index].eventTitle, subTitleCard: snapshot.data[index].eventSubTitle, dateCard: snapshot.data[index].eventDate, discriptionCard: snapshot.data[index].eventText, imageCard: snapshot.data[index].eventImage, ), ); }, ), ); }) ], ), ), ), ); } } |
Self full of disbelief but everything works. Yoohoo !!
After all this I cleaned up the code as a final step, which I always do. This way everything is always neat to start the next session.
Next time I'm going to start building the EventDetailScreen. That is the screen you will get when you push the IconButton in the EventCard via the EventList in the EventScreen. Then you will receive detailed information about the relevant event.
I would like to hear all comments in the comment section. Thank you in advance.
Until the next
Do, believe and be happy,
Stefaan.
Sometimes the smallest errors cost us the most time :) great improvement. Congratulations!
ReplyDeleteThank you sir or ma'm. For reading my article and taking the time to leave a comment. I'm very greatful.
Delete