Сделал возможность переключаться между приложениями и добавлять новые приложения практически не меняя код

This commit is contained in:
Ivan Murashov
2017-09-07 15:35:13 +03:00
parent 8d81fb185d
commit 361bcd48ce
22 changed files with 304 additions and 140 deletions

View File

@@ -1 +1,12 @@
Кроссплатформенное приложение AUTOBONUS для Dinect. Приложение Checker.
Для запуска необходимо установить [Dart](https://www.dartlang.org/install) - язык программирования и
[flutter](https://flutter.io/setup/) - фреймворк для создания кроссплатформенных мобильных приложений на этом языке.
# Перед тем, как собирать приложение, необходимо в файле lib/consts.dart установить правильное значение appName. Для автоклуба - это AutoBonus.
Для сборки и запуска приложения используются команды flutter run (собирает debug apk, устанавливает его на устройство) и
flutter build (собирает release apk, не устанавливает на устрйоство).
Команды run и build необходимо выполнять с опцией --flavor, чтобы apk файл собирался с необходимыми ресурсами и настройками.
Название конкретной flavor передается в аргументе. Все flavors перечислены в файле android/app/build.gradle.

View File

@@ -38,29 +38,66 @@ android {
} }
} }
// Не смог разобраться, как коомбинировать flavors в flutter при запуске
productFlavors { productFlavors {
en { autobonus_en {
applicationId 'com.dinect.autobonus'
buildConfigField "String", "locale", "\"en\"" buildConfigField "String", "locale", "\"en\""
buildConfigField "String", "flavor", "\"autobonus\""
} }
ru { autobonus_ru {
applicationId 'com.dinect.autobonus'
buildConfigField "String", "locale", "\"ru\"" buildConfigField "String", "locale", "\"ru\""
buildConfigField "String", "flavor", "\"autobonus\""
} }
ua { autobonus_ua {
applicationId 'com.dinect.autobonus'
buildConfigField "String", "locale", "\"ua\"" buildConfigField "String", "locale", "\"ua\""
buildConfigField "String", "flavor", "\"autobonus\""
} }
pip { pip_en {
buildConfigField "String", "primary_color", "\"#008794\"" applicationId 'com.dinect.pip'
buildConfigField "String", "accent_color", "\"#f49935\"" buildConfigField "String", "locale", "\"en\""
buildConfigField "String", "flavor", "\"pip\""
}
pip_ru {
applicationId 'com.dinect.pip'
buildConfigField "String", "locale", "\"ru\""
buildConfigField "String", "flavor", "\"pip\""
}
pip_ua {
applicationId 'com.dinect.pip'
buildConfigField "String", "locale", "\"ua\""
buildConfigField "String", "flavor", "\"pip\""
} }
} }
sourceSets.main { sourceSets {
jniLibs.srcDir 'jniLibs'
main.jniLibs.srcDir 'jniLibs'
pip_ua {
res.srcDirs = ['src/pip/res']
manifest.srcFile 'src/pip/AndroidManifest.xml'
}
pip_ru {
res.srcDirs = ['src/pip/res']
manifest.srcFile 'src/pip/AndroidManifest.xml'
}
pip_en {
res.srcDirs = ['src/pip/res']
manifest.srcFile 'src/pip/AndroidManifest.xml'
}
} }
} }
@@ -70,7 +107,7 @@ flutter {
dependencies { dependencies {
compile fileTree(dir: 'libs', include: ['*.jar']) compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:25.0.0' compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.squareup.okhttp3:okhttp:3.8.1' compile 'com.squareup.okhttp3:okhttp:3.8.1'
compile 'com.squareup.okio:okio:1.13.0' compile 'com.squareup.okio:okio:1.13.0'
compile 'me.dm7.barcodescanner:zxing:1.9.7' compile 'me.dm7.barcodescanner:zxing:1.9.7'

View File

@@ -37,6 +37,7 @@ import android.view.View;
import android.view.Window; import android.view.Window;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.Toast; import android.widget.Toast;
import android.widget.TextView;
import com.dinect.checker.net.ApiClient; import com.dinect.checker.net.ApiClient;
@@ -59,7 +60,9 @@ public abstract class AbstractScannerActivity extends AppCompatActivity {
"Перестань!", "Перестань!",
"Ну и зачем?..", "Ну и зачем?..",
}; };
private final AtomicInteger counter = new AtomicInteger(0); private final AtomicInteger counter = new AtomicInteger(0);
private int mColor;
public static final String SCAN_MODES = "SCAN_MODES"; public static final String SCAN_MODES = "SCAN_MODES";
public static final String ERROR_INFO = "ERROR_INFO"; public static final String ERROR_INFO = "ERROR_INFO";
@@ -115,6 +118,8 @@ public abstract class AbstractScannerActivity extends AppCompatActivity {
protected final void initToolbar(final int toolbarId, final @NonNull String title) { protected final void initToolbar(final int toolbarId, final @NonNull String title) {
Log.d(TAG, "initToolbar"); Log.d(TAG, "initToolbar");
final Toolbar toolbar = (Toolbar) findViewById(toolbarId); final Toolbar toolbar = (Toolbar) findViewById(toolbarId);
mColor = (int) getIntent().getLongExtra(MainActivity.PREF_APP_BAR_COLOR, 0xffffff);
toolbar.setBackgroundColor(mColor);
setSupportActionBar(toolbar); setSupportActionBar(toolbar);
final ActionBar actionBar = getSupportActionBar(); final ActionBar actionBar = getSupportActionBar();
@@ -295,7 +300,7 @@ public abstract class AbstractScannerActivity extends AppCompatActivity {
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.logout) { if (item.getItemId() == R.id.logout) {
logoutDialog = new AbstractScannerActivity.LogoutDialogFragment(); logoutDialog = LogoutDialogFragment.newInstance(mColor);
logoutDialog.show(getFragmentManager(), "logout"); logoutDialog.show(getFragmentManager(), "logout");
return true; return true;
} else if (item.getItemId() == R.id.faq) { } else if (item.getItemId() == R.id.faq) {
@@ -324,14 +329,25 @@ public abstract class AbstractScannerActivity extends AppCompatActivity {
public static class LogoutDialogFragment extends DialogFragment { public static class LogoutDialogFragment extends DialogFragment {
static LogoutDialogFragment newInstance(int color) {
LogoutDialogFragment f = new LogoutDialogFragment();
Bundle bundle = new Bundle();
bundle.putInt(MainActivity.PREF_APP_BAR_COLOR, color);
f.setArguments(bundle);
return f;
}
@Override @Override
public Dialog onCreateDialog(Bundle savedInstanceState) { public Dialog onCreateDialog(Bundle savedInstanceState) {
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
final LayoutInflater inflater = getActivity().getLayoutInflater(); final LayoutInflater inflater = getActivity().getLayoutInflater();
final View content = inflater.inflate(R.layout.f_logout_dialog, null); final View content = inflater.inflate(R.layout.f_logout_dialog, null);
builder.setView(content); builder.setView(content);
final View positiveButton = content.findViewById(R.id.positiveButton); final TextView positiveButton = (TextView) content.findViewById(R.id.positiveButton);
final View negativeButton = content.findViewById(R.id.negativeButton); final TextView negativeButton = (TextView) content.findViewById(R.id.negativeButton);
// Можно делать через стили, но я не уверен, что необходимо в нашем случае
positiveButton.setTextColor(getArguments().getInt(MainActivity.PREF_APP_BAR_COLOR));
negativeButton.setTextColor(getArguments().getInt(MainActivity.PREF_APP_BAR_COLOR));
negativeButton.setOnClickListener(new View.OnClickListener() { negativeButton.setOnClickListener(new View.OnClickListener() {
@Override @Override

View File

@@ -29,12 +29,14 @@ public class MainActivity extends FlutterActivity {
static final String TAG = "Checker.MainActivity"; static final String TAG = "Checker.MainActivity";
private static final int START_SCANNER_REQUEST_CODE = 2017; private static final int START_SCANNER_REQUEST_CODE = 2017;
private static final String PREF_POS_MERCHANT_ID = "pref_pos_merchant_id"; private static final String PREF_POS_MERCHANT_ID = "pref_pos_merchant_id";
private static final String PREF_DOC_ID = "pref_doc_id"; private static final String PREF_DOC_ID = "pref_doc_id";
private static final String PREF_POS_ID = "pref_pos_id"; private static final String PREF_POS_ID = "pref_pos_id";
static final String PREF_API_URL = "prefs_api_token"; static final String PREF_API_URL = "prefs_api_token";
static final String PREF_APP_TOKEN = "pres_app_token"; static final String PREF_APP_TOKEN = "pres_app_token";
static final String PREF_POS_TOKEN = "pref_pos_token"; static final String PREF_POS_TOKEN = "pref_pos_token";
static final String PREF_APP_BAR_COLOR = "pref_app_bar_color";
static final Class[] SCANNER_BACKEND = { static final Class[] SCANNER_BACKEND = {
ScannerActivity.class, ScannerActivity.class,
@@ -77,6 +79,9 @@ public class MainActivity extends FlutterActivity {
case "getLocale": case "getLocale":
result.success(BuildConfig.locale); result.success(BuildConfig.locale);
break; break;
case "getFlavor":
result.success(BuildConfig.flavor);
break;
case "getMerchantID": case "getMerchantID":
result.success(mPreferences.getString(PREF_POS_MERCHANT_ID, null)); result.success(mPreferences.getString(PREF_POS_MERCHANT_ID, null));
break; break;
@@ -88,6 +93,7 @@ public class MainActivity extends FlutterActivity {
cameraIntent.putExtra(PREF_API_URL, (String) arguments.get("url")); cameraIntent.putExtra(PREF_API_URL, (String) arguments.get("url"));
cameraIntent.putExtra(PREF_APP_TOKEN, (String) arguments.get("appToken")); cameraIntent.putExtra(PREF_APP_TOKEN, (String) arguments.get("appToken"));
cameraIntent.putExtra(PREF_POS_TOKEN, (String) arguments.get("token")); cameraIntent.putExtra(PREF_POS_TOKEN, (String) arguments.get("token"));
cameraIntent.putExtra(PREF_APP_BAR_COLOR, (Long) arguments.get("color"));
startActivityForResult(cameraIntent, START_SCANNER_REQUEST_CODE); startActivityForResult(cameraIntent, START_SCANNER_REQUEST_CODE);
break; break;
case "removeKeys": case "removeKeys":
@@ -172,6 +178,10 @@ public class MainActivity extends FlutterActivity {
} }
public void getFlavor() {
}
public void getLocale() { public void getLocale() {
} }

View File

@@ -45,7 +45,6 @@
android:id="@+id/toolbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="?attr/actionBarSize"
android:background="#eb0004"
app:titleTextColor="@android:color/white" /> app:titleTextColor="@android:color/white" />
<View <View

View File

@@ -10,7 +10,6 @@
android:id="@+id/zxingToolbar" android:id="@+id/zxingToolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="?attr/actionBarSize"
android:background="#eb0004"
app:titleTextColor="@android:color/white" /> app:titleTextColor="@android:color/white" />
<View <View

View File

@@ -0,0 +1,3 @@
<resources>
<string name="app_name">PIP</string>
</resources>

View File

@@ -0,0 +1,3 @@
<resources>
<string name="app_name">PIP</string>
</resources>

View File

@@ -0,0 +1,3 @@
<resources>
<string name="app_name">PIP</string>
</resources>

View File

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 74 KiB

View File

Before

Width:  |  Height:  |  Size: 359 KiB

After

Width:  |  Height:  |  Size: 359 KiB

BIN
assets/pip_splash.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 B

View File

@@ -1,7 +1,9 @@
import 'dart:async'; import 'dart:async';
import 'package:checker/resources.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:intl/intl.dart';
import 'common.dart'; import 'common.dart';
import 'consts.dart'; import 'consts.dart';
@@ -9,6 +11,9 @@ import 'strings.dart';
abstract class BaseState<T extends StatefulWidget> extends State<T> { abstract class BaseState<T extends StatefulWidget> extends State<T> {
/// Тип сборки. Определяет, какие брать ресурсы (цвета, картинки)
String app;
/// Ожидание ответа от сервера. /// Ожидание ответа от сервера.
bool loading = false; bool loading = false;
@@ -19,13 +24,42 @@ abstract class BaseState<T extends StatefulWidget> extends State<T> {
String textFieldValue = ''; String textFieldValue = '';
@override Widget build(BuildContext ctx) { @override Widget build(BuildContext ctx) {
return new Scaffold(appBar: getAppBar(),
platform.invokeMethod('getLocale').then((locale) {
Intl.defaultLocale = locale;
if (app == null) {
platform.invokeMethod('getFlavor').then((flavor) {
setState(() {
app = flavor;
onStart();
});
});
}
});
return getMainWidget();
}
Widget getMainWidget() {
return app == null ? getBackground() : new Scaffold(appBar: getAppBar(),
body: new Stack(children: <Widget>[ body: new Stack(children: <Widget>[
getScreenContent(), getScreenContent(),
new Center(child: loading ? new CircularProgressIndicator() : null) new Center(child: loading ? new CircularProgressIndicator() : null)
])); ]));
} }
Widget getBackground() {
return new Container(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new ExactAssetImage(Resources.getSplash(app)),
fit: BoxFit.cover)));
}
void onStart() {
}
/// Возвращает контейнер с всеми виджетами экрана. /// Возвращает контейнер с всеми виджетами экрана.
Widget getScreenContent(); Widget getScreenContent();
@@ -34,7 +68,7 @@ abstract class BaseState<T extends StatefulWidget> extends State<T> {
AppBar getAppBar() { AppBar getAppBar() {
return new AppBar(title: new Text(getTitle(), style: new TextStyle(fontSize: 18.0)), return new AppBar(title: new Text(getTitle(), style: new TextStyle(fontSize: 18.0)),
backgroundColor: primaryColor, actions: getMenuButtons()); backgroundColor: Resources.getPrimaryColor(app), actions: getMenuButtons());
} }
List<Widget> getMenuButtons() { List<Widget> getMenuButtons() {
@@ -55,7 +89,7 @@ abstract class BaseState<T extends StatefulWidget> extends State<T> {
return new Container(margin: new EdgeInsets.only(top: horizontalMargin, bottom: horizontalMargin, left: verticalMargin, right: verticalMargin), return new Container(margin: new EdgeInsets.only(top: horizontalMargin, bottom: horizontalMargin, left: verticalMargin, right: verticalMargin),
child: new Row(crossAxisAlignment: CrossAxisAlignment.start, child: new Row(crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[new Text(getHintString(), textAlign: TextAlign.left, children: <Widget>[new Text(getHintString(), textAlign: TextAlign.left,
style: new TextStyle(fontWeight: FontWeight.w300, color: error == null ? greyTextColor : primaryColor, fontSize: 14.0))])); style: new TextStyle(fontWeight: FontWeight.w300, color: error == null ? greyTextColor : Resources.getLogo(app), fontSize: 14.0))]));
} }
/// Возвращает подсказку, либо ошибку, если введенные в поле ввода данные неверны. /// Возвращает подсказку, либо ошибку, если введенные в поле ввода данные неверны.
@@ -118,14 +152,14 @@ abstract class BaseState<T extends StatefulWidget> extends State<T> {
return new RaisedButton(child: new Text(text, return new RaisedButton(child: new Text(text,
style: new TextStyle(color: Colors.white)), style: new TextStyle(color: Colors.white)),
onPressed: onPressed, onPressed: onPressed,
color: buttonColor); color: Resources.getButtonColor(app));
} }
/// Метод возвращает контейнер с отступами, который содержит картинку с логотипом. /// Метод возвращает контейнер с отступами, который содержит картинку с логотипом.
Widget getLogo() { Widget getLogo() {
double containerHeight = 92.0; double containerHeight = 92.0;
double imageWidth = 156.0; double imageWidth = 156.0;
return new Container(height: containerHeight, child: new Image.asset(logo_png, width: imageWidth)); return new Container(height: containerHeight, child: new Image.asset(Resources.getLogo(app), width: imageWidth));
} }
/// Возвращает текстовое поле, с однострочным пояснением над ним. /// Возвращает текстовое поле, с однострочным пояснением над ним.

View File

@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'consts.dart'; import 'consts.dart';
import 'network.dart'; import 'network.dart';
import 'resources.dart';
import 'package:checker/registration.dart'; import 'package:checker/registration.dart';
import 'package:checker/purchase.dart'; import 'package:checker/purchase.dart';
import 'faq.dart'; import 'faq.dart';
@@ -62,7 +63,7 @@ forceLogout(BuildContext context) async {
/// Запуск спецефичной для каждой платформы части приложения - сканера. /// Запуск спецефичной для каждой платформы части приложения - сканера.
/// Может производиться с нескольких экранов (splash, finish_registration). /// Может производиться с нескольких экранов (splash, finish_registration).
startScanner(BuildContext context) async { startScanner(BuildContext context, String app) async {
String token = await platform.invokeMethod('getToken'); String token = await platform.invokeMethod('getToken');
// Канал ловит вызовы методов из "нативной" части приложения. // Канал ловит вызовы методов из "нативной" части приложения.
@@ -88,6 +89,7 @@ startScanner(BuildContext context) async {
'token' : token, 'token' : token,
'url': url, 'url': url,
'appToken': appToken, 'appToken': appToken,
'color': Resources.getPrimaryColor(app).value
}); });
} }
} }

View File

@@ -1,14 +1,12 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
// Serious constants // Serious constants
const String appName = "Dinect"; const String appName = "AutoBonus";
const String url = 'https://pos-api-int.dinect.com/20130701/'; const String url = 'https://pos-api-int.dinect.com/20130701/';
const String appToken = '9fec83cdca38c357e6b65dbb17514cdd36bf2a08'; const String appToken = '9fec83cdca38c357e6b65dbb17514cdd36bf2a08';
// Assets // Assets
const String logo_png = 'assets/pip_logo.png';
const String splash_png = 'assets/splash.png';
const String logout_png = 'assets/logout.png'; const String logout_png = 'assets/logout.png';
const String activate_token_bg_png = 'assets/activate_token_message_background.png'; const String activate_token_bg_png = 'assets/activate_token_message_background.png';
const String active_token_bg_png = 'assets/active_token_message_background.png'; const String active_token_bg_png = 'assets/active_token_message_background.png';
@@ -17,12 +15,6 @@ const String powered_by_dinect_splash_png = 'assets/powered_by_dinect_splash.png
const String powered_by_dinect_png = 'assets/powered_by_dinect.png'; const String powered_by_dinect_png = 'assets/powered_by_dinect.png';
const String splash_text_png = 'assets/splash_text.png'; const String splash_text_png = 'assets/splash_text.png';
// Colors
//const Color primaryColor = const Color(0xffeb0004);
//const Color buttonColor = const Color(0xffeb0004);
const Color primaryColor = const Color(0xff008794);
const Color buttonColor = const Color(0xfff49935);
const Color greyTextColor = const Color(0xffa5a5a5); const Color greyTextColor = const Color(0xffa5a5a5);
const Color textBorderColor = const Color(0xffcfd8dc); const Color textBorderColor = const Color(0xffcfd8dc);
const Color tokenActiveTextColor = const Color(0xff1f5a1f); const Color tokenActiveTextColor = const Color(0xff1f5a1f);
@@ -31,6 +23,7 @@ const Color greenBackground = const Color(0xff8ae28a);
const Color faqGrey = const Color(0xff5b5b5b); const Color faqGrey = const Color(0xff5b5b5b);
const Color faqTitlesColor = const Color(0xff404040); const Color faqTitlesColor = const Color(0xff404040);
const Color inputFieldBackground = const Color(0xffefefef); const Color inputFieldBackground = const Color(0xffefefef);
// Dimens // Dimens
const double verticalMargin = 28.0; const double verticalMargin = 28.0;
const double buttonHeight = 48.0; const double buttonHeight = 48.0;

View File

@@ -68,7 +68,7 @@ class FAQScreenState<T> extends BaseState<FAQScreen> {
onWillPop() { onWillPop() {
if(returnToScanner) { if(returnToScanner) {
return startScanner(context); return startScanner(context, app);
} else { } else {
return true; return true;
} }

View File

@@ -47,7 +47,7 @@ class _RegistrationScreenState extends BaseState<FinishRegistrationScreen> {
// Если нет, то отправляется запрос на проверку статуса токена. // Если нет, то отправляется запрос на проверку статуса токена.
handleTap() async { handleTap() async {
if (_tokenActive) { if (_tokenActive) {
startScanner(context); startScanner(context, app);
} else { } else {
if (await platform.invokeMethod('isOnline')) { if (await platform.invokeMethod('isOnline')) {
String token = await platform.invokeMethod('getToken'); String token = await platform.invokeMethod('getToken');

View File

@@ -3,12 +3,13 @@ import 'package:flutter/services.dart';
import 'dart:convert'; import 'dart:convert';
import 'dart:core'; import 'dart:core';
import 'package:checker/strings.dart'; import 'resources.dart';
import 'package:checker/common.dart'; import 'strings.dart';
import 'package:checker/consts.dart'; import 'common.dart';
import 'package:checker/network.dart'; import 'consts.dart';
import 'package:checker/base_state.dart'; import 'network.dart';
import 'package:checker/purchase_success.dart'; import 'base_state.dart';
import 'purchase_success.dart';
/// Экран проведения покупки. /// Экран проведения покупки.
class PurchaseScreen extends StatefulWidget { class PurchaseScreen extends StatefulWidget {
@@ -48,7 +49,7 @@ class PurchaseScreenState<T> extends BaseState<PurchaseScreen> {
getHintLabel(), getHintLabel(),
getInputField(), getInputField(),
wrapButton(getScreenMargins(36.0), getCompleteButton()), wrapButton(getScreenMargins(36.0), getCompleteButton()),
wrapButton(getScreenMargins(24.0), getScanButton(context, StringsLocalization.scan(), primaryColor)) wrapButton(getScreenMargins(24.0), getScanButton(context, StringsLocalization.scan(), Resources.getPrimaryColor(app)))
]))]); ]))]);
} }
@@ -62,16 +63,16 @@ class PurchaseScreenState<T> extends BaseState<PurchaseScreen> {
} }
Widget getScanButton(BuildContext context, String title, Color textColor) { Widget getScanButton(BuildContext context, String title, Color textColor) {
return new Container(height: buttonHeight, child: new FlatButton(child: new Text(title, return new Container(
height: buttonHeight,
child: new FlatButton(
child: new Text(
title,
style: new TextStyle(color: textColor)), style: new TextStyle(color: textColor)),
onPressed: () => startScanner(context)), onPressed: () => startScanner(context, app)),
decoration: getDecorationForScanButton()); decoration: new BoxDecoration(
} border: new Border.all(color: Resources.getButtonColor(app), width: 1.0),
borderRadius: new BorderRadius.all(new Radius.circular(4.0))));
getDecorationForScanButton() {
return new BoxDecoration(
border: new Border.all(color: buttonColor, width: 1.0),
borderRadius: new BorderRadius.all(new Radius.circular(4.0)));
} }
@override String getTitle() { @override String getTitle() {

View File

@@ -50,7 +50,7 @@ class PurchaseSuccessScreenState<T> extends BaseState<PurchaseSuccessScreen> {
getScanButton() { getScanButton() {
String title = StringsLocalization.scan(); String title = StringsLocalization.scan();
return buildRaisedButton(title, () => startScanner(context)); return buildRaisedButton(title, () => startScanner(context, app));
} }
getSuccessMessage() { getSuccessMessage() {

28
lib/resources.dart Normal file
View File

@@ -0,0 +1,28 @@
import 'package:flutter/material.dart';
class Resources {
static String getLogo(String app) {
return app == null ? null : 'assets/${app}_logo.png';
}
static String getSplash(String app) {
return 'assets/${app != null ? app : 'pip'}_splash.png';
}
static Color getPrimaryColor(String app) {
switch (app) {
case 'pip': return new Color(0xff008794);
case 'autobonus': return new Color(0xffeb0004);
default: return new Color(0xffffffff);
}
}
static Color getButtonColor(String app) {
switch (app) {
case 'pip': return new Color(0xfff49935);
case 'autobonus': return new Color(0xffeb0004);
default: return new Color(0xffffffff);
}
}
}

View File

@@ -1,49 +1,70 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'dart:async';
import 'common.dart'; import 'common.dart';
import 'network.dart'; import 'network.dart';
import 'consts.dart'; import 'consts.dart';
import 'registration.dart'; import 'registration.dart';
import 'finish_registration.dart'; import 'finish_registration.dart';
import 'strings.dart'; import 'resources.dart';
import 'base_state.dart';
class SplashScreen extends StatelessWidget { class SplashScreen extends StatefulWidget {
@override State createState() => new _SplashScreenState();
}
class _SplashScreenState extends BaseState<SplashScreen> {
@override @override
Widget build(BuildContext context) { Widget getScreenContent() {
// Появляется splash screen, проверяется токен. return app == null
? getBackground()
: new Stack(
children: <Widget>[
getBackground(),
getLogo(),
new Align(
alignment: FractionalOffset.bottomRight,
child: new Container(
margin: new EdgeInsets.only(
right: 11.0,
bottom: 5.0),
child: new Image.asset(powered_by_dinect_splash_png,
height: 16.0,
width: 122.0)))]);
}
new Future.delayed(const Duration(milliseconds: 500), () { @override Widget getMainWidget() {
platform.invokeMethod("getLocale").then((locale) { return getScreenContent();
Intl.defaultLocale = locale; }
print(Intl.defaultLocale);
// showNextScreen(context);
});
});
return new Stack(children: <Widget>[getSplashBackground(), getLogo(), @override
new Align(alignment: FractionalOffset.bottomRight, child: String getTitle() {
new Container(margin: new EdgeInsets.only(right: 11.0, bottom: 5.0), child: return null;
new Image.asset(powered_by_dinect_splash_png, height: 16.0, width: 122.0)))]); }
@override void onStart() {
new Future.delayed(const Duration(milliseconds: 1000), () {
showNextScreen(context);
});
} }
/// Возвращает столбец с логотипом приложения и текстом под ним. /// Возвращает столбец с логотипом приложения и текстом под ним.
/// Столбец занимает не все доступное пространство, а необходимый минимум в центре экрана. /// Столбец занимает не все доступное пространство, а необходимый минимум в центре экрана.
getLogo() { getLogo() {
return new Center(child: new Column(mainAxisSize: MainAxisSize.min, return new Center(
children: <Widget>[new Image.asset(logo_png, height: 112.0, width: 252.0), child: new Column(
new Image.asset(splash_text_png, height: 40.0, width: 240.0)])); mainAxisSize: MainAxisSize.min,
} children: <Widget>[
new Image.asset(
/// Возвращает контейнер, который содержит decoration с фоновым изображением. Resources.getLogo(app),
getSplashBackground() { height: 112.0,
return new Container(decoration: width: 252.0),
new BoxDecoration(image: new Image.asset(
new DecorationImage(image: new ExactAssetImage(splash_png), fit: BoxFit.cover))); splash_text_png,
height: 40.0,
width: 240.0)]));
} }
/// Запуск следующего экрана приложения. /// Запуск следующего экрана приложения.
@@ -85,7 +106,7 @@ class SplashScreen extends StatelessWidget {
bool active = status['active'] == null ? false : status['active']; bool active = status['active'] == null ? false : status['active'];
if (active) { if (active) {
startScanner(context); startScanner(context, app);
} else { } else {
if (await platform.invokeMethod('isOnline')) { if (await platform.invokeMethod('isOnline')) {
_createToken(context); _createToken(context);

View File

@@ -23,16 +23,20 @@ flutter:
# To add assets to your application, add an assets section here, in # To add assets to your application, add an assets section here, in
# this "flutter" section, as in: # this "flutter" section, as in:
assets: assets:
- assets/autoclub_logo.png
- assets/autobonus_logo.png
- assets/pip_logo.png - assets/pip_logo.png
- assets/splash.png
- assets/autobonus_splash.png
- assets/pip_splash.png
- assets/logout.png - assets/logout.png
- assets/activate_token_message_background.png - assets/activate_token_message_background.png
- assets/active_token_message_background.png - assets/active_token_message_background.png
- assets/expansion_icon.png - assets/expansion_icon.png
- assets/powered_by_dinect_splash.png - assets/powered_by_dinect_splash.png
- assets/powered_by_dinect.png - assets/powered_by_dinect.png
- assets/autoclub_logo.png - assets/autobonus_logo.png
- assets/splash_text.png - assets/splash_text.png
# To add assets from package dependencies, first ensure the asset # To add assets from package dependencies, first ensure the asset