こんにちは!Dreamwalkerです。
久しぶりに書くことになってしまいました。
今回は12番目の「DribbbleのデザインをFlutterでやってみた」になります。
今回のデザイン
Patryk Polak さんのFitness Activity Trackerというでデザインをやってみたい!と思います。
結果
必要なライブラリー
1.page_transition
2. fl_chart
全てのコード
Activityページ。
main_page.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:notebook_the_third_story/fitness_activity_tracker/static_page.dart';
import 'package:page_transition/page_transition.dart';
class FitnessActivityTracker extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MainPage(),
);
}
}
class MainPage extends StatefulWidget {
@override
_MainPageState createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
body: Stack(
children: <Widget>[
Positioned(
left: 0,
right: 0,
bottom: 100,
top: 0,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 24),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(32),
bottomRight: Radius.circular(32),
)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
icon: Icon(Icons.menu),
onPressed: () {},
),
CircleAvatar(),
],
),
SizedBox(
height: 32,
),
Padding(
padding: const EdgeInsets.only(left: 16),
child: Text(
"Activity",
style: TextStyle(
color: Colors.black,
fontSize: 26,
fontWeight: FontWeight.bold,
),
),
),
SizedBox(
height: 24,
),
Container(
margin: EdgeInsets.only(left: 16, right: 16),
height: MediaQuery.of(context).size.height / 1.65,
child: Column(
children: <Widget>[
Expanded(
flex: 1,
child: Row(
children: <Widget>[
Expanded(
flex: 1,
child: Container(
margin: EdgeInsets.only(right: 8, bottom: 8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
border:
Border.all(color: Colors.grey[300])),
padding: EdgeInsets.only(
left: 24, top: 24, bottom: 24),
child: Column(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
Icon(
Icons.favorite_border,
color: Colors.red,
),
Spacer(),
Text(
"131",
style: TextStyle(
fontSize: 28,
fontWeight: FontWeight.bold,
),
),
Text(
"bpm",
style: TextStyle(
color: Colors.grey,
fontSize: 19,
fontWeight: FontWeight.w300),
),
Spacer(),
Text(
"Heart rate",
style: TextStyle(
fontWeight: FontWeight.bold,
),
)
],
),
),
),
Expanded(
flex: 1,
child: Container(
padding: EdgeInsets.only(
left: 24, top: 24, bottom: 24),
margin: EdgeInsets.only(left: 8, bottom: 8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
border: Border.all(color: Colors.grey[300]),
),
child: Column(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
Icon(
Icons.whatshot,
color: Colors.orange[500],
),
Spacer(),
Text(
"450",
style: TextStyle(
fontSize: 28,
fontWeight: FontWeight.bold,
),
),
Text(
"kcal",
style: TextStyle(
color: Colors.grey,
fontSize: 19,
fontWeight: FontWeight.w300),
),
Spacer(),
Text(
"Calories",
style: TextStyle(
fontWeight: FontWeight.bold,
),
)
],
),
),
),
],
),
),
Expanded(
flex: 1,
child: Row(
children: <Widget>[
Expanded(
flex: 1,
child: Container(
margin: EdgeInsets.only(right: 8, top: 8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
border:
Border.all(color: Colors.grey[300])),
padding: EdgeInsets.only(
left: 24, top: 24, bottom: 24),
child: Column(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
Icon(
Icons.directions_walk,
color: Colors.purple,
),
Spacer(),
Text(
"6551",
style: TextStyle(
fontSize: 28,
fontWeight: FontWeight.bold,
),
),
Text(
"steps",
style: TextStyle(
color: Colors.grey,
fontSize: 19,
fontWeight: FontWeight.w300),
),
Spacer(),
Text(
"Step",
style: TextStyle(
fontWeight: FontWeight.bold,
),
)
],
),
),
),
Expanded(
flex: 1,
child: Container(
margin: EdgeInsets.only(left: 8, top: 8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
border:
Border.all(color: Colors.grey[300])),
padding: EdgeInsets.only(
left: 24, top: 24, bottom: 24),
child: Column(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
Icon(
Icons.local_drink,
color: Colors.blue,
),
Spacer(),
Text(
"4",
style: TextStyle(
fontSize: 28,
fontWeight: FontWeight.bold,
),
),
Text(
"cups",
style: TextStyle(
color: Colors.grey,
fontSize: 19,
fontWeight: FontWeight.w300),
),
Spacer(),
Text(
"Water",
style: TextStyle(
fontWeight: FontWeight.bold,
),
)
],
),
),
),
],
)),
],
),
)
],
),
),
),
Positioned(
left: 0,
right: 0,
bottom: 0,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 24),
height: 80,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"Statistics",
style: TextStyle(
color: Colors.white,
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
IconButton(
icon: Icon(
Icons.keyboard_arrow_up,
),
color: Colors.white,
onPressed: () {
Navigator.of(context).push(PageTransition(
child: StatisticsPage(),
type: PageTransitionType.downToUp));
},
)
],
),
),
)
],
),
);
}
}
Statisticsページ。
static_page.dart
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class StatisticsPage extends StatefulWidget {
@override
_StatisticsPageState createState() => _StatisticsPageState();
}
class _StatisticsPageState extends State<StatisticsPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
SafeArea(
top: true,
left: true,
right: true,
child: Padding(
padding: const EdgeInsets.only(left: 16, right: 16, top: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
onPressed: () {},
icon: Icon(Icons.more_horiz),
),
Text(
"Statistics",
style: TextStyle(
color: Colors.black,
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
IconButton(
icon: Icon(Icons.keyboard_arrow_down),
onPressed: () {
Navigator.of(context).pop();
},
)
],
),
),
),
Padding(
padding: const EdgeInsets.only(top: 42),
child: Container(
padding: EdgeInsets.only(left: 24, top: 48, right: 24),
height: MediaQuery.of(context).size.height - 130,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.only(
topRight: Radius.circular(32),
topLeft: Radius.circular(32),
)),
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"Walk",
style: TextStyle(
color: Colors.white,
fontSize: 28,
fontWeight: FontWeight.bold,
),
),
Spacer(),
Icon(
Icons.calendar_today,
color: Colors.white,
size: 18,
),
SizedBox(
width: 8,
),
Text(
"23 November, 2019",
style: TextStyle(
color: Colors.white,
),
),
],
),
SizedBox(
height: 24,
),
Row(
children: <Widget>[
Container(
height: 28,
width: 70,
decoration: BoxDecoration(
border:
Border.all(color: Colors.white.withOpacity(.2)),
borderRadius: BorderRadius.circular(24)),
child: Center(
child: Text(
"Day",
style: TextStyle(
color: Colors.white,
),
)),
),
SizedBox(
width: 16,
),
Container(
height: 28,
width: 70,
decoration: BoxDecoration(
border: Border.all(),
borderRadius: BorderRadius.circular(24)),
child: Center(
child: Text(
"Week",
style: TextStyle(color: Colors.white.withOpacity(.3)),
)),
),
SizedBox(
width: 16,
),
Container(
height: 28,
width: 70,
decoration: BoxDecoration(
border: Border.all(),
borderRadius: BorderRadius.circular(24)),
child: Center(
child: Text(
"Month",
style: TextStyle(color: Colors.white.withOpacity(.3)),
)),
)
],
),
Container(
height: 200,
child: Column(
children: <Widget>[
Expanded(
flex: 4,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
"6551",
style: TextStyle(
color: Colors.white,
fontSize: 48,
fontWeight: FontWeight.bold,
),
),
SizedBox(
width: 32,
),
Text(
"steps",
style: TextStyle(
color: Colors.white.withOpacity(0.2),
fontSize: 28,
),
)
],
),
),
Expanded(
flex: 2,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"5.1",
style: TextStyle(
color: Colors.white, fontSize: 18),
),
Text(
"distance",
style: TextStyle(
color: Colors.white.withOpacity(0.2)),
)
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"450",
style: TextStyle(
color: Colors.white, fontSize: 18),
),
Text(
"kcal",
style: TextStyle(
color: Colors.white.withOpacity(0.2)),
)
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"13.9km/h",
style: TextStyle(
color: Colors.white, fontSize: 18),
),
Text(
"average speed",
style: TextStyle(
color: Colors.white.withOpacity(0.2)),
)
],
)
],
),
),
],
),
),
Container(
height: 180,
width: MediaQuery.of(context).size.width,
child: BarChart(
BarChartData(
alignment: BarChartAlignment.spaceBetween,
maxY: 20,
titlesData: FlTitlesData(
show: true,
bottomTitles: SideTitles(
showTitles: true,
textStyle: TextStyle(
color: Colors.white, fontSize: 12),
margin: 20,
getTitles: (double value) {
switch (value.toInt()) {
case 0:
return "14";
case 1:
return "";
case 2:
return "16";
case 3:
return "";
case 4:
return "18";
case 5:
return "";
case 6:
return "20";
case 7:
return "";
case 8:
return "22";
default:
return '';
}
}),
leftTitles: const SideTitles(showTitles: false),
),
borderData: FlBorderData(
show: false,
),
barGroups: [
BarChartGroupData(
x: 0,
barRods: [
BarChartRodData(
y: 14, color: Colors.orange[400])
],
),
BarChartGroupData(
x: 1,
barRods: [
BarChartRodData(y: 8, color: Colors.orange[400])
],
),
BarChartGroupData(
x: 2,
barRods: [
BarChartRodData(y: 8, color: Colors.orange[400])
],
),
BarChartGroupData(
x: 3,
barRods: [
BarChartRodData(y: 4, color: Colors.orange[400])
],
),
BarChartGroupData(
x: 4,
barRods: [
BarChartRodData(y: 6, color: Colors.orange[400])
],
),
BarChartGroupData(
x: 5,
barRods: [
BarChartRodData(
y: 18, color: Colors.orange[400])
],
),
BarChartGroupData(
x: 6,
barRods: [
BarChartRodData(
y: 10, color: Colors.orange[400])
],
),
BarChartGroupData(
x: 7,
barRods: [
BarChartRodData(y: 8, color: Colors.orange[400])
],
),
BarChartGroupData(
x: 8,
barRods: [
BarChartRodData(
y: 10, color: Colors.orange[400])
],
),
]),
),
),
Spacer(),
Container(
height: 80,
child: Row(
children: <Widget>[
Container(
height: 60,
width: 52,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(16)),
child: Center(
child: Icon(
Icons.favorite_border,
color: Colors.white,
),
),
),
Spacer(),
Container(
width: 100,
child: Stack(
children: <Widget>[
Positioned(
top: 0,
right: 16,
child: Text("MIN",style: TextStyle(
color: Colors.white,
),),
),
Positioned(
top: 16,
left: 16,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("64",style: TextStyle(
color: Colors.white,
fontSize: 28
),),
Text("bpm",style: TextStyle(
color: Colors.white.withOpacity(0.2),
),)
],
),
)
],
),
),
SizedBox(
width: 24,
),
Container(
width: 100,
child: Stack(
children: <Widget>[
Positioned(
top: 0,
right: 16,
child: Text("MAX",style: TextStyle(
color: Colors.white,
),),
),
Positioned(
top: 16,
left: 16,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("146",style: TextStyle(
color: Colors.white,
fontSize: 28
),),
Text("bpm",style: TextStyle(
color: Colors.white.withOpacity(0.2),
),)
],
),
)
],
),
),
],
),
),
],
),
),
)
],
),
);
}
}
終わりに
今回も読んでくださってありがとうございます。