mirror of
https://github.com/flutter/samples.git
synced 2025-11-08 22:09:06 +00:00
Adding Rally App to Flutter Samples (#135)
This commit is contained in:
committed by
Andrew Brogdon
parent
3348c2f2dd
commit
c056b754a2
344
material_studies/rally/lib/finance.dart
Normal file
344
material_studies/rally/lib/finance.dart
Normal file
@@ -0,0 +1,344 @@
|
||||
// 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/widgets.dart';
|
||||
|
||||
import 'package:rally/charts/pie_chart.dart';
|
||||
import 'package:rally/charts/line_chart.dart';
|
||||
import 'package:rally/charts/vertical_fraction_bar.dart';
|
||||
import 'package:rally/colors.dart';
|
||||
import 'package:rally/data.dart';
|
||||
import 'package:rally/formatters.dart';
|
||||
|
||||
class FinancialEntityView extends StatelessWidget {
|
||||
FinancialEntityView({
|
||||
this.heroLabel,
|
||||
this.heroAmount,
|
||||
this.wholeAmount,
|
||||
this.segments,
|
||||
this.financialEntityCards,
|
||||
}) : assert(segments.length == financialEntityCards.length);
|
||||
|
||||
/// The amounts to assign each item.
|
||||
///
|
||||
/// This list must have the same length as [colors].
|
||||
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: [
|
||||
RallyPieChart(
|
||||
heroLabel: heroLabel,
|
||||
heroAmount: heroAmount,
|
||||
wholeAmount: wholeAmount,
|
||||
segments: segments,
|
||||
),
|
||||
SizedBox(
|
||||
height: 1.0,
|
||||
child: Container(
|
||||
color: 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: (context) => FinancialEntityCategoryDetailsPage(),
|
||||
),
|
||||
);
|
||||
},
|
||||
child: SizedBox(
|
||||
height: 68,
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Row(
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 12, right: 12),
|
||||
child: VerticalFractionBar(
|
||||
color: indicatorColor,
|
||||
fraction: indicatorFraction,
|
||||
),
|
||||
),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.body1
|
||||
.copyWith(fontSize: 16.0),
|
||||
),
|
||||
Text(
|
||||
subtitle,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.body1
|
||||
.copyWith(color: RallyColors.gray60),
|
||||
),
|
||||
],
|
||||
),
|
||||
Spacer(),
|
||||
Text(
|
||||
'\$ ' + Formatters.usd.format(amount),
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.body2
|
||||
.copyWith(fontSize: 20.0, color: RallyColors.gray),
|
||||
),
|
||||
SizedBox(width: 32.0, child: suffix),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(
|
||||
height: 1,
|
||||
indent: 16,
|
||||
endIndent: 16,
|
||||
color: Color(0xAA282828),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Data model for [FinancialEntityCategoryView].
|
||||
class FinancialEntityCategoryModel {
|
||||
final Color indicatorColor;
|
||||
final double indicatorFraction;
|
||||
final String title;
|
||||
final String subtitle;
|
||||
final double usdAmount;
|
||||
final Widget suffix;
|
||||
|
||||
const FinancialEntityCategoryModel(
|
||||
this.indicatorColor,
|
||||
this.indicatorFraction,
|
||||
this.title,
|
||||
this.subtitle,
|
||||
this.usdAmount,
|
||||
this.suffix,
|
||||
);
|
||||
}
|
||||
|
||||
FinancialEntityCategoryView buildFinancialEntityFromAccountData(
|
||||
AccountData model,
|
||||
int i,
|
||||
) {
|
||||
return FinancialEntityCategoryView(
|
||||
suffix: Icon(Icons.chevron_right, color: Colors.grey),
|
||||
title: model.name,
|
||||
subtitle: '• • • • • • ${model.accountNumber.substring(6)}',
|
||||
indicatorColor: RallyColors.accountColor(i),
|
||||
indicatorFraction: 1.0,
|
||||
amount: model.primaryAmount,
|
||||
);
|
||||
}
|
||||
|
||||
FinancialEntityCategoryView buildFinancialEntityFromBillData(
|
||||
BillData model,
|
||||
int i,
|
||||
) {
|
||||
return FinancialEntityCategoryView(
|
||||
suffix: Icon(Icons.chevron_right, color: Colors.grey),
|
||||
title: model.name,
|
||||
subtitle: model.dueDate,
|
||||
indicatorColor: RallyColors.billColor(i),
|
||||
indicatorFraction: 1.0,
|
||||
amount: model.primaryAmount,
|
||||
);
|
||||
}
|
||||
|
||||
FinancialEntityCategoryView buildFinancialEntityFromBudgetData(
|
||||
BudgetData item,
|
||||
int i,
|
||||
BuildContext context,
|
||||
) {
|
||||
return FinancialEntityCategoryView(
|
||||
suffix: Text(' LEFT',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.body1
|
||||
.copyWith(color: RallyColors.gray60, fontSize: 10.0)),
|
||||
title: item.name,
|
||||
subtitle: Formatters.usdWithSign.format(item.amountUsed) +
|
||||
' / ' +
|
||||
Formatters.usdWithSign.format(item.primaryAmount),
|
||||
indicatorColor: RallyColors.budgetColor(i),
|
||||
indicatorFraction: item.amountUsed / item.primaryAmount,
|
||||
amount: item.primaryAmount - item.amountUsed,
|
||||
);
|
||||
}
|
||||
|
||||
List<FinancialEntityCategoryView> buildAccountDataListViews(
|
||||
List<AccountData> items) {
|
||||
return List<FinancialEntityCategoryView>.generate(
|
||||
items.length, (i) => buildFinancialEntityFromAccountData(items[i], i));
|
||||
}
|
||||
|
||||
List<FinancialEntityCategoryView> buildBillDataListViews(List<BillData> items) {
|
||||
return List<FinancialEntityCategoryView>.generate(
|
||||
items.length, (i) => buildFinancialEntityFromBillData(items[i], i));
|
||||
}
|
||||
|
||||
List<FinancialEntityCategoryView> buildBudgetDataListViews(
|
||||
List<BudgetData> items, BuildContext context) {
|
||||
return [
|
||||
for (var 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((i) => _DetailedEventCard(
|
||||
title: i.title,
|
||||
subtitle: Formatters.date.format(i.date),
|
||||
amount: i.amount,
|
||||
))
|
||||
.toList();
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
elevation: 0.0,
|
||||
centerTitle: true,
|
||||
title: Text(
|
||||
'Checking',
|
||||
style: Theme.of(context).textTheme.body1.copyWith(fontSize: 18.0),
|
||||
),
|
||||
),
|
||||
body: Column(children: [
|
||||
SizedBox(
|
||||
height: 200.0,
|
||||
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) {
|
||||
return FlatButton(
|
||||
onPressed: () {},
|
||||
child: SizedBox(
|
||||
height: 68.0,
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 67.0,
|
||||
child: Row(
|
||||
children: [
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.body1
|
||||
.copyWith(fontSize: 16.0),
|
||||
),
|
||||
Text(
|
||||
subtitle,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.body1
|
||||
.copyWith(color: RallyColors.gray60),
|
||||
)
|
||||
],
|
||||
),
|
||||
Spacer(),
|
||||
Text(
|
||||
'\$${Formatters.usd.format(amount)}',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.body2
|
||||
.copyWith(fontSize: 20.0, color: RallyColors.gray),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
child: SizedBox(
|
||||
height: 1.0,
|
||||
child: Container(
|
||||
color: Color(0xAA282828),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user