wt1.1.2 new treeview, bar chart for muscle development
This commit is contained in:
@@ -3,7 +3,7 @@ import 'dart:collection';
|
||||
import 'package:aitrainer_app/bloc/exercise_add_by_plan_bloc.dart';
|
||||
import 'package:aitrainer_app/bloc/exercise_by_plan/exercise_by_plan_bloc.dart';
|
||||
import 'package:aitrainer_app/localization/app_language.dart';
|
||||
import 'package:aitrainer_app/model/workout_tree.dart';
|
||||
import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/widgets/splash.dart';
|
||||
@@ -25,7 +25,7 @@ class _ExerciseAddByPlanPage extends State<ExerciseAddByPlanPage> with Trans {
|
||||
// ignore: close_sinks
|
||||
final ExerciseByPlanBloc bloc = arguments['blocExerciseByPlan'];
|
||||
final int customerId = arguments['customerId'];
|
||||
final WorkoutTree workoutTree = arguments['workoutTree'];
|
||||
final WorkoutMenuTree workoutTree = arguments['workoutTree'];
|
||||
final ExerciseRepository exerciseRepository = ExerciseRepository();
|
||||
setContext(context);
|
||||
|
||||
@@ -136,38 +136,15 @@ class _ExerciseAddByPlanPage extends State<ExerciseAddByPlanPage> with Trans {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Divider(color: Colors.transparent,),
|
||||
Text("Execute the " + (i+1).toString() + ". set!",
|
||||
Text(t("Execute the") + " " + (i+1).toString() + t(". set!"),
|
||||
style: TextStyle(),),
|
||||
TextFieldBlocBuilder(
|
||||
readOnly: exerciseBloc.step != i+1,
|
||||
textFieldBloc: exerciseBloc.quantity1Field,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.deepOrange,
|
||||
fontWeight: FontWeight.bold),
|
||||
inputFormatters: [
|
||||
WhitelistingTextInputFormatter(RegExp(r"[\d.]"))
|
||||
],
|
||||
|
||||
decoration: InputDecoration(
|
||||
fillColor: Colors.white,
|
||||
filled: false,
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 12, color: Colors.black54, fontWeight: FontWeight.w100),
|
||||
hintText: t("The number of the exercise"),
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.deepOrange, fontWeight: FontWeight.normal),
|
||||
labelText: t("Please repeat with ") + exerciseBloc.unitQuantity1Field.value + " " +
|
||||
exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit + " " +
|
||||
exerciseBloc.exercisePlanRepository.actualPlanDetail.repeats.toString() + " times!",
|
||||
),
|
||||
),
|
||||
TextFieldBlocBuilder(
|
||||
readOnly: exerciseBloc.step != i+1,
|
||||
textFieldBloc: exerciseBloc.unitQuantity1Field,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontSize: 18,
|
||||
color: Colors.black54,
|
||||
fontWeight: FontWeight.bold),
|
||||
inputFormatters: [
|
||||
@@ -178,11 +155,35 @@ class _ExerciseAddByPlanPage extends State<ExerciseAddByPlanPage> with Trans {
|
||||
fillColor: Colors.white,
|
||||
filled: false,
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 12, color: Colors.black54, fontWeight: FontWeight.w100),
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.deepOrange, fontWeight: FontWeight.normal),
|
||||
fontSize: 14, color: Colors.black54, fontWeight: FontWeight.w100),
|
||||
labelStyle: TextStyle(fontSize: 14, color: Colors.deepOrange, fontWeight: FontWeight.normal),
|
||||
labelText: exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit,
|
||||
),
|
||||
),
|
||||
TextFieldBlocBuilder(
|
||||
readOnly: exerciseBloc.step != i+1,
|
||||
textFieldBloc: exerciseBloc.quantity1Field,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
color: Colors.deepOrange,
|
||||
fontWeight: FontWeight.bold),
|
||||
inputFormatters: [
|
||||
WhitelistingTextInputFormatter(RegExp(r"[\d.]"))
|
||||
],
|
||||
|
||||
decoration: InputDecoration(
|
||||
fillColor: Colors.white,
|
||||
filled: false,
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 14, color: Colors.black54, fontWeight: FontWeight.w100),
|
||||
hintText: t("The number of the exercise"),
|
||||
labelStyle: TextStyle(fontSize: 14, color: Colors.deepOrange, fontWeight: FontWeight.normal),
|
||||
labelText: t("Please repeat with") + " "+ exerciseBloc.unitQuantity1Field.value + " " +
|
||||
exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit + " " +
|
||||
exerciseBloc.exercisePlanRepository.getActualPlanDetail().repeats.toString() + " " + t("times!"),
|
||||
),
|
||||
),
|
||||
RaisedButton(
|
||||
|
||||
padding: EdgeInsets.all(0),
|
||||
|
||||
@@ -1,23 +1,25 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:aitrainer_app/bloc/exercise_by_plan/exercise_by_plan_bloc.dart';
|
||||
import 'package:aitrainer_app/localization/app_language.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/workout_tree.dart';
|
||||
import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
||||
import 'package:aitrainer_app/treeview/tree_view.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar_common.dart';
|
||||
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
||||
import 'package:aitrainer_app/widgets/exercise_type_widget.dart';
|
||||
import 'package:aitrainer_app/widgets/splash.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_treeview/tree_view.dart';
|
||||
|
||||
class ExerciseByPlanPage extends StatefulWidget {
|
||||
@override
|
||||
_ExerciseByPlanPage createState() => _ExerciseByPlanPage();
|
||||
}
|
||||
|
||||
class _ExerciseByPlanPage extends State<ExerciseByPlanPage> {
|
||||
class _ExerciseByPlanPage extends State<ExerciseByPlanPage> with Trans {
|
||||
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||
// ignore: close_sinks
|
||||
ExerciseByPlanBloc bloc;
|
||||
@@ -38,21 +40,24 @@ class _ExerciseByPlanPage extends State<ExerciseByPlanPage> {
|
||||
final int customerId = arguments['customerId'];
|
||||
bloc = BlocProvider.of<ExerciseByPlanBloc>(context);
|
||||
bloc.customerId = customerId;
|
||||
setContext(context);
|
||||
|
||||
return Scaffold(
|
||||
key: _scaffoldKey,
|
||||
appBar: AppBarCommonNav(),
|
||||
body: Container(
|
||||
padding: EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: customerId == Cache().userLoggedIn.customerId ? AssetImage('asset/image/WT_light_background.png'):
|
||||
AssetImage('asset/image/WT_menu_dark.png'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
key: _scaffoldKey,
|
||||
appBar: AppBarCommonNav(),
|
||||
body: Container(
|
||||
padding: EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: customerId == Cache().userLoggedIn.customerId
|
||||
? AssetImage('asset/image/WT_light_background.png')
|
||||
: AssetImage('asset/image/WT_menu_dark.png'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
child: BlocConsumer<ExerciseByPlanBloc, ExerciseByPlanState>(listener: (context, state) {
|
||||
),
|
||||
child: BlocConsumer<ExerciseByPlanBloc, ExerciseByPlanState>(
|
||||
listener: (context, state) {
|
||||
if (state is ExerciseByPlanError) {
|
||||
Scaffold.of(context).showSnackBar(SnackBar(
|
||||
content: Text(
|
||||
@@ -64,124 +69,147 @@ class _ExerciseByPlanPage extends State<ExerciseByPlanPage> {
|
||||
LoadingDialog();
|
||||
}
|
||||
},
|
||||
// ignore: missing_return
|
||||
builder: (context, state) {
|
||||
|
||||
builder: (context, state) {
|
||||
if (state is ExerciseByPlanStateInitial || state is ExerciseByPlanLoading) {
|
||||
return Container();
|
||||
} else if (state is ExerciseByPlanReady) {
|
||||
return exerciseWidget(bloc);
|
||||
} else if (state is ExerciseByPlanError) {
|
||||
} else {
|
||||
return exerciseWidget(bloc);
|
||||
}
|
||||
})));
|
||||
})),
|
||||
bottomNavigationBar: BottomNavigator(bottomNavIndex: 2),
|
||||
);
|
||||
}
|
||||
|
||||
Widget exerciseWidget(ExerciseByPlanBloc bloc) {
|
||||
final LinkedHashMap args = LinkedHashMap();
|
||||
TreeViewController _treeViewController = TreeViewController(children: nodeExercisePlan(bloc));
|
||||
|
||||
TreeViewTheme _treeViewTheme = TreeViewTheme(
|
||||
expanderTheme: ExpanderThemeData(
|
||||
type: ExpanderType.plusMinus,
|
||||
modifier: ExpanderModifier.circleOutlined,
|
||||
position: ExpanderPosition.start,
|
||||
color: Colors.black26,
|
||||
size: 10,
|
||||
),
|
||||
labelStyle: TextStyle(fontSize: 14, letterSpacing: 0, color: Colors.blue.shade800),
|
||||
parentLabelStyle: TextStyle(
|
||||
fontSize: 14,
|
||||
letterSpacing: 0.3,
|
||||
fontWeight: FontWeight.w800,
|
||||
color: Colors.orange.shade600,
|
||||
),
|
||||
iconTheme: IconThemeData(
|
||||
size: 20,
|
||||
color: Colors.blue.shade800,
|
||||
),
|
||||
colorScheme: bloc.customerId == Cache().userLoggedIn.customerId ? ColorScheme.light(background: Colors.transparent) : ColorScheme.dark(background: Colors.transparent),
|
||||
);
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.transparent,
|
||||
body: TreeView(
|
||||
controller: _treeViewController,
|
||||
allowParentSelect: false,
|
||||
supportParentDoubleTap: false,
|
||||
//onExpansionChanged: _expandNodeHandler,
|
||||
onNodeTap: (key) {
|
||||
/* Node<dynamic> node = _treeViewController.getNode(key);
|
||||
WorkoutTree workoutTree = node.data as WorkoutTree;
|
||||
bloc.exercisePlanRepository.setActualPlanDetail(workoutTree.exerciseType);
|
||||
print("change node " + node.label + " key " + key);
|
||||
bloc.add(ExercisePlanUpdate(workoutTree: workoutTree));
|
||||
Navigator.of(context).pushNamed("exercisePlanDetailAdd", arguments: bloc); */
|
||||
|
||||
Node<dynamic> node = _treeViewController.getNode(key);
|
||||
WorkoutTree workoutTree = node.data as WorkoutTree;
|
||||
args['blocExerciseByPlan'] = bloc;
|
||||
args['customerId'] = bloc.customerId;
|
||||
args['workoutTree'] = workoutTree;
|
||||
Navigator.of(context).pushNamed("exerciseAddByPlanPage", arguments: args);
|
||||
},
|
||||
|
||||
theme: _treeViewTheme,
|
||||
),
|
||||
//bottomNavigationBar: BottomNavigator(bottomNavIndex: 2),
|
||||
floatingActionButtonLocation: FloatingActionButtonLocation.endDocked,
|
||||
return TreeView(
|
||||
startExpanded: false,
|
||||
children: nodeExercisePlan(bloc),
|
||||
);
|
||||
}
|
||||
|
||||
List<Node> nodeExercisePlan(ExerciseByPlanBloc bloc) {
|
||||
List<Node> nodes = List<Node>();
|
||||
Node actualNode;
|
||||
List<Widget> nodeExercisePlan(ExerciseByPlanBloc bloc) {
|
||||
List<Widget> exerciseTypes = List();
|
||||
bool isEnglish = AppLanguage().appLocal == Locale("en");
|
||||
|
||||
Card explanation = Card(
|
||||
color: Colors.white38,
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(left: 10, right: 5, top: 12, bottom: 8),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.info,
|
||||
color: Colors.orangeAccent,
|
||||
),
|
||||
Text(" "),
|
||||
Flexible(
|
||||
child:
|
||||
Text(
|
||||
t("Execute your active Exercise Plan!"),
|
||||
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
Divider(
|
||||
color: Colors.transparent,
|
||||
),
|
||||
Text(
|
||||
t("Select the muscle type and tap on the exercise. One the next page enter the weight and repeat."),
|
||||
style: TextStyle(fontSize: 12, fontWeight: FontWeight.normal),
|
||||
),
|
||||
],
|
||||
)));
|
||||
|
||||
exerciseTypes.add(explanation);
|
||||
|
||||
bloc.menuTreeRepository.sortedTree.forEach((name, list) {
|
||||
List<WorkoutTree> listWorkoutItem = list;
|
||||
List<Node> listExerciseTypePerMuscle = List<Node>();
|
||||
NodeIcon icon;
|
||||
listWorkoutItem.forEach((element) {
|
||||
|
||||
WorkoutTree treeItem = element;
|
||||
if ( treeItem.selected ) {
|
||||
icon =
|
||||
treeItem.executed == false ? NodeIcon(codePoint: Icons.bubble_chart.codePoint, color: "blueAccent") :
|
||||
NodeIcon(codePoint: Icons.check_box.codePoint, color: "green");
|
||||
|
||||
String exerciseLabel = isEnglish
|
||||
? treeItem.name
|
||||
: treeItem.exerciseType == null ? treeItem.name : treeItem.exerciseType.nameTranslation;
|
||||
|
||||
List<Node<dynamic>> planDetailList = List<Node<dynamic>>();
|
||||
String planDetail = bloc.exercisePlanRepository.getPlanDetail(treeItem.exerciseTypeId);
|
||||
|
||||
if (planDetail.length > 0) {
|
||||
exerciseLabel += " (" + planDetail + ")";
|
||||
}
|
||||
|
||||
actualNode = Node(
|
||||
label: exerciseLabel,
|
||||
key: treeItem.id.toString(),
|
||||
data: treeItem,
|
||||
expanded: planDetailList.length > 0 ? true : false,
|
||||
children: [],
|
||||
icon: icon);
|
||||
listExerciseTypePerMuscle.add(actualNode);
|
||||
}
|
||||
});
|
||||
|
||||
if (name != null) {
|
||||
actualNode = Node(
|
||||
label: name,
|
||||
key: name,
|
||||
expanded: true,
|
||||
children: listExerciseTypePerMuscle,
|
||||
icon: NodeIcon(codePoint: Icons.perm_identity.codePoint, color: "orange"));
|
||||
nodes.add(actualNode);
|
||||
}
|
||||
exerciseTypes.add(
|
||||
Container(
|
||||
margin: const EdgeInsets.only(left: 4.0),
|
||||
child: TreeViewChild(
|
||||
startExpanded: true,
|
||||
parent: ExerciseTypeWidget(exerciseTypeName: name), //_getExerciseWidget(exerciseTypeName: name),
|
||||
children: _getChildList(list, bloc),
|
||||
)));
|
||||
});
|
||||
|
||||
return nodes;
|
||||
return exerciseTypes;
|
||||
}
|
||||
|
||||
List<Widget> _getChildList(List<WorkoutMenuTree> listWorkoutTree, ExerciseByPlanBloc bloc) {
|
||||
List<Widget> list = List();
|
||||
listWorkoutTree.forEach((element) {
|
||||
|
||||
if ( element.selected) {
|
||||
list.add(
|
||||
TreeViewChild(
|
||||
startExpanded: false,
|
||||
parent:
|
||||
Card(
|
||||
margin: EdgeInsets.only(left: 10, top: 5),
|
||||
color: Colors.white54,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.only(left: 5, top: 0, right: 5, bottom: 0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
IconButton(
|
||||
icon: element.executed ? Icon(Icons.check_box, color: Colors.green):
|
||||
Icon(Icons.indeterminate_check_box, color: Colors.blue.shade800,),
|
||||
onPressed: () => {
|
||||
addExerciseByPlanEvent(bloc, element)
|
||||
},
|
||||
),
|
||||
SizedBox(width: 20),
|
||||
Flexible(
|
||||
child:
|
||||
InkWell(
|
||||
child:
|
||||
Text(
|
||||
element.name,
|
||||
textAlign: TextAlign.start,
|
||||
style: TextStyle(fontSize: 12, color: Colors.black),
|
||||
),
|
||||
onTap: () => {
|
||||
addExerciseByPlanEvent(bloc, element)
|
||||
},
|
||||
),
|
||||
|
||||
),
|
||||
IconButton(
|
||||
|
||||
padding: EdgeInsets.all(0),
|
||||
icon: Icon(Icons.description, color: Colors.black12,),
|
||||
onPressed: () {
|
||||
|
||||
},
|
||||
),
|
||||
|
||||
]),
|
||||
)
|
||||
),
|
||||
children: [
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
void addExerciseByPlanEvent(ExerciseByPlanBloc bloc, WorkoutMenuTree workoutTree) {
|
||||
LinkedHashMap args = LinkedHashMap();
|
||||
args['blocExerciseByPlan'] = bloc;
|
||||
args['customerId'] = bloc.customerId;
|
||||
args['workoutTree'] = workoutTree;
|
||||
Navigator.of(context).pushNamed("exerciseAddByPlanPage", arguments: args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import 'package:aitrainer_app/localization/app_language.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/exercise.dart';
|
||||
import 'package:aitrainer_app/model/exercise_type.dart';
|
||||
import 'package:aitrainer_app/repository/customer_repository.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar_common.dart';
|
||||
@@ -21,7 +20,6 @@ class _ExerciseLogPage extends State<ExerciseLogPage> with Trans {
|
||||
Widget build(BuildContext context) {
|
||||
LinkedHashMap arguments = ModalRoute.of(context).settings.arguments;
|
||||
final ExerciseRepository exerciseRepository = arguments['exerciseRepository'];
|
||||
final CustomerRepository customerRepository = arguments['customerRepository'];
|
||||
final int customerId = arguments['customerId'];
|
||||
setContext(context);
|
||||
|
||||
|
||||
+6
-4
@@ -2,6 +2,7 @@ import 'package:aitrainer_app/bloc/exercise_plan/exercise_plan_bloc.dart';
|
||||
import 'package:aitrainer_app/bloc/exercise_plan_custom_form.dart';
|
||||
import 'package:aitrainer_app/localization/app_language.dart';
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_plan_repository.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar_common.dart';
|
||||
@@ -34,8 +35,8 @@ class _ExercisePlanDetailAddPage extends State<ExercisePlanDetailAddPage> with T
|
||||
String exerciseName = "";
|
||||
if (bloc != null) {
|
||||
exerciseName = AppLanguage().appLocal == Locale("en")
|
||||
? bloc.exercisePlanRepository.actualPlanDetail.exerciseType.name
|
||||
: bloc.exercisePlanRepository.actualPlanDetail.exerciseType.nameTranslation;
|
||||
? bloc.exercisePlanRepository.getActualPlanDetail().exerciseType.name
|
||||
: bloc.exercisePlanRepository.getActualPlanDetail().exerciseType.nameTranslation;
|
||||
}
|
||||
|
||||
return Form(
|
||||
@@ -118,9 +119,10 @@ class _ExercisePlanDetailAddPage extends State<ExercisePlanDetailAddPage> with T
|
||||
color: Colors.red.shade300,
|
||||
focusColor: Colors.white,
|
||||
onPressed: () => {
|
||||
print("Remove " + bloc.exercisePlanRepository.actualPlanDetail.exerciseType.name),
|
||||
print("Remove " + bloc.exercisePlanRepository.getActualPlanDetail().exerciseType.name),
|
||||
bloc.exercisePlanRepository.getActualPlanDetail().change = ExercisePlanDetailChange.delete,
|
||||
planBloc.add(ExercisePlanRemoveExercise(
|
||||
exercisePlanDetail: bloc.exercisePlanRepository.actualPlanDetail)),
|
||||
exercisePlanDetail: bloc.exercisePlanRepository.getActualPlanDetail() )),
|
||||
Navigator.of(context).pop(),
|
||||
},
|
||||
child: Text(t(
|
||||
@@ -1,24 +1,26 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:aitrainer_app/bloc/exercise_plan/exercise_plan_bloc.dart';
|
||||
import 'package:aitrainer_app/localization/app_language.dart';
|
||||
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/workout_tree.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
||||
import 'package:aitrainer_app/treeview/tree_view.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar_common.dart';
|
||||
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
||||
import 'package:aitrainer_app/widgets/exercise_type_widget.dart';
|
||||
import 'package:aitrainer_app/widgets/splash.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_treeview/tree_view.dart';
|
||||
|
||||
class ExercisePlanCustomPage extends StatefulWidget {
|
||||
@override
|
||||
_ExercisePlanCustomPage createState() => _ExercisePlanCustomPage();
|
||||
}
|
||||
|
||||
class _ExercisePlanCustomPage extends State<ExercisePlanCustomPage> {
|
||||
class _ExercisePlanCustomPage extends State<ExercisePlanCustomPage> with Trans {
|
||||
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||
// ignore: close_sinks
|
||||
ExercisePlanBloc bloc;
|
||||
@@ -36,10 +38,10 @@ class _ExercisePlanCustomPage extends State<ExercisePlanCustomPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
LinkedHashMap arguments = ModalRoute.of(context).settings.arguments;
|
||||
final ExerciseRepository exerciseRepository = arguments['exerciseRepository'];
|
||||
final int customerId = arguments['customerId'];
|
||||
bloc = BlocProvider.of<ExercisePlanBloc>(context);
|
||||
bloc.customerId = customerId;
|
||||
setContext(context);
|
||||
|
||||
return Scaffold(
|
||||
key: _scaffoldKey,
|
||||
@@ -54,135 +56,158 @@ class _ExercisePlanCustomPage extends State<ExercisePlanCustomPage> {
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
child: BlocConsumer<ExercisePlanBloc, ExercisePlanState>(listener: (context, state) {
|
||||
if (state is ExercisePlanError) {
|
||||
Scaffold.of(context).showSnackBar(SnackBar(
|
||||
content: Text(
|
||||
state.message,
|
||||
),
|
||||
backgroundColor: Colors.orange,
|
||||
));
|
||||
} else if (state is ExercisePlanLoading) {
|
||||
LoadingDialog();
|
||||
}
|
||||
},
|
||||
child: BlocConsumer<ExercisePlanBloc, ExercisePlanState>(
|
||||
listener: (context, state) {
|
||||
if (state is ExercisePlanError) {
|
||||
Scaffold.of(context).showSnackBar(SnackBar(
|
||||
content: Text(
|
||||
state.message,
|
||||
),
|
||||
backgroundColor: Colors.orange,
|
||||
));
|
||||
} else if (state is ExercisePlanLoading) {
|
||||
LoadingDialog();
|
||||
}
|
||||
},
|
||||
// ignore: missing_return
|
||||
builder: (context, state) {
|
||||
if (state is ExercisePlanInitial) {
|
||||
builder: (context, state) {
|
||||
if (state is ExercisePlanReady) {
|
||||
return exerciseWidget(bloc);
|
||||
}
|
||||
return Container();
|
||||
} else if (state is ExercisePlanReady) {
|
||||
return exerciseWidget(bloc);
|
||||
} else if (state is ExercisePlanError) {
|
||||
return exerciseWidget(bloc);
|
||||
} else if (state is ExercisePlanLoading) {
|
||||
return Container();
|
||||
}
|
||||
})));
|
||||
|
||||
}
|
||||
)
|
||||
),
|
||||
bottomNavigationBar: BottomNavigator(bottomNavIndex: 2),
|
||||
);
|
||||
}
|
||||
|
||||
Widget exerciseWidget(ExercisePlanBloc bloc) {
|
||||
TreeViewController _treeViewController = TreeViewController(children: nodeExercisePlan(bloc));
|
||||
|
||||
TreeViewTheme _treeViewTheme = TreeViewTheme(
|
||||
expanderTheme: ExpanderThemeData(
|
||||
type: ExpanderType.plusMinus,
|
||||
modifier: ExpanderModifier.circleOutlined,
|
||||
position: ExpanderPosition.start,
|
||||
color: Colors.black26,
|
||||
size: 10,
|
||||
),
|
||||
labelStyle: TextStyle(fontSize: 14, letterSpacing: 0, color: Colors.blue.shade800),
|
||||
parentLabelStyle: TextStyle(
|
||||
fontSize: 14,
|
||||
letterSpacing: 0.3,
|
||||
fontWeight: FontWeight.w800,
|
||||
color: Colors.orange.shade600,
|
||||
),
|
||||
iconTheme: IconThemeData(
|
||||
size: 20,
|
||||
color: Colors.blue.shade800,
|
||||
),
|
||||
colorScheme: bloc.customerId == Cache().userLoggedIn.customerId ? ColorScheme.light(background: Colors.transparent) : ColorScheme.dark(background: Colors.transparent),
|
||||
);
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.transparent,
|
||||
body: TreeView(
|
||||
controller: _treeViewController,
|
||||
allowParentSelect: true,
|
||||
supportParentDoubleTap: false,
|
||||
//onExpansionChanged: _expandNodeHandler,
|
||||
onNodeTap: (key) {
|
||||
Node<dynamic> node = _treeViewController.getNode(key);
|
||||
WorkoutTree workoutTree = node.data as WorkoutTree;
|
||||
bloc.exercisePlanRepository.setActualPlanDetail(workoutTree.exerciseType);
|
||||
print("change node " + node.label + " key " + key);
|
||||
bloc.add(ExercisePlanUpdate(workoutTree: workoutTree));
|
||||
Navigator.of(context).pushNamed("exercisePlanDetailAdd", arguments: bloc);
|
||||
},
|
||||
theme: _treeViewTheme,
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
backgroundColor: Colors.blueAccent,
|
||||
child: Icon(Icons.save_alt),
|
||||
onPressed: () => {
|
||||
bloc.add(ExercisePlanSave()),
|
||||
if (bloc.exercisePlanRepository.getExercisePlanDetailSize() > 0) {
|
||||
Navigator.of(context).pop()
|
||||
}
|
||||
}
|
||||
),
|
||||
//bottomNavigationBar: BottomNavigator(bottomNavIndex: 2),
|
||||
floatingActionButtonLocation: FloatingActionButtonLocation.endDocked,
|
||||
return TreeView(
|
||||
startExpanded: false,
|
||||
children: _getTreeChildren(bloc),
|
||||
);
|
||||
}
|
||||
|
||||
List<Node> nodeExercisePlan(ExercisePlanBloc bloc) {
|
||||
List<Node> nodes = List<Node>();
|
||||
Node actualNode;
|
||||
bool isEnglish = AppLanguage().appLocal == Locale("en");
|
||||
List<Widget> _getTreeChildren(ExercisePlanBloc bloc) {
|
||||
List<Widget> exerciseTypes = List();
|
||||
|
||||
bloc.menuTreeRepository.sortedTree.forEach((name, list) {
|
||||
List<WorkoutTree> listWorkoutItem = list;
|
||||
List<Node> listExerciseTypePerMuscle = List<Node>();
|
||||
NodeIcon icon;
|
||||
listWorkoutItem.forEach((element) {
|
||||
WorkoutTree treeItem = element;
|
||||
icon =
|
||||
treeItem.selected == true ? NodeIcon(codePoint: Icons.bubble_chart.codePoint, color: "blueAccent") : null;
|
||||
Card explanation = Card(
|
||||
color: Colors.white60,
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(left: 10, right: 5, top: 12, bottom: 8),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.info,
|
||||
color: Colors.orangeAccent,
|
||||
),
|
||||
Text(" "),
|
||||
Text(
|
||||
t("Custom Exercise Plan"),
|
||||
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
Divider(
|
||||
color: Colors.transparent,
|
||||
),
|
||||
Text(
|
||||
t("Select manually the exercises what you would like to have in your plan. At the end don't forget to save."),
|
||||
style: TextStyle(fontSize: 12, fontWeight: FontWeight.normal),
|
||||
),
|
||||
|
||||
String exerciseLabel = isEnglish
|
||||
? treeItem.name
|
||||
: treeItem.exerciseType == null ? treeItem.name : treeItem.exerciseType.nameTranslation;
|
||||
],
|
||||
)
|
||||
)
|
||||
);
|
||||
exerciseTypes.add(explanation);
|
||||
|
||||
List<Node<dynamic>> planDetailList = List<Node<dynamic>>();
|
||||
String planDetail = bloc.exercisePlanRepository.getPlanDetail(treeItem.exerciseTypeId);
|
||||
|
||||
if (planDetail.length > 0) {
|
||||
exerciseLabel += " (" + planDetail +")";
|
||||
}
|
||||
|
||||
actualNode = Node(
|
||||
label: exerciseLabel,
|
||||
key: treeItem.id.toString(),
|
||||
data: treeItem,
|
||||
expanded: planDetailList.length > 0 ? true : false,
|
||||
children: [],
|
||||
icon: icon);
|
||||
listExerciseTypePerMuscle.add(actualNode);
|
||||
});
|
||||
//print ("Node name " + name);
|
||||
if (name != null) {
|
||||
actualNode = Node(
|
||||
label: name, // AppLocalizations.of(context).translate(name),
|
||||
key: name,
|
||||
expanded: true,
|
||||
children: listExerciseTypePerMuscle,
|
||||
icon: NodeIcon(codePoint: Icons.perm_identity.codePoint, color: "orange"));
|
||||
nodes.add(actualNode);
|
||||
}
|
||||
bloc.menuTreeRepository.sortedTree.forEach((name, list) {
|
||||
exerciseTypes.add(Container(
|
||||
margin: const EdgeInsets.only(left: 4.0),
|
||||
child: TreeViewChild(
|
||||
startExpanded: true,
|
||||
parent: ExerciseTypeWidget(exerciseTypeName: name),
|
||||
children: _getChildList(list, bloc),
|
||||
)));
|
||||
});
|
||||
|
||||
return nodes;
|
||||
return exerciseTypes;
|
||||
}
|
||||
|
||||
List<Widget> _getChildList(List<WorkoutMenuTree> listWorkoutTree, ExercisePlanBloc bloc) {
|
||||
List<Widget> list = List();
|
||||
listWorkoutTree.forEach((element) {
|
||||
|
||||
list.add(
|
||||
TreeViewChild(
|
||||
startExpanded: false,
|
||||
parent:
|
||||
Card(
|
||||
margin: EdgeInsets.only(left: 10, top: 5),
|
||||
color: Colors.white54,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.only(left: 5, top: 0, right: 5, bottom: 0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
IconButton(
|
||||
icon: element.selected ? Icon(Icons.check, color: Colors.greenAccent.shade700,) : Icon(Icons.add, color: Colors.blue.shade400,),
|
||||
onPressed: () => {
|
||||
bloc.add(ExercisePlanUpdateUI(workoutTree: element)),
|
||||
Navigator.of(context).pushNamed("exercisePlanDetailAdd", arguments: bloc),
|
||||
},
|
||||
),
|
||||
SizedBox(width: 20),
|
||||
Flexible(
|
||||
child:
|
||||
InkWell(
|
||||
child:
|
||||
Text(
|
||||
element.name,
|
||||
textAlign: TextAlign.start,
|
||||
style: TextStyle(fontSize: 12, color: Colors.black),
|
||||
),
|
||||
onTap: () => {
|
||||
bloc.add(ExercisePlanUpdateUI(workoutTree: element)),
|
||||
Navigator.of(context).pushNamed("exercisePlanDetailAdd", arguments: bloc),
|
||||
},
|
||||
),
|
||||
),
|
||||
InkWell(
|
||||
child:
|
||||
element.selected && bloc.exercisePlanRepository.exercisePlanDetails[element.exerciseTypeId].change != null ?
|
||||
Text(bloc.exercisePlanRepository.exercisePlanDetails[element.exerciseTypeId].repeats.toString() +
|
||||
" x " + bloc.exercisePlanRepository.exercisePlanDetails[element.exerciseTypeId].weightEquation +
|
||||
" " + element.exerciseType.unitQuantityUnit, style: TextStyle(fontSize: 9, color: Colors.green),) : Text(""),
|
||||
onTap: () => {
|
||||
bloc.add(ExercisePlanUpdateUI(workoutTree: element)),
|
||||
Navigator.of(context).pushNamed("exercisePlanDetailAdd", arguments: bloc),
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
|
||||
padding: EdgeInsets.all(0),
|
||||
icon: Icon(Icons.description, color: Colors.black12,),
|
||||
onPressed: () {
|
||||
|
||||
},
|
||||
),
|
||||
|
||||
]),
|
||||
)
|
||||
),
|
||||
children: [
|
||||
]
|
||||
)
|
||||
);
|
||||
|
||||
});
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,322 @@
|
||||
import 'dart:collection';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/widgets/exercise_type_widget.dart';
|
||||
import 'package:fl_chart/fl_chart.dart';
|
||||
import 'package:aitrainer_app/util/common.dart';
|
||||
import 'package:aitrainer_app/bloc/development_by_muscle/development_by_muscle_bloc.dart';
|
||||
import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
||||
import 'package:aitrainer_app/treeview/tree_view.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar_common.dart';
|
||||
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
||||
import 'package:aitrainer_app/widgets/splash.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
|
||||
|
||||
class MyDevelopmentMusclePage extends StatefulWidget {
|
||||
@override
|
||||
_MyDevelopmentMuscleState createState() => _MyDevelopmentMuscleState();
|
||||
}
|
||||
|
||||
class _MyDevelopmentMuscleState extends State<MyDevelopmentMusclePage> with Common, Trans {
|
||||
// ignore: close_sinks
|
||||
DevelopmentByMuscleBloc bloc;
|
||||
double cWidth;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
/// We require the initializers to run after the loading screen is rendered
|
||||
SchedulerBinding.instance.addPostFrameCallback((_) {
|
||||
BlocProvider.of<DevelopmentByMuscleBloc>(context).add(DevelopmentByMuscleLoad());
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
bloc = BlocProvider.of<DevelopmentByMuscleBloc>(context);
|
||||
cWidth = mediaSizeWidth(context);
|
||||
setContext(context);
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBarCommonNav(),
|
||||
body: Container(
|
||||
padding: EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_menu_dark.png'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
child: BlocConsumer<DevelopmentByMuscleBloc, DevelopmentByMuscleState>(
|
||||
listener: (context, state) {
|
||||
if (state is DevelopmentByMuscleErrorState) {
|
||||
Scaffold.of(context).showSnackBar(SnackBar(
|
||||
content: Text(
|
||||
state.message,
|
||||
),
|
||||
backgroundColor: Colors.orange,
|
||||
));
|
||||
} else if (state is DevelopmentByMuscleLoadingState) {
|
||||
LoadingDialog();
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
if (state is DevelopmentByMuscleStateInitial) {
|
||||
return Container();
|
||||
} else {
|
||||
return TreeView(
|
||||
startExpanded: false,
|
||||
children: _getTreeChildren(bloc.workoutTreeRepository.sortedTree, bloc),
|
||||
);
|
||||
}
|
||||
;
|
||||
},
|
||||
),
|
||||
),
|
||||
bottomNavigationBar: BottomNavigator(bottomNavIndex: 1),
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> _getTreeChildren(SplayTreeMap tree, DevelopmentByMuscleBloc bloc) {
|
||||
List<Widget> exerciseTypes = List();
|
||||
|
||||
Card explanation = Card(
|
||||
color: Colors.white60,
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(left: 10, right: 5, top: 12),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.info,
|
||||
color: Colors.orangeAccent,
|
||||
),
|
||||
Text(" "),
|
||||
Text(
|
||||
t("My Development By Muscle"),
|
||||
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
Divider(
|
||||
color: Colors.transparent,
|
||||
),
|
||||
Text(
|
||||
t("Here you see you development in the last period."),
|
||||
style: TextStyle(fontSize: 12, fontWeight: FontWeight.normal),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
ChoiceChip(
|
||||
avatar: Icon(Icons.bubble_chart,),
|
||||
label: Text(t('Sum Of Mass')),
|
||||
|
||||
labelStyle: TextStyle(fontSize: 9,color: Colors.black),
|
||||
selectedColor: Colors.lightBlueAccent,
|
||||
selected: bloc.diagramType == DiagramType.sumMass,
|
||||
onSelected: (value) => {
|
||||
bloc.add(DevelopmentByMuscleDiagramTypeChange(diagramType: DiagramType.sumMass))
|
||||
},
|
||||
),
|
||||
ChoiceChip(
|
||||
avatar: Icon(Icons.accessibility_new),
|
||||
label: Text(t('One Max Rep')),
|
||||
labelStyle: TextStyle(fontSize: 9,color: Colors.black),
|
||||
selectedColor: Colors.lightBlueAccent,
|
||||
selected: bloc.diagramType == DiagramType.oneRepMax,
|
||||
onSelected: (value) => {
|
||||
bloc.add(DevelopmentByMuscleDiagramTypeChange(diagramType: DiagramType.oneRepMax))
|
||||
},
|
||||
),
|
||||
ChoiceChip(
|
||||
avatar: Icon(Icons.perm_device_information),
|
||||
label: Text(t('Percent')),
|
||||
labelStyle: TextStyle(fontSize: 9,color: Colors.black),
|
||||
selectedColor: Colors.lightBlueAccent,
|
||||
selected: bloc.diagramType == DiagramType.percent,
|
||||
onSelected: (value) => {
|
||||
bloc.add(DevelopmentByMuscleDiagramTypeChange(diagramType: DiagramType.percent))
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
ChoiceChip(
|
||||
avatar: Icon(Icons.timer),
|
||||
label: Text(t('Detailed')),
|
||||
labelStyle: TextStyle(fontSize: 9, color: Colors.black),
|
||||
disabledColor: Colors.black26,
|
||||
selectedColor: Colors.greenAccent,
|
||||
selected: bloc.dateRate == DateRate.daily,
|
||||
onSelected: (value) => {
|
||||
bloc.add(DevelopmentByMuscleDateRateChange(dateRate: DateRate.daily))
|
||||
},
|
||||
|
||||
),
|
||||
ChoiceChip(
|
||||
avatar: Icon(Icons.timer),
|
||||
label: Text(t('Weekly')),
|
||||
labelStyle: TextStyle(fontSize: 9, color: Colors.black),
|
||||
selectedColor: Colors.greenAccent,
|
||||
disabledColor: Colors.white12,
|
||||
tooltip: "Heti bontás",
|
||||
selected: bloc.dateRate == DateRate.weekly,
|
||||
onSelected: (value) => {
|
||||
bloc.add(DevelopmentByMuscleDateRateChange(dateRate: DateRate.weekly))
|
||||
},
|
||||
|
||||
),
|
||||
ChoiceChip(
|
||||
avatar: Icon(Icons.timer),
|
||||
label: Text(t('Monthly')),
|
||||
labelStyle: TextStyle(fontSize: 9, color: Colors.black),
|
||||
selectedColor: Colors.greenAccent,
|
||||
disabledColor: Colors.black26,
|
||||
selected: bloc.dateRate == DateRate.monthly,
|
||||
onSelected: (value) => {
|
||||
bloc.add(DevelopmentByMuscleDateRateChange(dateRate: DateRate.monthly))
|
||||
},
|
||||
|
||||
),
|
||||
ChoiceChip(
|
||||
avatar: Icon(Icons.timer),
|
||||
label: Text(t('Yearly')),
|
||||
labelStyle: TextStyle(fontSize: 9, color: Colors.black),
|
||||
selectedColor: Colors.greenAccent,
|
||||
disabledColor: Colors.white70,
|
||||
selected: bloc.dateRate == DateRate.yearly,
|
||||
onSelected: (value) => {
|
||||
bloc.add(DevelopmentByMuscleDateRateChange(dateRate: DateRate.yearly))
|
||||
},
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
)
|
||||
)
|
||||
);
|
||||
exerciseTypes.add(explanation);
|
||||
|
||||
tree.forEach((name, list) {
|
||||
List<WorkoutMenuTree> listWorkoutMenuTree = list;
|
||||
exerciseTypes.add(Container(
|
||||
margin: const EdgeInsets.only(left: 4.0),
|
||||
child: TreeViewChild(
|
||||
startExpanded: true,
|
||||
parent: _getExerciseWidget(exerciseTypeName: name),
|
||||
children: _getChildList(list, bloc),
|
||||
)));
|
||||
});
|
||||
|
||||
return exerciseTypes;
|
||||
}
|
||||
|
||||
Widget _getExerciseWidget({@required String exerciseTypeName, List<WorkoutMenuTree> list}) {
|
||||
return ExerciseTypeWidget(exerciseTypeName: exerciseTypeName);
|
||||
}
|
||||
|
||||
List<Widget> _getChildList(List<WorkoutMenuTree> listWorkoutTree, DevelopmentByMuscleBloc bloc) {
|
||||
List<Widget> list = List();
|
||||
listWorkoutTree.forEach((element) {
|
||||
bool hasNoData = (bloc.listChartData[element.exerciseTypeId] == null);
|
||||
String unit = " kg";
|
||||
if ( bloc.diagramType == DiagramType.percent) {
|
||||
unit = " %";
|
||||
}
|
||||
list.add(SizedBox(
|
||||
width: cWidth * 0.85,
|
||||
height: hasNoData ? 0 : 200,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.only(left:5, top:5, right:5, bottom: 5),
|
||||
color: Colors.white70,
|
||||
child: Column(mainAxisSize: MainAxisSize.min, children: [
|
||||
hasNoData
|
||||
? Container()
|
||||
: Text(
|
||||
element.exerciseType.nameTranslation,
|
||||
style: TextStyle(color: Colors.deepOrange),
|
||||
),
|
||||
hasNoData
|
||||
? Container(
|
||||
//child: Text("no data for " + element.exerciseType.nameTranslation),
|
||||
)
|
||||
: Expanded(
|
||||
//fit: FlexFit.loose,
|
||||
child: BarChart(
|
||||
BarChartData(
|
||||
alignment: BarChartAlignment.spaceAround,
|
||||
barTouchData: BarTouchData(
|
||||
touchTooltipData: BarTouchTooltipData(
|
||||
tooltipBgColor: Colors.white70,
|
||||
getTooltipItem: (group, groupIndex, rod, rodIndex) {
|
||||
return BarTooltipItem(
|
||||
rod.y.toStringAsFixed(0) + unit,
|
||||
TextStyle(color: Colors.black54, fontSize: 12, fontWeight: FontWeight.bold),
|
||||
);
|
||||
}),
|
||||
),
|
||||
titlesData: FlTitlesData(
|
||||
show: true,
|
||||
bottomTitles: SideTitles(
|
||||
showTitles: true,
|
||||
textStyle: TextStyle(fontSize: 8, color: Colors.blueGrey),
|
||||
getTitles: (double value) {
|
||||
var date = new DateTime.fromMillisecondsSinceEpoch(value.toInt());
|
||||
//String strDate = DateFormat('MM.dd.', AppLanguage().appLocal.toString()).format(date);
|
||||
String strDate = bloc.getDatePart(date);
|
||||
return strDate;
|
||||
},
|
||||
),
|
||||
leftTitles: SideTitles(
|
||||
showTitles: true,
|
||||
textStyle: TextStyle(fontSize: 8, color: Colors.blueGrey),
|
||||
interval: bloc.listChartData[element.exerciseTypeId] == null
|
||||
? 100
|
||||
: bloc.listChartData[element.exerciseTypeId].interval,
|
||||
margin: 10,
|
||||
getTitles: (double value) {
|
||||
return value.toStringAsFixed(0) + unit;
|
||||
})),
|
||||
borderData: FlBorderData(
|
||||
show: false,
|
||||
),
|
||||
gridData: FlGridData(
|
||||
show: true,
|
||||
checkToShowHorizontalLine: (value) =>
|
||||
value % bloc.listChartData[element.exerciseTypeId].gridInterval == 0,
|
||||
getDrawingHorizontalLine: (value) {
|
||||
return FlLine(
|
||||
color: Colors.black26,
|
||||
strokeWidth: 0.5,
|
||||
);
|
||||
},
|
||||
),
|
||||
groupsSpace: 2,
|
||||
barGroups: bloc.listChartData[element.exerciseTypeId] == null
|
||||
? []
|
||||
: bloc.listChartData[element.exerciseTypeId].data,
|
||||
),
|
||||
swapAnimationDuration: Duration(milliseconds: 1200),
|
||||
),
|
||||
)
|
||||
]),
|
||||
),
|
||||
));
|
||||
});
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import 'package:aitrainer_app/widgets/app_bar_common.dart';
|
||||
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class MyDevelopmentPage extends StatefulWidget {
|
||||
@override
|
||||
@@ -84,10 +85,10 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
|
||||
fit: StackFit.passthrough,
|
||||
overflow: Overflow.clip,
|
||||
children: [
|
||||
Image.asset('asset/image/lock.png',
|
||||
/*Image.asset('asset/image/lock.png',
|
||||
height: 40,
|
||||
width: 40,
|
||||
),
|
||||
),*/
|
||||
FlatButton(
|
||||
padding: EdgeInsets.all(20),
|
||||
textColor: Colors.white,
|
||||
@@ -95,6 +96,8 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
|
||||
focusColor: Colors.blueAccent,
|
||||
onPressed: () =>
|
||||
{
|
||||
Navigator.of(context).pushNamed('mydevelopmentMusclePage',
|
||||
arguments: args)
|
||||
},
|
||||
child: Text(t("Development Of Muscles"),
|
||||
style: TextStyle(fontSize: 18),)
|
||||
|
||||
Reference in New Issue
Block a user