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

Popular posts from this blog

Thinking & coding: Linking Firebase to my Flutter App. Watch out for a important detail.

Software developer yes, but where to begin?

Thinking & coding: the Custom Navigation icons