150 lines
5.5 KiB
Dart
150 lines
5.5 KiB
Dart
import 'package:flutter/material.dart';
|
||
import 'package:flutter/services.dart';
|
||
|
||
import 'common.dart';
|
||
import 'network.dart';
|
||
import 'consts.dart';
|
||
|
||
abstract class BaseState<T> extends State<T> {
|
||
|
||
bool loading = false;
|
||
String error = null;
|
||
String textFieldValue = '';
|
||
|
||
TextEditingController controller = new TextEditingController();
|
||
|
||
@override Widget build(BuildContext context) {
|
||
return new Scaffold(appBar: getAppBar(context), body: getBody(context));
|
||
}
|
||
|
||
AppBar getAppBar(BuildContext context) {
|
||
return new AppBar(title: new Text(getTitle(), style: new TextStyle(fontSize: 18.0)),
|
||
backgroundColor: primaryColor, actions: getMenuButtons(context));
|
||
}
|
||
|
||
@overide getMenuButtons(BuildContext context) {
|
||
return <Widget>[getFaqButton()];
|
||
}
|
||
|
||
getFaqButton() {
|
||
return new IconButton(icon: new Icon(Icons.help_outline), onPressed: () => faq(context, false));
|
||
}
|
||
|
||
getLogoutButton() {
|
||
return new IconButton(icon: new Image.asset(logout_png, height: iconHeight, width: iconHeight), onPressed: () => logout(context));
|
||
}
|
||
|
||
Widget getBody(BuildContext context) {
|
||
return new Stack(children: <Widget>[getScreenContent(), getProgressIndicator()]);
|
||
}
|
||
|
||
Widget getScreenContent(BuildContext context);
|
||
|
||
String getTitle();
|
||
|
||
String getHint();
|
||
|
||
/// Метод возвращает контейнер с отступами, который содержит картинку с логотипом.
|
||
getLogo() {
|
||
double containerHeight = 92.0;
|
||
double imageWidth = 156.0;
|
||
return new Container(height: containerHeight, child: new Image.asset(logo_png, width: imageWidth));
|
||
}
|
||
|
||
getHintLabel() {
|
||
double horizontalMargin = 8.0;
|
||
return new Container(margin: new EdgeInsets.only(top: horizontalMargin, bottom: horizontalMargin, left: verticalMargin, right: verticalMargin),
|
||
child: new Row(crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: <Widget>[new Text(getHintText(), textAlign: TextAlign.left,
|
||
style: new TextStyle(fontWeight: FontWeight.w300, color: error == null ? greyTextColor : primaryColor, fontSize: 14.0))]));
|
||
}
|
||
|
||
getHintText() {
|
||
if (textFieldValue.length == 0 && error == null) {
|
||
return ' ';
|
||
} else if (error != null) {
|
||
return error;
|
||
} else {
|
||
return getHint();
|
||
}
|
||
}
|
||
|
||
/// Смена состояния экрана при изменении текста в поле ввода.
|
||
handleUserInput(String text) {
|
||
setState(() {
|
||
textFieldValue = text;
|
||
});
|
||
}
|
||
|
||
/// Метод возвращает контейнер с установленными отступами, в котором размещен TextField обернутый в BoxDecoration.
|
||
getDecoratedTextWidget() {
|
||
return new Container(margin: new EdgeInsets.only(left: verticalMargin, right: verticalMargin),
|
||
padding: getPaddingForTextWidget(),
|
||
decoration: getDecoraionForTextWidget(),
|
||
child: getTextWidget());
|
||
}
|
||
|
||
getPaddingForTextWidget() {
|
||
const double verticalPadding = 12.0;
|
||
const double horizontalPadding = 16.0;
|
||
return new EdgeInsets.only(top: verticalPadding,
|
||
bottom: verticalPadding,
|
||
left: horizontalPadding,
|
||
right: horizontalPadding);
|
||
}
|
||
|
||
/// Метод возвращает BoxDecoration для _getDecoratedInputField
|
||
getDecoraionForTextWidget() {
|
||
return new BoxDecoration(color: getTextFilledBackground(),
|
||
border: new Border.all(color: textBorderColor, width: 1.0),
|
||
borderRadius: new BorderRadius.all(new Radius.circular(4.0)));
|
||
}
|
||
|
||
Color getTextFilledBackground() {
|
||
return const Color(0xffefefef);
|
||
}
|
||
|
||
Widget getTextWidget() {
|
||
return new TextField(keyboardType: TextInputType.number,
|
||
decoration: new InputDecoration.collapsed(hintText: getHint(),
|
||
hintStyle: new TextStyle(color: greyTextColor, fontSize: 16.0)),
|
||
onChanged: (text) => handleUserInput(text));
|
||
}
|
||
|
||
Widget getProgressIndicator() {
|
||
return new Center(child: loading ? new CircularProgressIndicator() : null);
|
||
}
|
||
|
||
Widget getValueWithTitle(String title, String value) {
|
||
return new Container(padding: new EdgeInsets.only(left: verticalMargin, right: verticalMargin, top: 18.0),
|
||
child: new Column(children: <Widget>[
|
||
new Row(crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[new Text(title, textAlign: TextAlign.left, style: new TextStyle(color: greyTextColor, fontSize: 14.0))]),
|
||
new Row(crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[new Expanded(child: new Text(value, textAlign: TextAlign.left, style: new TextStyle(color: Colors.black, fontSize: 20.0)))])
|
||
]));
|
||
}
|
||
|
||
Widget buildButton(EdgeInsets margin, Widget widget) {
|
||
return new Container(margin: margin, height: buttonHeight, child: new Row(children: <Widget>[new Expanded(child: widget)]));
|
||
}
|
||
|
||
Widget buildRaisedButton(BuildContext context, String text, VoidCallback onPressed) {
|
||
return new RaisedButton(child: new Text(text,
|
||
style: new TextStyle(color: Colors.white)),
|
||
onPressed: onPressed,
|
||
color: primaryColor);
|
||
}
|
||
|
||
Widget buildFlatButton(BuildContext context, String title, Color textColor) {
|
||
return new Container(height: buttonHeight, child: new FlatButton(child: new Text(title,
|
||
style: new TextStyle(color: textColor)),
|
||
onPressed: () => startScanner(context)),
|
||
decoration: _getDecoraionForScanButton());
|
||
}
|
||
|
||
_getDecoraionForScanButton() {
|
||
return new BoxDecoration(
|
||
border: new Border.all(color: primaryColor, width: 1.0),
|
||
borderRadius: new BorderRadius.all(new Radius.circular(4.0)));
|
||
}
|
||
}
|