import 'dart:ui'; import 'package:dartin/dartin.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; import 'package:sport/services/api/rest_client.dart'; import 'package:sport/utils/toast.dart'; import 'package:sport/widgets/appbar.dart'; import 'package:sport/widgets/button_primary.dart'; import 'package:sport/widgets/dialog/alert_dialog.dart'; import 'package:sport/widgets/dialog/request_dialog.dart'; import 'package:sport/widgets/misc.dart'; class DurationSettingPage extends StatefulWidget { @override State createState() => _PageState(); } class _PageState extends State with SingleTickerProviderStateMixin { TabController _controller; @override void initState() { super.initState(); _controller = new TabController(length: 2, vsync: this)..addListener(() { setState(() { }); }); } @override void dispose() { super.dispose(); _controller?.dispose(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, appBar: buildAppBar(context, title: "设定目标"), body: Padding( padding: const EdgeInsets.all(12.0), child: Column( children: [ Center( child: TabBar( controller: _controller, isScrollable: true, indicatorPadding: EdgeInsets.symmetric(horizontal: 10.0), indicatorWeight: 3, unselectedLabelColor: Color(0xff999999), labelStyle: TextStyle(fontSize: 18.0, fontWeight: FontWeight.w600), unselectedLabelStyle: TextStyle(fontSize: 18.0, fontWeight: FontWeight.w600), labelPadding: EdgeInsets.symmetric(vertical: 0.0, horizontal: 30.0), // indicator: const BoxDecoration(), // labelPadding: EdgeInsets.all(20.0), tabs: [ Tab( icon: Image.asset("lib/assets/img/setgoals_icon_duration_${_controller.index == 0 ? "press" : "normal"}.png"), text: "时长", iconMargin: EdgeInsets.only(bottom: 3.0), ), Tab( icon: Image.asset("lib/assets/img/setgoals_icon_consume_${_controller.index == 1 ? "press" : "normal"}.png"), text: "卡路里", iconMargin: EdgeInsets.only(bottom: 3.0), ) ], ), ), Divider(), Expanded( child: Container( padding: const EdgeInsets.only(top: 30.0), child: TabBarView( controller: _controller, physics: NeverScrollableScrollPhysics(), children: [ _Form(type: 0, unit: "分钟", items: [20, 40, 60, 80, 100, 120]), _Form(type: 1, unit: "卡", items: [100, 150, 200, 250, 300, 350]), ], ), ), ) ], ), ), ); } } class _Form extends StatefulWidget { final int type; final String unit; final List items; const _Form({Key key, this.type, this.unit, this.items}) : super(key: key); @override State createState() => _FormState(); } class _FormState extends State<_Form> { ValueNotifier _valueTotal = ValueNotifier(0); ValueNotifier _valueIndex = ValueNotifier(0); TextEditingController _controller; @override void initState() { super.initState(); _controller = TextEditingController(); if (widget.type == 0) { _valueTotal.value = 20; } else { _valueTotal.value = 100; } } @override void dispose() { super.dispose(); _valueIndex?.dispose(); } @override Widget build(BuildContext context) { return Column( children: [ Row( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.end, children: [ ValueListenableBuilder( valueListenable: _valueTotal, builder: (_, value, ___) => Text( "$value", style: Theme.of(context).textTheme.headline1.copyWith(fontSize: 40.0), ), ), Padding( padding: const EdgeInsets.all(6.0), child: Text( widget.unit, style: Theme.of(context).textTheme.subtitle2, ), ), ], ), GestureDetector( onTap: () async { if (await showDialog( context: context, builder: (context) => CustomAlertDialog( child: Padding( padding: const EdgeInsets.fromLTRB(16.0, 32.0, 16.0, 0), child: TextField( textAlign: TextAlign.center, controller: _controller, keyboardType: TextInputType.number, autofocus: true, maxLength: 4, inputFormatters: [WhitelistingTextInputFormatter.digitsOnly], decoration: InputDecoration( counterText: '', helperText: '', helperMaxLines: 1, focusedBorder: UnderlineInputBorder( borderSide: BorderSide(color: Theme.of(context).accentColor), ))), ), ok: () => Navigator.of(context).pop(true)), ) == true) { var val = _controller.text.trim(); if (val.isEmpty == true) return; _valueTotal.value = int.parse(val); _valueIndex.value = -1; } }, child: Container( width: 80.0, height: 30.0, margin: const EdgeInsets.all(8.0), decoration: BoxDecoration( borderRadius: BorderRadius.circular(20), border: Border.all( color: Theme.of(context).accentColor, width: .5, ), ), child: Center(child: Text("自定义", style: Theme.of(context).textTheme.subtitle1.copyWith(color: Theme.of(context).accentColor), strutStyle: fixedLine,)), ), ), const SizedBox( height: 15.0, ), Padding( padding: const EdgeInsets.symmetric(vertical: 20.0), child: ValueListenableBuilder( valueListenable: _valueIndex, builder: (_, value, __) => StaggeredGridView.countBuilder( padding: EdgeInsets.zero, shrinkWrap: true, physics: NeverScrollableScrollPhysics(), crossAxisCount: 3, itemCount: widget.items.length, itemBuilder: (BuildContext context, int index) => GestureDetector( onTap: () { _valueIndex.value = index; _valueTotal.value = widget.items[index]; }, child: Center( child: Container( height: 66.0, decoration: BoxDecoration( image: value == index ? DecorationImage(image: AssetImage("lib/assets/img/control_img_selected.png"), alignment: Alignment.bottomRight) : null, borderRadius: BorderRadius.circular(10), border: Border.all( color: value == index ? Theme.of(context).accentColor : const Color(0xffCECECE), width: .5, ), ), child: Center( child: Text("${widget.items[index]}${widget.unit}", style: value == index ? Theme.of(context).textTheme.subtitle1.copyWith(fontSize: 16.0, color: Theme.of(context).accentColor) : Theme.of(context).textTheme.subtitle1.copyWith(fontSize: 16.0))), )), ), crossAxisSpacing: 12.0, mainAxisSpacing: 12.0, staggeredTileBuilder: (int index) => StaggeredTile.fit(1), ), ), ), PrimaryButton( height: 44.0, content: "确定", callback: () async { await request(context, () async { if (widget.type == 0) { await inject().setSportTargetToday("duration", durationMinute: _valueTotal.value); } else { await inject().setSportTargetToday("consume", consume: _valueTotal.value); } ToastUtil.show("提交信息成功"); }); Navigator.pop(context, true); }, ) ], ); } }