Hello, developers! In this course, we will learn how to improve the user interface (UI) of the Lotto app. In the previous course, we implemented features to generate Lotto numbers and display the results. Now, let’s enhance the UI to improve the user experience further.
1. Project Setup and Existing Code Review
First, let’s take another look at the existing Lotto app project. The existing Lotto app has only basic features like a number generator. When the app is run, randomly generated Lotto numbers are displayed on the screen.
The structure of the existing code is as follows.
import 'package:flutter/material.dart';
import 'dart:math';
void main() => runApp(LottoApp());
class LottoApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Lotto App',
home: LottoHome(),
);
}
}
class LottoHome extends StatefulWidget {
@override
_LottoHomeState createState() => _LottoHomeState();
}
class _LottoHomeState extends State {
List lottoNumbers = [];
void generateNumbers() {
lottoNumbers = List.generate(6, (index) => Random().nextInt(45) + 1)..sort();
setState(() {});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Lotto Number Generator')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Generated Lotto Numbers:',
style: TextStyle(fontSize: 24),
),
SizedBox(height: 20),
Text(
lottoNumbers.join(', '),
style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
),
SizedBox(height: 30),
ElevatedButton(
onPressed: generateNumbers,
child: Text('Generate Numbers'),
),
],
),
),
);
}
}
Now let’s explore various ways to improve the UI.
2. Establishing a UI Improvement Plan
To improve the UI, we can consider the following elements:
- Changing the color scheme
- Adjusting font styles and sizes
- Applying card or grid layouts to make the numbers stand out more
- Improving button design
- Adding animation effects
2.1 Changing the Color Scheme
Using an eye-catching and enjoyable color combination instead of a simple color palette can provide a pleasant experience for users. For example, set a light color for the background and a contrasting dark color for the text.
2.2 Adjusting Font Styles and Sizes
To create a more attractive user experience, various font styles can be applied. Try using more unique fonts than the default one to change the mood of the app. You can easily apply a variety of fonts using Google Fonts.
2.3 Applying Card or Grid Layouts
By outputting Lotto numbers using cards, information can be conveyed more clearly. Additionally, let’s apply a grid layout to arrange the Lotto numbers.
2.4 Improving Button Design
Rather than using the default button, customize a button that includes selectable color combinations and text styles to emphasize button presses more.
2.5 Adding Animation Effects
Adding animation effects to buttons or UI elements can significantly enhance the user experience. Flutter provides various tools to easily implement animations.
3. Implementing UI Improvements
Now, based on the established plan, let’s modify the actual code to enhance the existing Lotto app by correcting certain elements.
3.1 Changing the Color Scheme
First, let’s change the color scheme to increase the contrast between the background and the text. Modify the build
method in the main.dart
file.
class LottoApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Lotto App',
theme: ThemeData(
primarySwatch: Colors.blue,
scaffoldBackgroundColor: Colors.lightBlue[50],
textTheme: TextTheme(
bodyText1: TextStyle(color: Colors.grey[800]),
bodyText2: TextStyle(color: Colors.black),
),
),
home: LottoHome(),
);
}
}
3.2 Adjusting Font Styles and Sizes
Next, let’s change the default text style. We can apply a more attractive font by adding the style
property to the Text
widget.
Text(
'Generated Lotto Numbers:',
style: TextStyle(
fontSize: 28,
fontWeight: FontWeight.bold,
fontFamily: 'Roboto',
),
),
3.3 Applying Grid Layout
We will change the display of Lotto numbers to a grid format. Adding the code below will wrap each number in a card, making it visually appealing.
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
childAspectRatio: 1,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
itemCount: lottoNumbers.length,
itemBuilder: (context, index) {
return Card(
color: Colors.yellowAccent,
child: Center(
child: Text(
lottoNumbers[index].toString(),
style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold),
),
),
);
},
),
3.4 Improving Button Design
To enhance the button design, we will add properties to the ElevatedButton
to change its style.
ElevatedButton(
onPressed: generateNumbers,
style: ElevatedButton.styleFrom(
primary: Colors.blue,
onPrimary: Colors.white,
padding: EdgeInsets.symmetric(horizontal: 25, vertical: 15),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)),
),
child: Text('Generate Numbers', style: TextStyle(fontSize: 20)),
),
3.5 Adding Animation Effects
We will use AnimatedContainer
to apply animation effects when the button is clicked. The animation effect will be activated upon pressing the button.
AnimatedContainer(
duration: Duration(milliseconds: 200),
decoration: BoxDecoration(
color: buttonPressed ? Colors.green : Colors.blue,
borderRadius: BorderRadius.circular(30),
),
child: ElevatedButton(
onPressed: () {
setState(() {
buttonPressed = !buttonPressed;
});
generateNumbers();
},
child: Text('Generate Numbers', style: TextStyle(fontSize: 20)),
),
),
4. Final Code
We will integrate all of the above code to create the final code as follows.
import 'package:flutter/material.dart';
import 'dart:math';
void main() => runApp(LottoApp());
class LottoApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Lotto App',
theme: ThemeData(
primarySwatch: Colors.blue,
scaffoldBackgroundColor: Colors.lightBlue[50],
textTheme: TextTheme(
bodyText1: TextStyle(color: Colors.grey[800]),
bodyText2: TextStyle(color: Colors.black),
),
),
home: LottoHome(),
);
}
}
class LottoHome extends StatefulWidget {
@override
_LottoHomeState createState() => _LottoHomeState();
}
class _LottoHomeState extends State {
List lottoNumbers = [];
bool buttonPressed = false;
void generateNumbers() {
lottoNumbers = List.generate(6, (index) => Random().nextInt(45) + 1)..sort();
setState(() {});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Lotto Number Generator')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Generated Lotto Numbers:', style: TextStyle(fontSize: 28, fontWeight: FontWeight.bold, fontFamily: 'Roboto')),
SizedBox(height: 20),
Expanded(
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
childAspectRatio: 1,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
itemCount: lottoNumbers.length,
itemBuilder: (context, index) {
return Card(
color: Colors.yellowAccent,
child: Center(
child: Text(
lottoNumbers[index].toString(),
style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold),
),
),
);
},
),
),
SizedBox(height: 30),
ElevatedButton(
onPressed: () {
setState(() {
buttonPressed = !buttonPressed;
});
generateNumbers();
},
style: ElevatedButton.styleFrom(
primary: Colors.blue,
onPrimary: Colors.white,
padding: EdgeInsets.symmetric(horizontal: 25, vertical: 15),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)),
),
child: Text('Generate Numbers', style: TextStyle(fontSize: 20)),
),
],
),
),
);
}
}
5. Conclusion and Future Improvement Directions
So far, we have learned how to improve the UI of the Lotto app. By improving the app’s design in various ways, we can enhance the user’s experience. In the future, we can enrich the Lotto app even further by adding additional features, such as visualizing historical data for Lotto numbers or providing a record-keeping function for the numbers generated by the user.
I hope this course has been helpful to developers like you, and I look forward to bringing you another topic in the next course. Thank you for reading to the end!