Thinking & coding: a new screen, EventDetailScreen.
In this programming session I am going to write the 'EventDetailScreen'. It will become a page showing all the info of the chosen event.
In the 'EventCard' there is an 'InfoButton'. It is this button that will navigate the user to the detail screen.
Lets start the journey.
First I create a new Dart file in the project tree, the 'event_detail_screen.dart'. The class in this library will be named 'EventDetailScreen'.
Then i largely build the UI of this new screen. That is all a bit of piecing and measuring, but in general, straightforward. The finishing touch will come later. Now its about the data handling.
Now that I have some screen layout, I will try to link the data to this EventDetailScreen. My big question is, if I press the info button of an event card in the list of events, how do I get the correct details of the correct event in my detail screen.
I'm going to fix the navigation first. When I push the info button, that I can go to the detail screen anyway and back again, it seems just as easy to me hahaha.
After reading the documentation from Hooks and writing several tests in my app, I found the following method.
The eventScreen is a HookWidget. This uses a useProvider and a StreamBuilder so that the data of the Stream is given document by document to the list of EventCards. This is done on the basis of variables that can be addressed. The next step is to also make variables accessible in the EvenDetailScreen. Finally, in the Navigator, we are going to equate the data variables of the EventCard with the variables of the EventDetailScreen. Don't forget that this is only possible if you also make the EventDetailScreen a HookWidget. That's the beauty of Hooks now. Saves a lot of writing code.
Everything works as planned, but I still needed a whole programming session here, and some extra time. A coding session for me is 4 hours and I needed 5 hours for this. Until all mistakes and exeptions were gone.
Below you will find the code I wrote. The hilite lines are the main in linking the data between the EventScreen, the EventCard and the EventDetailScreen.
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, ), ); }, ), ); }) ], ), ), ), ); } } |
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 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | import 'package:flutter/material.dart'; import 'package:my_first_production/owner_data/owner_data.dart'; import 'package:my_first_production/owner_data/style.dart'; import '../event_detail_screen.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), //#TODO implement the correct Icon color: colorPalletDarkButAndText, onPressed: () { Navigator.of(context).push( MaterialPageRoute( builder: (context) => EventDetailScreen( eventDetailScreenTitle: titleCard, eventDetailScreenDate: dateCard, eventDetailScreenText: discriptionCard, ), ), ); }) ], ), 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( //#TODO replace the testimage with the imageCard 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), ), ), ], ), ), ], ), ), ), ); } } |
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 | import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:my_first_production/owner_data/owner_data.dart'; import 'package:my_first_production/owner_data/style.dart'; class EventDetailScreen extends HookWidget { final String eventDetailScreenTitle; final String eventDetailScreenSubTitle; final String eventDetailScreenDate; final String eventDetailScreenText; final String eventDetailScreenImage; const EventDetailScreen( {this.eventDetailScreenTitle, this.eventDetailScreenSubTitle, this.eventDetailScreenDate, this.eventDetailScreenText, this.eventDetailScreenImage}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(), body: Column( children: [ Expanded( flex: 1, child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ Container( constraints: BoxConstraints( maxWidth: MediaQuery.of(context).size.width * 0.95, ), decoration: BoxDecoration( boxShadow: [ BoxShadow( color: Colors.grey, offset: Offset(-4, -4), blurRadius: 8, ) ], //#TODO change testimage with eventDetailScreenImage image: DecorationImage( image: AssetImage(testImage), fit: BoxFit.cover), borderRadius: BorderRadius.only( topLeft: Radius.circular(200.0), bottomRight: Radius.circular(200.0), bottomLeft: Radius.circular(30.0)), ), ), ], ), ), Expanded( flex: 1, child: Container( //color: Colors.red, width: MediaQuery.of(context).size.width * 0.95, child: Padding( padding: const EdgeInsets.fromLTRB(20.0, 10.0, 8.0, 8.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( height: 5.0, ), Text( eventDetailScreenTitle, style: SubTitle1TextStyle, ), SizedBox( height: 10.0, ), Text( eventDetailScreenDate, style: SubTitle2TextStyle, ), SizedBox( height: 20.0, ), Text( eventDetailScreenText, style: BodyText1TextStyle, ), ], ), ), ), ) ], ), ); } } |
So I hope that you can follow my thinking process and the coding.
The EventDetailScreen looks like this on the moment.
Next time I clean up the UI and the code.
CU all next time and dont forget to leave a comment, Thank you
Do, believe and be happy,
Stefaan
Thanks to Andy Julow
Comments
Post a Comment