Mini Project

Profile page

container

This is profile page and if you click one of profile card, it will move to about page.

main.dart

import 'package:flutter/material.dart';
import './pages/profile.dart';

void main() => runApp(HomeApp());

class HomeApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'appTitle',
      theme: ThemeData(fontFamily: 'Ubuntu'),
      home: Profile(),
    );
  }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  • Line 2 code : import profile.dart file
  • Line 12 code : declare profile class object into home aread within material app widget

profile.dart

import 'package:flutter/material.dart';
import './about_page.dart';
import '../../component/cardWidget.dart';

class Profile extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.deepOrange,
        appBar: AppBar(
          backgroundColor: Colors.deepOrange,
          title: Text('Profile'),
        ),
        body: SafeArea(
          child: Padding(
            padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 5),
            child: Column(
              children: <Widget>[
                GestureDetector(
                  onTap: () {
                    Navigator.push(
                      context,
                      MaterialPageRoute(builder: (context) => AboutPage()),
                    );
                  },
                  child: CardWidget(
                    profileImage: 'assets/kevin.jpg',
                    name: 'Kevin',
                    job: 'Minions',
                  ),
                ),
                GestureDetector(
                  onTap: null,
                  child: CardWidget(
                    profileImage: 'assets/buzz.jpg',
                    name: 'Buzz',
                    job: 'Toy Story',
                  ),
                ),
                GestureDetector(
                  onTap: null,
                  child: CardWidget(
                    profileImage: 'assets/woody.jpg',
                    name: 'Woody',
                    job: 'Toy Story',
                  ),
                ),
                GestureDetector(
                  onTap: null,
                  child: CardWidget(
                    profileImage: 'assets/alien.jpg',
                    name: 'Alien',
                    job: 'Toy Story',
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

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
  • Line 3 code : I made cardWidget object as separate dart file. and import it.
  • Line 15 code : SafeArea is a widget that make boundary within clear area for user's viewpoint.
  • Line 20 code : Gesture Detector is creating "tap interaction" on that widget
  • Line 28 - 30 code : Inject object variable value into cardWidget object.

cardWidget.dart

I make cardWidget.dart within component folder.

import 'package:flutter/material.dart';

class CardWidget extends StatelessWidget {
  CardWidget({this.profileImage, this.name, this.job});
  final profileImage;
  final name;
  final job;
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Card(
        margin: EdgeInsets.symmetric(vertical: 10, horizontal: 10),
        child: Padding(
          padding: const EdgeInsets.all(10.0),
          child: Row(
            children: <Widget>[
              CircleAvatar(
                radius: 25,
                backgroundColor: Colors.indigo,
                backgroundImage: AssetImage(profileImage),
              ),
              Padding(
                padding: const EdgeInsets.only(left: 18.0),
                child: Text(
                  name,
                  style: TextStyle(
                    fontFamily: 'Ubuntu',
                    fontSize: 20,
                    color: Colors.deepOrange,
                  ),
                ),
              ),
              Expanded(child: SizedBox()),
              Container(
                child: Text(job),
              )
            ],
          ),
        ),
      ),
    );
  }
}

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
  • Line 5 - 7 code : Define object variable for cardWidget object.
  • Line 11 code : Card widget is defined by Material design. It has rounded corner and shadow. Card flutter API docs
  • Line 17 code : CircleAvatar is a circular shape of profile image

about_page.dart

import 'package:flutter/material.dart';

class AboutPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.blue,
      body: SafeArea(
        child: Column(
          children: <Widget>[
            IconButton(
              color: Colors.white,
              icon: Icon(Icons.close),
              tooltip: 'close',
              onPressed: () {
                Navigator.of(context).pop();
              },
            ),
            Padding(
              padding: const EdgeInsets.all(28.0),
              child: CircleAvatar(
                radius: 50,
                backgroundColor: Colors.indigo,
                backgroundImage: AssetImage('assets/img/kevin.jpg'),
              ),
            ),
            Text(
              "Kevin",
              style: TextStyle(
                fontFamily: 'Ubuntu',
                fontSize: 33,
                color: Colors.white,
              ),
            ),
            SizedBox(height: 10),
            Text(
              "Minions",
              style: TextStyle(
                fontFamily: 'Ubuntu',
                fontSize: 15,
                color: Colors.white,
              ),
            ),
            SizedBox(
              height: 40,
              width: 200,
              child: Divider(
                color: Colors.white,
              ),
            ),
            Container(
              padding: EdgeInsets.all(25),
              child: Text(
                "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting,remaining essentially unchanged. It was popularised in the 1960s with the release  ",
                style: TextStyle(
                  fontSize: 17,
                  color: Colors.white,
                  height: 1.3,
                ),
              ),
            ),
            Container(
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(10),
                color: Colors.white,
              ),
              margin: EdgeInsets.symmetric(horizontal: 20),
              width: double.infinity,
              child: FlatButton(
                onPressed: null,
                child: Text(
                  'Contact',
                  style: TextStyle(color: Colors.blue, fontSize: 15),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

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
  • Line 16 code : pop method is basically 'back' to previous screen that is stacked.
  • Line 35 code : SizedBox is spacing between widget. height is value of that spacing.
  • Line 63 - 65 code : decoration properties for 'contact' button
  • Line 68 code : expand container to full width of device

Random Dice Game

container

This is random dice game by tapping on it. By tapping it, dice picture is randomly changed from 1 to 6 dice. Total number of dice will be calculated by A + B

  • Let's create dice image file from 1 to 6. and name it like "dice1.png" and put it into "asset" folder.
  • Create "dice.dart" under pages folder. This will be StatefulWidget

main.dart

import 'package:flutter/material.dart';
import './pages/dice.dart';

void main() => runApp(HomeApp());

class HomeApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'appTitle',
      theme: ThemeData(fontFamily: 'Ubuntu'),
      home: Dice(),
    );
  }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  • Line 12 code : bring Dice() widget into home widget.

dice.dart

import 'package:flutter/material.dart';
import 'dart:math';

class Dice extends StatefulWidget {
  @override
  _DiceState createState() => _DiceState();
}

class _DiceState extends State<Dice> {
  int leftDiceNumber = 1;
  int rightDiceNumber = 1;
  int totalDiceNumber = 0;

  void changeLeftDice() {
    setState(() {
      leftDiceNumber = Random().nextInt(6) + 1;
      totalDiceNumber = leftDiceNumber + rightDiceNumber;
    });
  }

  void changeRightDice() {
    setState(() {
      rightDiceNumber = Random().nextInt(6) + 1;
      totalDiceNumber = leftDiceNumber + rightDiceNumber;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.red,
        appBar: AppBar(
          title: Text('Dice'),
          backgroundColor: Colors.red,
        ),
        body: Column(
          children: <Widget>[
            Padding(
              padding: const EdgeInsets.all(18.0),
              child: Container(
                child: Text(
                  'Total Dice number is $totalDiceNumber',
                  style: TextStyle(fontSize: 20, color: Colors.white),
                ),
              ),
            ),
            SizedBox(
              height: 20,
            ),
            Row(
              children: <Widget>[
                Container(
                  child: Expanded(
                    child: Padding(
                      padding: const EdgeInsets.all(10.0),
                      child: FlatButton(
                        onPressed: () {
                          changeLeftDice();
                        },
                        child: Image.asset('assets/dice$leftDiceNumber.png'),
                      ),
                    ),
                  ),
                ),
                Container(
                  child: Expanded(
                    child: Padding(
                      padding: const EdgeInsets.all(10.0),
                      child: FlatButton(
                        onPressed: () {
                          changeRightDice();
                        },
                        child: Image.asset('assets/dice$rightDiceNumber.png'),
                      ),
                    ),
                  ),
                ),
              ],
            ),
            Row(
              children: <Widget>[
                Container(
                  padding: EdgeInsets.only(left: 80),
                  child: Text(
                    'A',
                    style: TextStyle(color: Colors.white, fontSize: 20),
                  ),
                ),
                Container(
                  padding: EdgeInsets.only(left: 180),
                  child: Text(
                    'B',
                    style: TextStyle(color: Colors.white, fontSize: 20),
                  ),
                ),
              ],
            )
          ],
        ),
      ),
    );
  }
}

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
  • Line 2 code : To make random dice, we need math package to generate random number.
  • Line 4 code : dice will be changed by its state (1 to 6) let's make statefulWidget to handle it.
  • Line 9 code : Dice State Widget "_DiceState"
  • Line 10 - 12 code : initiate variable for dice.
  • Line 14 - 18 code : this is method for changing dice number and by using "setState", you can update dice state.
  • Line 33 - 35 code : Appbar widget
  • Line 58 - 60 code : call method "ChangeLeftDice()"
  • Line 81 - 95 code : Label A, Label B

Profile info with TabBar

container

In this mini project, i made profile info page with tabBar Widget. User can navigate 3 different sections of information.

main.dart

import 'package:flutter/material.dart';
import './pages/about_tab.dart';

void main() => runApp(HomeApp());

class HomeApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'appTitle',
      theme: ThemeData(fontFamily: 'Ubuntu'),
      home: AboutTab(),
    );
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

about_tab.dart

import 'package:flutter/material.dart';

class AboutTab extends StatefulWidget {
  @override
  _AboutTabState createState() => _AboutTabState();
}

class _AboutTabState extends State<AboutTab>
    with SingleTickerProviderStateMixin {
  TabController _tabController;

  @override
  void initState() {
    _tabController = new TabController(length: 3, vsync: this);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.blue,
      body: SafeArea(
        child: Column(
          children: <Widget>[
            Padding(
              padding: const EdgeInsets.all(28.0),
              child: CircleAvatar(
                radius: 50,
                backgroundColor: Colors.indigo,
                backgroundImage: AssetImage('assets/img/kevin.jpg'),
              ),
            ),
            Text(
              "Kevin",
              style: TextStyle(
                fontFamily: 'Ubuntu',
                fontSize: 33,
                color: Colors.white,
              ),
            ),
            SizedBox(height: 10),
            Text(
              "Minions",
              style: TextStyle(
                fontFamily: 'Ubuntu',
                fontSize: 15,
                color: Colors.white,
              ),
            ),
            SizedBox(
              height: 40,
              width: 200,
              child: Divider(
                color: Colors.white,
              ),
            ),
            Container(
              child: DefaultTabController(
                length: 3,
                child: Column(
                  children: <Widget>[
                    Container(
                      child: TabBar(
                        tabs: [
                          Tab(icon: Icon(Icons.collections_bookmark)),
                          Tab(icon: Icon(Icons.card_membership)),
                          Tab(icon: Icon(Icons.youtube_searched_for)),
                        ],
                        controller: _tabController,
                      ),
                    ),
                  ],
                ),
              ),
            ),
            Flexible(
              child: Padding(
                padding: const EdgeInsets.all(28.0),
                child: TabBarView(
                  children: [
                    new Text(
                      "TAB 1 -------- Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting,remaining essentially unchanged. It was popularised in the 1960s with the release",
                      style: TextStyle(
                          fontSize: 17, color: Colors.white, height: 1.3),
                    ),
                    new Text(
                      "TAB 2 -------- Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting,remaining essentially unchanged. It was popularised in the 1960s with the release",
                      style: TextStyle(
                          fontSize: 17, color: Colors.white, height: 1.3),
                    ),
                    new Text(
                      "TAB 3 -------- Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting,remaining essentially unchanged. It was popularised in the 1960s with the release",
                      style: TextStyle(
                          fontSize: 17, color: Colors.white, height: 1.3),
                    ),
                  ],
                  controller: _tabController,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

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
  • Line 3 - 6 code : Define TabBar state
  • Line 10 code : TabBarController is "Coordinates tab selection between a TabBar and a TabBarView." It is controlled by "index" in the tab array list. Here is more info about it.
  • Line 13 - 16 code : Initialize state of tabBar. and Create "_tabController" object from "TabController" class
  • Line 58 - 75 code : Declare tab UI
  • Line 79 code : Define TabBarView which is a content of Tab.
  • Line 81 - 85 code : This is tab 1