Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
7d033716
Unverified
Commit
7d033716
authored
Nov 05, 2019
by
Shi-Hao Hong
Committed by
GitHub
Nov 05, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Revert "[Gallery] Add Material Study app Rally as an example app (#42236)" (#44194)
This reverts commit
a214b462
.
parent
a214b462
Changes
20
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
1 addition
and
1912 deletions
+1
-1912
all.dart
examples/flutter_gallery/lib/demo/all.dart
+0
-1
app.dart
examples/flutter_gallery/lib/demo/rally/app.dart
+0
-88
line_chart.dart
...les/flutter_gallery/lib/demo/rally/charts/line_chart.dart
+0
-187
pie_chart.dart
...ples/flutter_gallery/lib/demo/rally/charts/pie_chart.dart
+0
-258
vertical_fraction_bar.dart
..._gallery/lib/demo/rally/charts/vertical_fraction_bar.dart
+0
-44
colors.dart
examples/flutter_gallery/lib/demo/rally/colors.dart
+0
-69
data.dart
examples/flutter_gallery/lib/demo/rally/data.dart
+0
-228
finance.dart
examples/flutter_gallery/lib/demo/rally/finance.dart
+0
-330
formatters.dart
examples/flutter_gallery/lib/demo/rally/formatters.dart
+0
-19
home.dart
examples/flutter_gallery/lib/demo/rally/home.dart
+0
-206
login.dart
examples/flutter_gallery/lib/demo/rally/login.dart
+0
-91
main.dart
examples/flutter_gallery/lib/demo/rally/main.dart
+0
-18
accounts.dart
examples/flutter_gallery/lib/demo/rally/tabs/accounts.dart
+0
-36
bills.dart
examples/flutter_gallery/lib/demo/rally/tabs/bills.dart
+0
-42
budgets.dart
examples/flutter_gallery/lib/demo/rally/tabs/budgets.dart
+0
-42
overview.dart
examples/flutter_gallery/lib/demo/rally/tabs/overview.dart
+0
-151
settings.dart
examples/flutter_gallery/lib/demo/rally/tabs/settings.dart
+0
-59
rally_demo.dart
examples/flutter_gallery/lib/demo/rally_demo.dart
+0
-15
demos.dart
examples/flutter_gallery/lib/gallery/demos.dart
+0
-8
pubspec.yaml
examples/flutter_gallery/pubspec.yaml
+1
-20
No files found.
examples/flutter_gallery/lib/demo/all.dart
View file @
7d033716
...
...
@@ -11,7 +11,6 @@ export 'fortnightly/fortnightly.dart';
export
'images_demo.dart'
;
export
'material/material.dart'
;
export
'pesto_demo.dart'
;
export
'rally_demo.dart'
;
export
'shrine_demo.dart'
;
export
'transformations/transformations_demo.dart'
;
export
'typography_demo.dart'
;
...
...
examples/flutter_gallery/lib/demo/rally/app.dart
deleted
100644 → 0
View file @
a214b462
// Copyright 2019-present the Flutter authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import
'package:flutter/material.dart'
;
import
'package:flutter_gallery/demo/rally/colors.dart'
;
import
'package:flutter_gallery/demo/rally/home.dart'
;
import
'package:flutter_gallery/demo/rally/login.dart'
;
/// The RallyApp is a MaterialApp with a theme and 2 routes.
///
/// The home route is the main page with tabs for sub pages.
/// The login route is the initial route.
class
RallyApp
extends
StatelessWidget
{
@override
Widget
build
(
BuildContext
context
)
{
return
MaterialApp
(
title:
'Rally'
,
theme:
_buildRallyTheme
(),
home:
HomePage
(),
initialRoute:
'/login'
,
routes:
<
String
,
WidgetBuilder
>{
'/login'
:
(
BuildContext
context
)
=>
LoginPage
(),
},
);
}
ThemeData
_buildRallyTheme
()
{
final
ThemeData
base
=
ThemeData
.
dark
();
return
ThemeData
(
scaffoldBackgroundColor:
RallyColors
.
primaryBackground
,
primaryColor:
RallyColors
.
primaryBackground
,
textTheme:
_buildRallyTextTheme
(
base
.
textTheme
),
inputDecorationTheme:
InputDecorationTheme
(
labelStyle:
const
TextStyle
(
color:
RallyColors
.
gray
,
fontWeight:
FontWeight
.
w500
,
),
filled:
true
,
fillColor:
RallyColors
.
inputBackground
,
focusedBorder:
InputBorder
.
none
,
),
);
}
TextTheme
_buildRallyTextTheme
(
TextTheme
base
)
{
return
base
.
copyWith
(
body1:
base
.
body1
.
copyWith
(
fontFamily:
'Roboto Condensed'
,
fontSize:
14
,
fontWeight:
FontWeight
.
w400
,
),
body2:
base
.
body2
.
copyWith
(
fontFamily:
'Eczar'
,
fontSize:
40
,
fontWeight:
FontWeight
.
w400
,
letterSpacing:
1.4
,
),
button:
base
.
button
.
copyWith
(
fontFamily:
'Roboto Condensed'
,
fontWeight:
FontWeight
.
w700
,
letterSpacing:
2.8
,
),
headline:
base
.
body2
.
copyWith
(
fontFamily:
'Eczar'
,
fontSize:
40
,
fontWeight:
FontWeight
.
w600
,
letterSpacing:
1.4
,
),
)
.
apply
(
displayColor:
Colors
.
white
,
bodyColor:
Colors
.
white
,
);
}
}
examples/flutter_gallery/lib/demo/rally/charts/line_chart.dart
deleted
100644 → 0
View file @
a214b462
// Copyright 2019-present the Flutter authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import
'package:flutter/material.dart'
;
import
'package:flutter_gallery/demo/rally/colors.dart'
;
import
'package:flutter_gallery/demo/rally/data.dart'
;
class
RallyLineChart
extends
StatelessWidget
{
const
RallyLineChart
({
this
.
events
=
const
<
DetailedEventData
>[]
})
:
assert
(
events
!=
null
);
final
List
<
DetailedEventData
>
events
;
@override
Widget
build
(
BuildContext
context
)
{
return
CustomPaint
(
painter:
RallyLineChartPainter
(
Theme
.
of
(
context
).
textTheme
.
body1
,
events
));
}
}
class
RallyLineChartPainter
extends
CustomPainter
{
RallyLineChartPainter
(
this
.
labelStyle
,
this
.
events
);
final
TextStyle
labelStyle
;
// Events to plot on the line as points.
final
List
<
DetailedEventData
>
events
;
// Number of days to plot.
// This is hardcoded to reflect the dummy data, but would be dynamic in a real
// app.
final
int
numDays
=
52
;
// Beginning of window. The end is this plus numDays.
// This is hardcoded to reflect the dummy data, but would be dynamic in a real
// app.
final
DateTime
startDate
=
DateTime
.
utc
(
2018
,
12
,
1
);
// Ranges uses to lerp the pixel points.
// This is hardcoded to reflect the dummy data, but would be dynamic in a real
// app.
final
double
maxAmount
=
3000
;
// minAmount is assumed to be 0
// The number of milliseconds in a day. This is the inherit period fot the
// points in this line.
static
const
int
millisInDay
=
24
*
60
*
60
*
1000
;
// Amount to shift the tick drawing by so that the Sunday ticks do not start
// on the edge.
final
int
tickShift
=
3
;
// Arbitrary unit of space for absolute positioned painting.
final
double
space
=
16
;
@override
void
paint
(
Canvas
canvas
,
Size
size
)
{
final
double
ticksTop
=
size
.
height
-
space
*
5
;
final
double
labelsTop
=
size
.
height
-
space
*
2
;
_drawLine
(
canvas
,
Rect
.
fromLTWH
(
0
,
0
,
size
.
width
,
ticksTop
),
);
_drawXAxisTicks
(
canvas
,
Rect
.
fromLTWH
(
0
,
ticksTop
,
size
.
width
,
labelsTop
-
ticksTop
),
);
_drawXAxisLabels
(
canvas
,
Rect
.
fromLTWH
(
0
,
labelsTop
,
size
.
width
,
size
.
height
-
labelsTop
),
);
}
// Since we're only using fixed dummy data, we can set this to false. In a
// real app we would have the data as part of the state and repaint when it's
// changed.
@override
bool
shouldRepaint
(
CustomPainter
oldDelegate
)
=>
false
;
void
_drawLine
(
Canvas
canvas
,
Rect
rect
)
{
final
Paint
linePaint
=
Paint
()
..
color
=
RallyColors
.
accountColor
(
2
)
..
style
=
PaintingStyle
.
stroke
..
strokeWidth
=
2
;
// Arbitrary value for the first point. In a real app, a wider range of
// points would be used that go beyond the boundaries of the screen.
double
lastAmount
=
800
;
// Try changing this value between 1, 7, 15, etc.
const
int
smoothing
=
7
;
// Align the points with equal deltas (1 day) as a cumulative sum.
int
startMillis
=
startDate
.
millisecondsSinceEpoch
;
final
List
<
Offset
>
points
=
<
Offset
>[
Offset
(
0
,
(
maxAmount
-
lastAmount
)
/
maxAmount
*
rect
.
height
)
];
for
(
int
i
=
0
;
i
<
numDays
+
smoothing
;
i
++)
{
final
int
endMillis
=
startMillis
+
millisInDay
*
1
;
final
List
<
DetailedEventData
>
filteredEvents
=
events
.
where
(
(
DetailedEventData
e
)
{
return
startMillis
<=
e
.
date
.
millisecondsSinceEpoch
&&
e
.
date
.
millisecondsSinceEpoch
<=
endMillis
;
},
).
toList
();
lastAmount
+=
sumOf
<
DetailedEventData
>(
filteredEvents
,
(
DetailedEventData
e
)
=>
e
.
amount
);
final
double
x
=
i
/
numDays
*
rect
.
width
;
final
double
y
=
(
maxAmount
-
lastAmount
)
/
maxAmount
*
rect
.
height
;
points
.
add
(
Offset
(
x
,
y
));
startMillis
=
endMillis
;
}
final
Path
path
=
Path
();
path
.
moveTo
(
points
[
0
].
dx
,
points
[
0
].
dy
);
for
(
int
i
=
1
;
i
<
points
.
length
-
smoothing
;
i
+=
smoothing
)
{
final
double
x1
=
points
[
i
].
dx
;
final
double
y1
=
points
[
i
].
dy
;
final
double
x2
=
(
x1
+
points
[
i
+
smoothing
].
dx
)
/
2
;
final
double
y2
=
(
y1
+
points
[
i
+
smoothing
].
dy
)
/
2
;
path
.
quadraticBezierTo
(
x1
,
y1
,
x2
,
y2
);
}
canvas
.
drawPath
(
path
,
linePaint
);
}
/// Draw the X-axis increment markers at constant width intervals.
void
_drawXAxisTicks
(
Canvas
canvas
,
Rect
rect
)
{
for
(
int
i
=
0
;
i
<
numDays
;
i
++)
{
final
double
x
=
rect
.
width
/
numDays
*
i
;
canvas
.
drawRect
(
Rect
.
fromPoints
(
Offset
(
x
,
i
%
7
==
tickShift
?
rect
.
top
:
rect
.
center
.
dy
),
Offset
(
x
,
rect
.
bottom
),
),
Paint
()
..
style
=
PaintingStyle
.
stroke
..
strokeWidth
=
1
..
color
=
RallyColors
.
gray25
,
);
}
}
/// Set X-axis labels under the X-axis increment markers.
void
_drawXAxisLabels
(
Canvas
canvas
,
Rect
rect
)
{
final
TextStyle
selectedLabelStyle
=
labelStyle
.
copyWith
(
fontWeight:
FontWeight
.
w700
,
);
final
TextStyle
unselectedLabelStyle
=
labelStyle
.
copyWith
(
fontWeight:
FontWeight
.
w700
,
color:
RallyColors
.
gray25
,
);
final
TextPainter
leftLabel
=
TextPainter
(
text:
TextSpan
(
text:
'AUGUST 2019'
,
style:
unselectedLabelStyle
),
textDirection:
TextDirection
.
ltr
,
);
leftLabel
.
layout
();
leftLabel
.
paint
(
canvas
,
Offset
(
rect
.
left
+
space
/
2
,
rect
.
center
.
dy
));
final
TextPainter
centerLabel
=
TextPainter
(
text:
TextSpan
(
text:
'SEPTEMBER 2019'
,
style:
selectedLabelStyle
),
textDirection:
TextDirection
.
ltr
,
);
centerLabel
.
layout
();
final
double
x
=
(
rect
.
width
-
centerLabel
.
width
)
/
2
;
final
double
y
=
rect
.
center
.
dy
;
centerLabel
.
paint
(
canvas
,
Offset
(
x
,
y
));
final
TextPainter
rightLabel
=
TextPainter
(
text:
TextSpan
(
text:
'OCTOBER 2019'
,
style:
unselectedLabelStyle
),
textDirection:
TextDirection
.
ltr
,
);
rightLabel
.
layout
();
rightLabel
.
paint
(
canvas
,
Offset
(
rect
.
right
-
centerLabel
.
width
-
space
/
2
,
rect
.
center
.
dy
),
);
}
}
examples/flutter_gallery/lib/demo/rally/charts/pie_chart.dart
deleted
100644 → 0
View file @
a214b462
// Copyright 2019-present the Flutter authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import
'dart:math'
;
import
'package:flutter/material.dart'
;
import
'package:flutter_gallery/demo/rally/colors.dart'
;
import
'package:flutter_gallery/demo/rally/data.dart'
;
import
'package:flutter_gallery/demo/rally/formatters.dart'
;
/// A colored piece of the [RallyPieChart].
class
RallyPieChartSegment
{
const
RallyPieChartSegment
({
this
.
color
,
this
.
value
});
final
Color
color
;
final
double
value
;
}
List
<
RallyPieChartSegment
>
buildSegmentsFromAccountItems
(
List
<
AccountData
>
items
)
{
return
List
<
RallyPieChartSegment
>.
generate
(
items
.
length
,
(
int
i
)
{
return
RallyPieChartSegment
(
color:
RallyColors
.
accountColor
(
i
),
value:
items
[
i
].
primaryAmount
,
);
},
);
}
List
<
RallyPieChartSegment
>
buildSegmentsFromBillItems
(
List
<
BillData
>
items
)
{
return
List
<
RallyPieChartSegment
>.
generate
(
items
.
length
,
(
int
i
)
{
return
RallyPieChartSegment
(
color:
RallyColors
.
billColor
(
i
),
value:
items
[
i
].
primaryAmount
,
);
},
);
}
List
<
RallyPieChartSegment
>
buildSegmentsFromBudgetItems
(
List
<
BudgetData
>
items
)
{
return
List
<
RallyPieChartSegment
>.
generate
(
items
.
length
,
(
int
i
)
{
return
RallyPieChartSegment
(
color:
RallyColors
.
budgetColor
(
i
),
value:
items
[
i
].
primaryAmount
-
items
[
i
].
amountUsed
,
);
},
);
}
/// An animated circular pie chart to represent pieces of a whole, which can
/// have empty space.
class
RallyPieChart
extends
StatefulWidget
{
const
RallyPieChart
({
this
.
heroLabel
,
this
.
heroAmount
,
this
.
wholeAmount
,
this
.
segments
});
final
String
heroLabel
;
final
double
heroAmount
;
final
double
wholeAmount
;
final
List
<
RallyPieChartSegment
>
segments
;
@override
_RallyPieChartState
createState
()
=>
_RallyPieChartState
();
}
class
_RallyPieChartState
extends
State
<
RallyPieChart
>
with
SingleTickerProviderStateMixin
{
AnimationController
controller
;
Animation
<
double
>
animation
;
@override
void
initState
()
{
super
.
initState
();
controller
=
AnimationController
(
duration:
const
Duration
(
milliseconds:
600
),
vsync:
this
,
);
animation
=
CurvedAnimation
(
parent:
TweenSequence
<
double
>(<
TweenSequenceItem
<
double
>>[
TweenSequenceItem
<
double
>(
tween:
Tween
<
double
>(
begin:
0
,
end:
0
),
weight:
1
,
),
TweenSequenceItem
<
double
>(
tween:
Tween
<
double
>(
begin:
0
,
end:
1
),
weight:
1.5
,
),
]).
animate
(
controller
),
curve:
Curves
.
decelerate
);
controller
.
forward
();
}
@override
void
dispose
()
{
controller
.
dispose
();
super
.
dispose
();
}
@override
Widget
build
(
BuildContext
context
)
{
return
_AnimatedRallyPieChart
(
animation:
animation
,
centerLabel:
widget
.
heroLabel
,
centerAmount:
widget
.
heroAmount
,
total:
widget
.
wholeAmount
,
segments:
widget
.
segments
,
);
}
}
class
_AnimatedRallyPieChart
extends
AnimatedWidget
{
const
_AnimatedRallyPieChart
({
Key
key
,
this
.
animation
,
this
.
centerLabel
,
this
.
centerAmount
,
this
.
total
,
this
.
segments
,
})
:
super
(
key:
key
,
listenable:
animation
);
final
Animation
<
double
>
animation
;
final
String
centerLabel
;
final
double
centerAmount
;
final
double
total
;
final
List
<
RallyPieChartSegment
>
segments
;
@override
Widget
build
(
BuildContext
context
)
{
final
TextStyle
labelTextStyle
=
Theme
.
of
(
context
).
textTheme
.
body1
.
copyWith
(
fontSize:
14
,
letterSpacing:
0.5
,
);
return
DecoratedBox
(
decoration:
_RallyPieChartOutlineDecoration
(
maxFraction:
animation
.
value
,
total:
total
,
segments:
segments
,
),
child:
SizedBox
(
height:
300
,
child:
Center
(
child:
Column
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
<
Widget
>[
Text
(
centerLabel
,
style:
labelTextStyle
,
),
Text
(
usdWithSignFormat
.
format
(
centerAmount
),
style:
Theme
.
of
(
context
).
textTheme
.
headline
,
),
],
),
),
),
);
}
}
class
_RallyPieChartOutlineDecoration
extends
Decoration
{
const
_RallyPieChartOutlineDecoration
({
this
.
maxFraction
,
this
.
total
,
this
.
segments
});
final
double
maxFraction
;
final
double
total
;
final
List
<
RallyPieChartSegment
>
segments
;
@override
BoxPainter
createBoxPainter
([
VoidCallback
onChanged
])
{
return
_RallyPieChartOutlineBoxPainter
(
maxFraction:
maxFraction
,
wholeAmount:
total
,
segments:
segments
,
);
}
}
class
_RallyPieChartOutlineBoxPainter
extends
BoxPainter
{
_RallyPieChartOutlineBoxPainter
({
this
.
maxFraction
,
this
.
wholeAmount
,
this
.
segments
});
final
double
maxFraction
;
final
double
wholeAmount
;
final
List
<
RallyPieChartSegment
>
segments
;
static
const
double
wholeRadians
=
2
*
pi
;
static
const
double
spaceRadians
=
wholeRadians
/
180
;
@override
void
paint
(
Canvas
canvas
,
Offset
offset
,
ImageConfiguration
configuration
)
{
// Create two padded reacts to draw arcs in: one for colored arcs and one for
// inner bg arc.
const
double
strokeWidth
=
4
;
final
double
outerRadius
=
min
(
configuration
.
size
.
width
,
configuration
.
size
.
height
,
)
/
2
;
final
Rect
outerRect
=
Rect
.
fromCircle
(
center:
configuration
.
size
.
center
(
Offset
.
zero
),
radius:
outerRadius
-
strokeWidth
*
3
,
);
final
Rect
innerRect
=
Rect
.
fromCircle
(
center:
configuration
.
size
.
center
(
Offset
.
zero
),
radius:
outerRadius
-
strokeWidth
*
4
,
);
// Paint each arc with spacing.
double
cumulativeSpace
=
0
;
double
cumulativeTotal
=
0
;
for
(
RallyPieChartSegment
segment
in
segments
)
{
final
Paint
paint
=
Paint
()..
color
=
segment
.
color
;
final
double
startAngle
=
_calculateStartAngle
(
cumulativeTotal
,
cumulativeSpace
);
final
double
sweepAngle
=
_calculateSweepAngle
(
segment
.
value
,
0
);
canvas
.
drawArc
(
outerRect
,
startAngle
,
sweepAngle
,
true
,
paint
);
cumulativeTotal
+=
segment
.
value
;
cumulativeSpace
+=
spaceRadians
;
}
// Paint any remaining space black (e.g. budget amount remaining).
final
double
remaining
=
wholeAmount
-
cumulativeTotal
;
if
(
remaining
>
0
)
{
final
Paint
paint
=
Paint
()..
color
=
Colors
.
black
;
final
double
startAngle
=
_calculateStartAngle
(
cumulativeTotal
,
spaceRadians
*
segments
.
length
);
final
double
sweepAngle
=
_calculateSweepAngle
(
remaining
,
-
spaceRadians
);
canvas
.
drawArc
(
outerRect
,
startAngle
,
sweepAngle
,
true
,
paint
);
}
// Paint a smaller inner circle to cover the painted arcs, so they are
// display as segments.
final
Paint
bgPaint
=
Paint
()..
color
=
RallyColors
.
primaryBackground
;
canvas
.
drawArc
(
innerRect
,
0
,
2
*
pi
,
true
,
bgPaint
);
}
double
_calculateAngle
(
double
amount
,
double
offset
)
{
final
double
wholeMinusSpacesRadians
=
wholeRadians
-
(
segments
.
length
*
spaceRadians
);
return
maxFraction
*
(
amount
/
wholeAmount
*
wholeMinusSpacesRadians
+
offset
);
}
double
_calculateStartAngle
(
double
total
,
double
offset
)
=>
_calculateAngle
(
total
,
offset
)
-
pi
/
2
;
double
_calculateSweepAngle
(
double
total
,
double
offset
)
=>
_calculateAngle
(
total
,
offset
);
}
examples/flutter_gallery/lib/demo/rally/charts/vertical_fraction_bar.dart
deleted
100644 → 0
View file @
a214b462
// Copyright 2019-present the Flutter authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import
'package:flutter/material.dart'
;
class
VerticalFractionBar
extends
StatelessWidget
{
const
VerticalFractionBar
({
this
.
color
,
this
.
fraction
});
final
Color
color
;
final
double
fraction
;
@override
Widget
build
(
BuildContext
context
)
{
return
SizedBox
(
height:
32
,
width:
4
,
child:
Column
(
children:
<
Widget
>[
SizedBox
(
height:
(
1
-
fraction
)
*
32
,
child:
Container
(
color:
Colors
.
black
,
),
),
SizedBox
(
height:
fraction
*
32
,
child:
Container
(
color:
color
),
),
],
),
);
}
}
examples/flutter_gallery/lib/demo/rally/colors.dart
deleted
100644 → 0
View file @
a214b462
// Copyright 2019-present the Flutter authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import
'dart:ui'
;
/// Most color assignments in Rally are not like the the typical color
/// assignments that are common in other apps. Instead of primarily mapping to
/// component type and part, they are assigned round robin based on layout.
class
RallyColors
{
static
const
List
<
Color
>
accountColors
=
<
Color
>[
Color
(
0xFF005D57
),
Color
(
0xFF04B97F
),
Color
(
0xFF37EFBA
),
Color
(
0xFF007D51
),
];
static
const
List
<
Color
>
billColors
=
<
Color
>[
Color
(
0xFFFFDC78
),
Color
(
0xFFFF6951
),
Color
(
0xFFFFD7D0
),
Color
(
0xFFFFAC12
),
];
static
const
List
<
Color
>
budgetColors
=
<
Color
>[
Color
(
0xFFB2F2FF
),
Color
(
0xFFB15DFF
),
Color
(
0xFF72DEFF
),
Color
(
0xFF0082FB
),
];
static
const
Color
gray
=
Color
(
0xFFD8D8D8
);
static
const
Color
gray60
=
Color
(
0x99D8D8D8
);
static
const
Color
gray25
=
Color
(
0x40D8D8D8
);
static
const
Color
white60
=
Color
(
0x99FFFFFF
);
static
const
Color
primaryBackground
=
Color
(
0xFF33333D
);
static
const
Color
inputBackground
=
Color
(
0xFF26282F
);
static
const
Color
cardBackground
=
Color
(
0x03FEFEFE
);
/// Convenience method to get a single account color with position i.
static
Color
accountColor
(
int
i
)
{
return
cycledColor
(
accountColors
,
i
);
}
/// Convenience method to get a single bill color with position i.
static
Color
billColor
(
int
i
)
{
return
cycledColor
(
billColors
,
i
);
}
/// Convenience method to get a single budget color with position i.
static
Color
budgetColor
(
int
i
)
{
return
cycledColor
(
budgetColors
,
i
);
}
/// Gets a color from a list that is considered to be infinitely repeating.
static
Color
cycledColor
(
List
<
Color
>
colors
,
int
i
)
{
return
colors
[
i
%
colors
.
length
];
}
}
examples/flutter_gallery/lib/demo/rally/data.dart
deleted
100644 → 0
View file @
a214b462
// Copyright 2019-present the Flutter authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Calculates the sum of the primary amounts of a list of [AccountData].
double
sumAccountDataPrimaryAmount
(
List
<
AccountData
>
items
)
=>
sumOf
<
AccountData
>(
items
,
(
AccountData
item
)
=>
item
.
primaryAmount
);
/// Calculates the sum of the primary amounts of a list of [BillData].
double
sumBillDataPrimaryAmount
(
List
<
BillData
>
items
)
=>
sumOf
<
BillData
>(
items
,
(
BillData
item
)
=>
item
.
primaryAmount
);
/// Calculates the sum of the primary amounts of a list of [BudgetData].
double
sumBudgetDataPrimaryAmount
(
List
<
BudgetData
>
items
)
=>
sumOf
<
BudgetData
>(
items
,
(
BudgetData
item
)
=>
item
.
primaryAmount
);
/// Calculates the sum of the amounts used of a list of [BudgetData].
double
sumBudgetDataAmountUsed
(
List
<
BudgetData
>
items
)
=>
sumOf
<
BudgetData
>(
items
,
(
BudgetData
item
)
=>
item
.
amountUsed
);
/// Utility function to sum up values in a list.
double
sumOf
<
T
>(
List
<
T
>
list
,
double
getValue
(
T
elt
))
{
double
sum
=
0
;
for
(
T
elt
in
list
)
sum
+=
getValue
(
elt
);
return
sum
;
}
/// A data model for an account.
///
/// The [primaryAmount] is the balance of the account in USD.
class
AccountData
{
const
AccountData
({
this
.
name
,
this
.
primaryAmount
,
this
.
accountNumber
});
/// The display name of this entity.
final
String
name
;
// The primary amount or value of this entity.
final
double
primaryAmount
;
/// The full displayable account number.
final
String
accountNumber
;
}
/// A data model for a bill.
///
/// The [primaryAmount] is the amount due in USD.
class
BillData
{
const
BillData
({
this
.
name
,
this
.
primaryAmount
,
this
.
dueDate
});
/// The display name of this entity.
final
String
name
;
// The primary amount or value of this entity.
final
double
primaryAmount
;
/// The due date of this bill.
final
String
dueDate
;
}
/// A data model for a budget.
///
/// The [primaryAmount] is the budget cap in USD.
class
BudgetData
{
const
BudgetData
({
this
.
name
,
this
.
primaryAmount
,
this
.
amountUsed
});
/// The display name of this entity.
final
String
name
;
// The primary amount or value of this entity.
final
double
primaryAmount
;
/// Amount of the budget that is consumed or used.
final
double
amountUsed
;
}
class
DetailedEventData
{
const
DetailedEventData
({
this
.
title
,
this
.
date
,
this
.
amount
,
});
final
String
title
;
final
DateTime
date
;
final
double
amount
;
}
/// Class to return dummy data lists.
///
/// In a real app, this might be replaced with some asynchronous service.
class
DummyDataService
{
static
List
<
AccountData
>
getAccountDataList
()
{
return
<
AccountData
>[
const
AccountData
(
name:
'Checking'
,
primaryAmount:
2215.13
,
accountNumber:
'1234561234'
,
),
const
AccountData
(
name:
'Home Savings'
,
primaryAmount:
8678.88
,
accountNumber:
'8888885678'
,
),
const
AccountData
(
name:
'Car Savings'
,
primaryAmount:
987.48
,
accountNumber:
'8888889012'
,
),
const
AccountData
(
name:
'Vacation'
,
primaryAmount:
253
,
accountNumber:
'1231233456'
,
),
];
}
static
List
<
DetailedEventData
>
getDetailedEventItems
()
{
return
<
DetailedEventData
>[
DetailedEventData
(
title:
'Genoe'
,
date:
DateTime
.
utc
(
2019
,
1
,
24
),
amount:
-
16.54
,
),
DetailedEventData
(
title:
'Fortnightly Subscribe'
,
date:
DateTime
.
utc
(
2019
,
1
,
5
),
amount:
-
12.54
,
),
DetailedEventData
(
title:
'Circle Cash'
,
date:
DateTime
.
utc
(
2019
,
1
,
5
),
amount:
365.65
,
),
DetailedEventData
(
title:
'Crane Hospitality'
,
date:
DateTime
.
utc
(
2019
,
1
,
4
),
amount:
-
705.13
,
),
DetailedEventData
(
title:
'ABC Payroll'
,
date:
DateTime
.
utc
(
2018
,
12
,
15
),
amount:
1141.43
,
),
DetailedEventData
(
title:
'Shrine'
,
date:
DateTime
.
utc
(
2018
,
12
,
15
),
amount:
-
88.88
,
),
DetailedEventData
(
title:
'Foodmates'
,
date:
DateTime
.
utc
(
2018
,
12
,
4
),
amount:
-
11.69
,
),
];
}
static
List
<
BillData
>
getBillDataList
()
{
return
<
BillData
>[
const
BillData
(
name:
'RedPay Credit'
,
primaryAmount:
45.36
,
dueDate:
'Jan 29'
,
),
const
BillData
(
name:
'Rent'
,
primaryAmount:
1200
,
dueDate:
'Feb 9'
,
),
const
BillData
(
name:
'TabFine Credit'
,
primaryAmount:
87.33
,
dueDate:
'Feb 22'
,
),
const
BillData
(
name:
'ABC Loans'
,
primaryAmount:
400
,
dueDate:
'Feb 29'
,
),
];
}
static
List
<
BudgetData
>
getBudgetDataList
()
{
return
<
BudgetData
>[
const
BudgetData
(
name:
'Coffee Shops'
,
primaryAmount:
70
,
amountUsed:
45.49
,
),
const
BudgetData
(
name:
'Groceries'
,
primaryAmount:
170
,
amountUsed:
16.45
,
),
const
BudgetData
(
name:
'Restaurants'
,
primaryAmount:
170
,
amountUsed:
123.25
,
),
const
BudgetData
(
name:
'Clothing'
,
primaryAmount:
70
,
amountUsed:
19.45
,
),
];
}
static
List
<
String
>
getSettingsTitles
()
{
return
<
String
>[
'Manage Accounts'
,
'Tax Documents'
,
'Passcode and Touch ID'
,
'Notifications'
,
'Personal Information'
,
'Paperless Settings'
,
'Find ATMs'
,
'Help'
,
'Sign out'
,
];
}
}
examples/flutter_gallery/lib/demo/rally/finance.dart
deleted
100644 → 0
View file @
a214b462
// Copyright 2019-present the Flutter authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import
'package:flutter/material.dart'
;
import
'package:flutter_gallery/demo/rally/charts/pie_chart.dart'
;
import
'package:flutter_gallery/demo/rally/charts/line_chart.dart'
;
import
'package:flutter_gallery/demo/rally/charts/vertical_fraction_bar.dart'
;
import
'package:flutter_gallery/demo/rally/colors.dart'
;
import
'package:flutter_gallery/demo/rally/data.dart'
;
import
'package:flutter_gallery/demo/rally/formatters.dart'
;
class
FinancialEntityView
extends
StatelessWidget
{
const
FinancialEntityView
({
this
.
heroLabel
,
this
.
heroAmount
,
this
.
wholeAmount
,
this
.
segments
,
this
.
financialEntityCards
,
})
:
assert
(
segments
.
length
==
financialEntityCards
.
length
);
/// The amounts to assign each item.
final
List
<
RallyPieChartSegment
>
segments
;
final
String
heroLabel
;
final
double
heroAmount
;
final
double
wholeAmount
;
final
List
<
FinancialEntityCategoryView
>
financialEntityCards
;
@override
Widget
build
(
BuildContext
context
)
{
return
Column
(
children:
<
Widget
>[
RallyPieChart
(
heroLabel:
heroLabel
,
heroAmount:
heroAmount
,
wholeAmount:
wholeAmount
,
segments:
segments
,
),
SizedBox
(
height:
1
,
child:
Container
(
color:
const
Color
(
0xA026282F
),
),
),
ListView
(
shrinkWrap:
true
,
children:
financialEntityCards
),
],
);
}
}
/// A reusable widget to show balance information of a single entity as a card.
class
FinancialEntityCategoryView
extends
StatelessWidget
{
const
FinancialEntityCategoryView
({
@required
this
.
indicatorColor
,
@required
this
.
indicatorFraction
,
@required
this
.
title
,
@required
this
.
subtitle
,
@required
this
.
amount
,
@required
this
.
suffix
,
});
final
Color
indicatorColor
;
final
double
indicatorFraction
;
final
String
title
;
final
String
subtitle
;
final
double
amount
;
final
Widget
suffix
;
@override
Widget
build
(
BuildContext
context
)
{
return
FlatButton
(
onPressed:
()
{
Navigator
.
push
(
context
,
MaterialPageRoute
<
FinancialEntityCategoryDetailsPage
>(
builder:
(
BuildContext
context
)
=>
FinancialEntityCategoryDetailsPage
(),
),
);
},
child:
SizedBox
(
height:
68
,
child:
Column
(
children:
<
Widget
>[
Expanded
(
child:
Row
(
children:
<
Widget
>[
Padding
(
padding:
const
EdgeInsets
.
only
(
left:
12
,
right:
12
),
child:
VerticalFractionBar
(
color:
indicatorColor
,
fraction:
indicatorFraction
,
),
),
Column
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
<
Widget
>[
Text
(
title
,
style:
Theme
.
of
(
context
).
textTheme
.
body1
.
copyWith
(
fontSize:
16
),
),
Text
(
subtitle
,
style:
Theme
.
of
(
context
).
textTheme
.
body1
.
copyWith
(
color:
RallyColors
.
gray60
),
),
],
),
const
Spacer
(),
Text
(
'
\$
'
+
usdFormat
.
format
(
amount
),
style:
Theme
.
of
(
context
).
textTheme
.
body2
.
copyWith
(
fontSize:
20
,
color:
RallyColors
.
gray
),
),
SizedBox
(
width:
32
,
child:
suffix
),
],
),
),
const
Divider
(
height:
1
,
indent:
16
,
endIndent:
16
,
color:
Color
(
0xAA282828
),
),
],
),
),
);
}
}
/// Data model for [FinancialEntityCategoryView].
class
FinancialEntityCategoryModel
{
const
FinancialEntityCategoryModel
(
this
.
indicatorColor
,
this
.
indicatorFraction
,
this
.
title
,
this
.
subtitle
,
this
.
usdAmount
,
this
.
suffix
,
);
final
Color
indicatorColor
;
final
double
indicatorFraction
;
final
String
title
;
final
String
subtitle
;
final
double
usdAmount
;
final
Widget
suffix
;
}
FinancialEntityCategoryView
buildFinancialEntityFromAccountData
(
AccountData
model
,
int
accountDataIndex
,
)
{
return
FinancialEntityCategoryView
(
suffix:
const
Icon
(
Icons
.
chevron_right
,
color:
Colors
.
grey
),
title:
model
.
name
,
subtitle:
'• • • • • •
${model.accountNumber.substring(6)}
'
,
indicatorColor:
RallyColors
.
accountColor
(
accountDataIndex
),
indicatorFraction:
1
,
amount:
model
.
primaryAmount
,
);
}
FinancialEntityCategoryView
buildFinancialEntityFromBillData
(
BillData
model
,
int
billDataInex
,
)
{
return
FinancialEntityCategoryView
(
suffix:
const
Icon
(
Icons
.
chevron_right
,
color:
Colors
.
grey
),
title:
model
.
name
,
subtitle:
model
.
dueDate
,
indicatorColor:
RallyColors
.
billColor
(
billDataInex
),
indicatorFraction:
1
,
amount:
model
.
primaryAmount
,
);
}
FinancialEntityCategoryView
buildFinancialEntityFromBudgetData
(
BudgetData
item
,
int
budgetDataIndex
,
BuildContext
context
,
)
{
final
String
amountUsed
=
usdWithSignFormat
.
format
(
item
.
amountUsed
);
final
String
primaryAmount
=
usdWithSignFormat
.
format
(
item
.
primaryAmount
);
return
FinancialEntityCategoryView
(
suffix:
Text
(
' LEFT'
,
style:
Theme
.
of
(
context
).
textTheme
.
body1
.
copyWith
(
color:
RallyColors
.
gray60
,
fontSize:
10
),
),
title:
item
.
name
,
subtitle:
amountUsed
+
' / '
+
primaryAmount
,
indicatorColor:
RallyColors
.
budgetColor
(
budgetDataIndex
),
indicatorFraction:
item
.
amountUsed
/
item
.
primaryAmount
,
amount:
item
.
primaryAmount
-
item
.
amountUsed
,
);
}
List
<
FinancialEntityCategoryView
>
buildAccountDataListViews
(
List
<
AccountData
>
items
)
{
return
List
<
FinancialEntityCategoryView
>.
generate
(
items
.
length
,
(
int
i
)
=>
buildFinancialEntityFromAccountData
(
items
[
i
],
i
),
);
}
List
<
FinancialEntityCategoryView
>
buildBillDataListViews
(
List
<
BillData
>
items
)
{
return
List
<
FinancialEntityCategoryView
>.
generate
(
items
.
length
,
(
int
i
)
=>
buildFinancialEntityFromBillData
(
items
[
i
],
i
),
);
}
List
<
FinancialEntityCategoryView
>
buildBudgetDataListViews
(
List
<
BudgetData
>
items
,
BuildContext
context
)
{
return
<
FinancialEntityCategoryView
>[
for
(
int
i
=
0
;
i
<
items
.
length
;
i
++)
buildFinancialEntityFromBudgetData
(
items
[
i
],
i
,
context
)
];
}
class
FinancialEntityCategoryDetailsPage
extends
StatelessWidget
{
final
List
<
DetailedEventData
>
items
=
DummyDataService
.
getDetailedEventItems
();
@override
Widget
build
(
BuildContext
context
)
{
final
List
<
_DetailedEventCard
>
cards
=
items
.
map
((
DetailedEventData
detailedEventData
)
{
return
_DetailedEventCard
(
title:
detailedEventData
.
title
,
subtitle:
dateFormat
.
format
(
detailedEventData
.
date
),
amount:
detailedEventData
.
amount
,
);
}).
toList
();
return
Scaffold
(
appBar:
AppBar
(
elevation:
0
,
centerTitle:
true
,
title:
Text
(
'Checking'
,
style:
Theme
.
of
(
context
).
textTheme
.
body1
.
copyWith
(
fontSize:
18
),
),
),
body:
Column
(
children:
<
Widget
>[
SizedBox
(
height:
200
,
width:
double
.
infinity
,
child:
RallyLineChart
(
events:
items
),
),
Flexible
(
child:
ListView
(
shrinkWrap:
true
,
children:
cards
),
),
],
),
);
}
}
class
_DetailedEventCard
extends
StatelessWidget
{
const
_DetailedEventCard
({
@required
this
.
title
,
@required
this
.
subtitle
,
@required
this
.
amount
,
});
final
String
title
;
final
String
subtitle
;
final
double
amount
;
@override
Widget
build
(
BuildContext
context
)
{
final
TextTheme
textTheme
=
Theme
.
of
(
context
).
textTheme
;
return
FlatButton
(
onPressed:
()
{},
child:
SizedBox
(
height:
68
,
child:
Column
(
children:
<
Widget
>[
SizedBox
(
height:
67
,
child:
Row
(
children:
<
Widget
>[
Column
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
<
Widget
>[
Text
(
title
,
style:
textTheme
.
body1
.
copyWith
(
fontSize:
16
),
),
Text
(
subtitle
,
style:
textTheme
.
body1
.
copyWith
(
color:
RallyColors
.
gray60
),
)
],
),
const
Spacer
(),
Text
(
'
\$
${usdFormat.format(amount)}
'
,
style:
textTheme
.
body2
.
copyWith
(
fontSize:
20
,
color:
RallyColors
.
gray
),
),
],
),
),
Padding
(
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
16
),
child:
SizedBox
(
height:
1
,
child:
Container
(
color:
const
Color
(
0xAA282828
),
),
),
),
],
),
),
);
}
}
examples/flutter_gallery/lib/demo/rally/formatters.dart
deleted
100644 → 0
View file @
a214b462
// Copyright 2019-present the Flutter authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import
'package:intl/intl.dart'
;
NumberFormat
usdFormat
=
NumberFormat
.
currency
(
name:
''
);
NumberFormat
usdWithSignFormat
=
NumberFormat
.
currency
(
name:
'
\$
'
);
DateFormat
dateFormat
=
DateFormat
(
'MM-dd-yy'
);
examples/flutter_gallery/lib/demo/rally/home.dart
deleted
100644 → 0
View file @
a214b462
// Copyright 2019-present the Flutter authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import
'package:flutter/material.dart'
;
import
'package:flutter_gallery/demo/rally/tabs/accounts.dart'
;
import
'package:flutter_gallery/demo/rally/tabs/bills.dart'
;
import
'package:flutter_gallery/demo/rally/tabs/budgets.dart'
;
import
'package:flutter_gallery/demo/rally/tabs/overview.dart'
;
import
'package:flutter_gallery/demo/rally/tabs/settings.dart'
;
const
int
tabCount
=
5
;
class
HomePage
extends
StatefulWidget
{
@override
_HomePageState
createState
()
=>
_HomePageState
();
}
class
_HomePageState
extends
State
<
HomePage
>
with
SingleTickerProviderStateMixin
{
TabController
_tabController
;
@override
void
initState
()
{
super
.
initState
();
_tabController
=
TabController
(
length:
tabCount
,
vsync:
this
)
..
addListener
(()
{
// Set state to make sure that the [_RallyTab] widgets get updated when changing tabs.
setState
(()
{
});
});
}
@override
void
dispose
()
{
_tabController
.
dispose
();
super
.
dispose
();
}
@override
Widget
build
(
BuildContext
context
)
{
final
ThemeData
theme
=
Theme
.
of
(
context
);
return
Scaffold
(
body:
SafeArea
(
child:
Column
(
children:
<
Widget
>[
Theme
(
// This theme effectively removes the default visual touch
// feedback for tapping a tab, which is replaced with a custom
// animation.
data:
theme
.
copyWith
(
splashColor:
Colors
.
transparent
,
highlightColor:
Colors
.
transparent
,
),
child:
TabBar
(
// Setting isScrollable to true prevents the tabs from being
// wrapped in [Expanded] widgets, which allows for more
// flexible sizes and size animations among tabs.
isScrollable:
true
,
labelPadding:
EdgeInsets
.
zero
,
tabs:
_buildTabs
(
theme
),
controller:
_tabController
,
// This hides the tab indicator.
indicatorColor:
Colors
.
transparent
,
),
),
Expanded
(
child:
TabBarView
(
controller:
_tabController
,
children:
_buildTabViews
(),
),
),
],
),
),
);
}
List
<
Widget
>
_buildTabs
(
ThemeData
theme
)
{
return
<
Widget
>[
_RallyTab
(
theme
,
Icons
.
pie_chart
,
'OVERVIEW'
,
0
,
_tabController
),
_RallyTab
(
theme
,
Icons
.
attach_money
,
'ACCOUNTS'
,
1
,
_tabController
),
_RallyTab
(
theme
,
Icons
.
money_off
,
'BILLS'
,
2
,
_tabController
),
_RallyTab
(
theme
,
Icons
.
table_chart
,
'BUDGETS'
,
3
,
_tabController
),
_RallyTab
(
theme
,
Icons
.
settings
,
'SETTINGS'
,
4
,
_tabController
),
];
}
List
<
Widget
>
_buildTabViews
()
{
return
<
Widget
>[
OverviewView
(),
AccountsView
(),
BillsView
(),
BudgetsView
(),
SettingsView
(),
];
}
}
class
_RallyTab
extends
StatefulWidget
{
_RallyTab
(
ThemeData
theme
,
IconData
iconData
,
String
title
,
int
tabIndex
,
TabController
tabController
,
)
:
titleText
=
Text
(
title
,
style:
theme
.
textTheme
.
button
),
isExpanded
=
tabController
.
index
==
tabIndex
,
icon
=
Icon
(
iconData
);
final
Text
titleText
;
final
Icon
icon
;
final
bool
isExpanded
;
@override
_RallyTabState
createState
()
=>
_RallyTabState
();
}
class
_RallyTabState
extends
State
<
_RallyTab
>
with
SingleTickerProviderStateMixin
{
Animation
<
double
>
_titleSizeAnimation
;
Animation
<
double
>
_titleFadeAnimation
;
Animation
<
double
>
_iconFadeAnimation
;
AnimationController
_controller
;
@override
void
initState
()
{
super
.
initState
();
_controller
=
AnimationController
(
duration:
const
Duration
(
milliseconds:
200
),
vsync:
this
,
);
_titleSizeAnimation
=
_controller
.
view
;
_titleFadeAnimation
=
_controller
.
drive
(
CurveTween
(
curve:
Curves
.
easeOut
));
_iconFadeAnimation
=
_controller
.
drive
(
Tween
<
double
>(
begin:
0.6
,
end:
1
));
if
(
widget
.
isExpanded
)
{
_controller
.
value
=
1
;
}
}
@override
void
didUpdateWidget
(
_RallyTab
oldWidget
)
{
super
.
didUpdateWidget
(
oldWidget
);
if
(
widget
.
isExpanded
)
{
_controller
.
forward
();
}
else
{
_controller
.
reverse
();
}
}
@override
Widget
build
(
BuildContext
context
)
{
// Calculate the width of each unexpanded tab by counting the number of
// units and dividing it into the screen width. Each unexpanded tab is 1
// unit, and there is always 1 expanded tab which is 1 unit + any extra
// space determined by the multiplier.
final
double
width
=
MediaQuery
.
of
(
context
).
size
.
width
;
const
double
expandedTitleWidthMultiplier
=
2
;
final
double
unitWidth
=
width
/
(
tabCount
+
expandedTitleWidthMultiplier
);
return
SizedBox
(
height:
56
,
child:
Row
(
children:
<
Widget
>[
FadeTransition
(
child:
SizedBox
(
width:
unitWidth
,
child:
widget
.
icon
,
),
opacity:
_iconFadeAnimation
,
),
FadeTransition
(
child:
SizeTransition
(
child:
SizedBox
(
width:
unitWidth
*
expandedTitleWidthMultiplier
,
child:
Center
(
child:
widget
.
titleText
),
),
axis:
Axis
.
horizontal
,
axisAlignment:
-
1
,
sizeFactor:
_titleSizeAnimation
,
),
opacity:
_titleFadeAnimation
,
),
],
),
);
}
@override
void
dispose
()
{
_controller
.
dispose
();
super
.
dispose
();
}
}
examples/flutter_gallery/lib/demo/rally/login.dart
deleted
100644 → 0
View file @
a214b462
// Copyright 2019-present the Flutter authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import
'package:flutter/material.dart'
;
class
LoginPage
extends
StatefulWidget
{
@override
_LoginPageState
createState
()
=>
_LoginPageState
();
}
class
_LoginPageState
extends
State
<
LoginPage
>
{
final
TextEditingController
_usernameController
=
TextEditingController
();
final
TextEditingController
_passwordController
=
TextEditingController
();
@override
Widget
build
(
BuildContext
context
)
{
return
Scaffold
(
appBar:
AppBar
(
elevation:
0
,
leading:
IconButton
(
icon:
const
BackButtonIcon
(),
tooltip:
MaterialLocalizations
.
of
(
context
).
backButtonTooltip
,
onPressed:
()
{
Navigator
.
of
(
context
,
rootNavigator:
true
).
pop
();
},
),
),
body:
SafeArea
(
child:
GestureDetector
(
onTap:
()
{
Navigator
.
pop
(
context
);
},
child:
ListView
(
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
24
),
children:
<
Widget
>[
Padding
(
padding:
const
EdgeInsets
.
symmetric
(
vertical:
64
),
child:
SizedBox
(
height:
160
,
child:
Image
.
asset
(
'logo.png'
,
package:
'rally_assets'
,
),
),
),
TextField
(
controller:
_usernameController
,
decoration:
const
InputDecoration
(
labelText:
'Username'
,
),
),
const
SizedBox
(
height:
12
),
TextField
(
controller:
_passwordController
,
decoration:
const
InputDecoration
(
labelText:
'Password'
,
),
obscureText:
true
,
),
SizedBox
(
height:
120
,
child:
Image
.
asset
(
'thumb.png'
,
package:
'rally_assets'
,
),
),
],
),
),
),
);
}
@override
void
dispose
()
{
_usernameController
.
dispose
();
_passwordController
.
dispose
();
super
.
dispose
();
}
}
examples/flutter_gallery/lib/demo/rally/main.dart
deleted
100644 → 0
View file @
a214b462
// Copyright 2019-present the Flutter authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import
'package:flutter/widgets.dart'
;
import
'package:flutter_gallery/demo/rally/app.dart'
;
void
main
(
)
=>
runApp
(
RallyApp
());
examples/flutter_gallery/lib/demo/rally/tabs/accounts.dart
deleted
100644 → 0
View file @
a214b462
// Copyright 2019-present the Flutter authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import
'package:flutter/widgets.dart'
;
import
'package:flutter_gallery/demo/rally/data.dart'
;
import
'package:flutter_gallery/demo/rally/finance.dart'
;
import
'package:flutter_gallery/demo/rally/charts/pie_chart.dart'
;
/// A page that shows a summary of accounts.
class
AccountsView
extends
StatelessWidget
{
final
List
<
AccountData
>
items
=
DummyDataService
.
getAccountDataList
();
@override
Widget
build
(
BuildContext
context
)
{
final
double
balanceTotal
=
sumAccountDataPrimaryAmount
(
items
);
return
FinancialEntityView
(
heroLabel:
'Total'
,
heroAmount:
balanceTotal
,
segments:
buildSegmentsFromAccountItems
(
items
),
wholeAmount:
balanceTotal
,
financialEntityCards:
buildAccountDataListViews
(
items
),
);
}
}
examples/flutter_gallery/lib/demo/rally/tabs/bills.dart
deleted
100644 → 0
View file @
a214b462
// Copyright 2019-present the Flutter authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import
'package:flutter/widgets.dart'
;
import
'package:flutter_gallery/demo/rally/data.dart'
;
import
'package:flutter_gallery/demo/rally/finance.dart'
;
import
'package:flutter_gallery/demo/rally/charts/pie_chart.dart'
;
/// A page that shows a summary of bills.
class
BillsView
extends
StatefulWidget
{
@override
_BillsViewState
createState
()
=>
_BillsViewState
();
}
class
_BillsViewState
extends
State
<
BillsView
>
with
SingleTickerProviderStateMixin
{
final
List
<
BillData
>
items
=
DummyDataService
.
getBillDataList
();
@override
Widget
build
(
BuildContext
context
)
{
final
double
dueTotal
=
sumBillDataPrimaryAmount
(
items
);
return
FinancialEntityView
(
heroLabel:
'Due'
,
heroAmount:
dueTotal
,
segments:
buildSegmentsFromBillItems
(
items
),
wholeAmount:
dueTotal
,
financialEntityCards:
buildBillDataListViews
(
items
),
);
}
}
examples/flutter_gallery/lib/demo/rally/tabs/budgets.dart
deleted
100644 → 0
View file @
a214b462
// Copyright 2019-present the Flutter authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import
'package:flutter/widgets.dart'
;
import
'package:flutter_gallery/demo/rally/charts/pie_chart.dart'
;
import
'package:flutter_gallery/demo/rally/data.dart'
;
import
'package:flutter_gallery/demo/rally/finance.dart'
;
class
BudgetsView
extends
StatefulWidget
{
@override
_BudgetsViewState
createState
()
=>
_BudgetsViewState
();
}
class
_BudgetsViewState
extends
State
<
BudgetsView
>
with
SingleTickerProviderStateMixin
{
final
List
<
BudgetData
>
items
=
DummyDataService
.
getBudgetDataList
();
@override
Widget
build
(
BuildContext
context
)
{
final
double
capTotal
=
sumBudgetDataPrimaryAmount
(
items
);
final
double
usedTotal
=
sumBudgetDataAmountUsed
(
items
);
return
FinancialEntityView
(
heroLabel:
'Left'
,
heroAmount:
capTotal
-
usedTotal
,
segments:
buildSegmentsFromBudgetItems
(
items
),
wholeAmount:
capTotal
,
financialEntityCards:
buildBudgetDataListViews
(
items
,
context
),
);
}
}
examples/flutter_gallery/lib/demo/rally/tabs/overview.dart
deleted
100644 → 0
View file @
a214b462
// Copyright 2019-present the Flutter authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import
'dart:math'
;
import
'package:flutter/material.dart'
;
import
'package:flutter_gallery/demo/rally/colors.dart'
;
import
'package:flutter_gallery/demo/rally/data.dart'
;
import
'package:flutter_gallery/demo/rally/finance.dart'
;
import
'package:flutter_gallery/demo/rally/formatters.dart'
;
/// A page that shows a status overview.
class
OverviewView
extends
StatefulWidget
{
@override
_OverviewViewState
createState
()
=>
_OverviewViewState
();
}
class
_OverviewViewState
extends
State
<
OverviewView
>
{
@override
Widget
build
(
BuildContext
context
)
{
final
List
<
AccountData
>
accountDataList
=
DummyDataService
.
getAccountDataList
();
final
List
<
BillData
>
billDataList
=
DummyDataService
.
getBillDataList
();
final
List
<
BudgetData
>
budgetDataList
=
DummyDataService
.
getBudgetDataList
();
return
Padding
(
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
16
,
vertical:
8
),
child:
ListView
(
children:
<
Widget
>[
_AlertsView
(),
const
SizedBox
(
height:
16
),
_FinancialView
(
title:
'Accounts'
,
total:
sumAccountDataPrimaryAmount
(
accountDataList
),
financialItemViews:
buildAccountDataListViews
(
accountDataList
),
),
const
SizedBox
(
height:
16
),
_FinancialView
(
title:
'Bills'
,
total:
sumBillDataPrimaryAmount
(
billDataList
),
financialItemViews:
buildBillDataListViews
(
billDataList
),
),
const
SizedBox
(
height:
16
),
_FinancialView
(
title:
'Budgets'
,
total:
sumBudgetDataPrimaryAmount
(
budgetDataList
),
financialItemViews:
buildBudgetDataListViews
(
budgetDataList
,
context
),
),
const
SizedBox
(
height:
16
),
],
),
);
}
}
class
_AlertsView
extends
StatelessWidget
{
@override
Widget
build
(
BuildContext
context
)
{
return
Container
(
padding:
const
EdgeInsets
.
only
(
left:
16
,
top:
4
,
bottom:
4
),
color:
RallyColors
.
cardBackground
,
child:
Column
(
children:
<
Widget
>[
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
children:
<
Widget
>[
const
Text
(
'Alerts'
),
FlatButton
(
onPressed:
()
{},
child:
const
Text
(
'SEE ALL'
),
textColor:
Colors
.
white
,
),
],
),
Container
(
color:
RallyColors
.
primaryBackground
,
height:
1
),
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
children:
<
Widget
>[
const
Expanded
(
child:
Text
(
'Heads up, you’ve used up 90% of your Shopping budget for this month.'
),
),
SizedBox
(
width:
100
,
child:
Align
(
alignment:
Alignment
.
topRight
,
child:
IconButton
(
onPressed:
()
{},
icon:
Icon
(
Icons
.
sort
,
color:
RallyColors
.
white60
),
),
),
),
],
),
],
),
);
}
}
class
_FinancialView
extends
StatelessWidget
{
const
_FinancialView
({
this
.
title
,
this
.
total
,
this
.
financialItemViews
});
final
String
title
;
final
double
total
;
final
List
<
FinancialEntityCategoryView
>
financialItemViews
;
@override
Widget
build
(
BuildContext
context
)
{
final
ThemeData
theme
=
Theme
.
of
(
context
);
return
Container
(
color:
RallyColors
.
cardBackground
,
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
stretch
,
children:
<
Widget
>[
Padding
(
padding:
const
EdgeInsets
.
all
(
16
),
child:
Text
(
title
),
),
Padding
(
padding:
const
EdgeInsets
.
only
(
left:
16
,
right:
16
),
child:
Text
(
usdWithSignFormat
.
format
(
total
),
style:
theme
.
textTheme
.
body2
.
copyWith
(
fontSize:
44
,
fontWeight:
FontWeight
.
w600
,
),
),
),
...
financialItemViews
.
sublist
(
0
,
min
(
financialItemViews
.
length
,
3
)),
FlatButton
(
child:
const
Text
(
'SEE ALL'
),
textColor:
Colors
.
white
,
onPressed:
()
{},
),
],
),
);
}
}
examples/flutter_gallery/lib/demo/rally/tabs/settings.dart
deleted
100644 → 0
View file @
a214b462
// Copyright 2019-present the Flutter authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import
'package:flutter/material.dart'
;
import
'package:flutter_gallery/demo/rally/data.dart'
;
import
'package:flutter_gallery/demo/rally/login.dart'
;
class
SettingsView
extends
StatefulWidget
{
@override
_SettingsViewState
createState
()
=>
_SettingsViewState
();
}
class
_SettingsViewState
extends
State
<
SettingsView
>
{
List
<
Widget
>
items
=
DummyDataService
.
getSettingsTitles
()
.
map
((
String
title
)
=>
_SettingsItem
(
title
))
.
toList
();
@override
Widget
build
(
BuildContext
context
)
{
return
ListView
(
children:
items
);
}
}
class
_SettingsItem
extends
StatelessWidget
{
const
_SettingsItem
(
this
.
title
);
final
String
title
;
@override
Widget
build
(
BuildContext
context
)
{
return
FlatButton
(
textColor:
Colors
.
white
,
child:
SizedBox
(
height:
60
,
child:
Row
(
children:
<
Widget
>[
Text
(
title
),
]),
),
onPressed:
()
{
Navigator
.
push
<
void
>(
context
,
MaterialPageRoute
<
void
>(
builder:
(
BuildContext
context
)
=>
LoginPage
()),
);
},
);
}
}
examples/flutter_gallery/lib/demo/rally_demo.dart
deleted
100644 → 0
View file @
a214b462
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter/material.dart'
;
import
'package:flutter_gallery/demo/rally/app.dart'
;
class
RallyDemo
extends
StatelessWidget
{
const
RallyDemo
({
Key
key
})
:
super
(
key:
key
);
static
const
String
routeName
=
'/rally'
;
// Used by the Gallery app.
@override
Widget
build
(
BuildContext
context
)
=>
RallyApp
();
}
examples/flutter_gallery/lib/gallery/demos.dart
View file @
7d033716
...
...
@@ -131,14 +131,6 @@ List<GalleryDemo> _buildGalleryDemos() {
routeName:
TransformationsDemo
.
routeName
,
buildRoute:
(
BuildContext
context
)
=>
const
TransformationsDemo
(),
),
GalleryDemo
(
title:
'Rally'
,
subtitle:
'A personal finance app'
,
icon:
GalleryIcons
.
data_table
,
category:
_kDemos
,
routeName:
RallyDemo
.
routeName
,
buildRoute:
(
BuildContext
context
)
=>
const
RallyDemo
(),
),
// Style
GalleryDemo
(
...
...
examples/flutter_gallery/pubspec.yaml
View file @
7d033716
...
...
@@ -17,7 +17,6 @@ dependencies:
video_player
:
0.10.2+5
scoped_model
:
1.0.1
shrine_images
:
1.1.2
rally_assets
:
1.0.0
# Also update dev/benchmarks/complex_layout/pubspec.yaml
flutter_gallery_assets
:
0.1.9+2
...
...
@@ -200,8 +199,6 @@ flutter:
-
packages/shrine_images/35-0.jpg
-
packages/shrine_images/36-0.jpg
-
packages/shrine_images/37-0.jpg
-
packages/rally_assets/logo.png
-
packages/rally_assets/thumb.png
fonts
:
-
family
:
Raleway
...
...
@@ -263,21 +260,5 @@ flutter:
-
asset
:
packages/flutter_gallery_assets/fonts/merriweather/Merriweather-Italic.ttf
-
asset
:
packages/flutter_gallery_assets/fonts/merriweather/Merriweather-Regular.ttf
-
asset
:
packages/flutter_gallery_assets/fonts/merriweather/Merriweather-Light.ttf
-
family
:
Roboto Condensed
fonts
:
-
asset
:
packages/rally_assets/RobotoCondensed-Light.ttf
weight
:
400
-
asset
:
packages/rally_assets/RobotoCondensed-Regular.ttf
weight
:
500
-
asset
:
packages/rally_assets/RobotoCondensed-Bold.ttf
weight
:
700
-
family
:
Eczar
fonts
:
-
asset
:
packages/rally_assets/Eczar-Regular.ttf
weight
:
400
-
asset
:
packages/rally_assets/Eczar-SemiBold.ttf
weight
:
600
-
asset
:
packages/rally_assets/Eczar-Bold.ttf
weight
:
700
# PUBSPEC CHECKSUM:
55a6
# PUBSPEC CHECKSUM:
8b43
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment