Files
checker/lib/base_state.dart

155 lines
6.7 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'common.dart';
import 'consts.dart';
import 'strings.dart';
abstract class BaseState<T extends StatefulWidget> extends State<T> {
/// Ожидание ответа от сервера.
bool loading = false;
/// Текст ошибки, подставляется в подсказку, либо появляется над текстовым полем.
String error;
/// Введенное пользователем значение.
String textFieldValue = '';
Strings s;
@override Widget build(BuildContext ctx) {
return new Scaffold(appBar: getAppBar(ctx),
body: new Stack(children: <Widget>[
getScreenContent(ctx),
new Center(child: loading ? new CircularProgressIndicator() : null)
]));
}
/// Возвращает контейнер с всеми виджетами экрана.
Widget getScreenContent(BuildContext ctx);
/// Возвращает заголовок для AppBar
String getTitle(BuildContext ctx);
AppBar getAppBar(BuildContext ctx) {
return new AppBar(title: new Text(getTitle(ctx), style: new TextStyle(fontSize: 18.0)),
backgroundColor: primaryColor, actions: getMenuButtons(ctx));
}
List<Widget> getMenuButtons(BuildContext context) {
return <Widget>[getFaqButton()];
}
Widget getFaqButton() {
return new IconButton(icon: new Icon(Icons.help_outline), onPressed: () => faq(context, false));
}
Widget getLogoutButton() {
return new IconButton(icon: new Image.asset(logout_png, height: iconHeight, width: iconHeight), onPressed: () => logout(context));
}
/// Возврвщает контейнер, внутри которого Text с подсказкой.
Widget getHintLabel(BuildContext ctx) {
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(getHintString(ctx), textAlign: TextAlign.left,
style: new TextStyle(fontWeight: FontWeight.w300, color: error == null ? greyTextColor : primaryColor, fontSize: 14.0))]));
}
/// Возвращает подсказку, либо ошибку, если введенные в поле ввода данные неверны.
String getHintString(BuildContext ctx) {
if (textFieldValue.length == 0 && error == null) {
return ' ';
} else if (error != null) {
return error;
} else {
return getHint(ctx);
}
}
/// Возвращает текст подсказки для поля ввода.
/// Должен быть переопределен на экранах, на которых есть поле ввода.
String getHint(BuildContext ctx) {
return null;
}
/// Смена состояния экрана при изменении текста в поле ввода.
void handleUserInput(String text) {
setState(() {
textFieldValue = text;
});
}
/// Метод возвращает контейнер с полем ввода внутри.
Widget getInputField(BuildContext ctx) {
return new Container(margin: new EdgeInsets.only(left: verticalMargin, right: verticalMargin),
padding: getInputFieldContainerPadding(),
decoration: getInputFieldContainerDecoration(),
child: new TextField(keyboardType: TextInputType.number,
decoration: new InputDecoration.collapsed(hintText: getHint(ctx),
hintStyle: new TextStyle(color: greyTextColor, fontSize: 16.0)),
onChanged: (text) => handleUserInput(text)));
}
/// Возвращат паддинги для поля ввода.
EdgeInsets getInputFieldContainerPadding() {
const double verticalPadding = 12.0;
const double horizontalPadding = 16.0;
return new EdgeInsets.only(top: verticalPadding,
bottom: verticalPadding,
left: horizontalPadding,
right: horizontalPadding);
}
/// Метод возвращает BoxDecoration для _getDecoratedInputField
BoxDecoration getInputFieldContainerDecoration() {
return new BoxDecoration(color: inputFieldBackground,
border: new Border.all(color: textBorderColor, width: 1.0),
borderRadius: new BorderRadius.all(new Radius.circular(4.0)));
}
/// Возвращает выпуклую залитую фирменным цветом кнопку
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 getLogo() {
double containerHeight = 92.0;
double imageWidth = 156.0;
return new Container(height: containerHeight, child: new Image.asset(logo_png, width: imageWidth));
}
/// Возвращает текстовое поле, с однострочным пояснением над ним.
Widget getValueWithDescription(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: getDescriptionWidget(title)),
new Row(crossAxisAlignment: CrossAxisAlignment.start, children: getValueWidget(value))
]));
}
/// Возвращает список, единственный элемент которого - Text с заголовком для текстового поля.
List<Widget> getDescriptionWidget(String title) {
return <Widget>[new Text(title, textAlign: TextAlign.left, style: new TextStyle(color: greyTextColor, fontSize: 14.0))]
}
/// Возвращает список, единственный элемент которого - Text с информацией (размер скидки, сумма проведенной покупки).
List<Widget> getValueWidget(String value) {
return <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)]));
}
}