flutter: Use part of Best-Flutter-UI-Templates
See: https://github.com/mitesh77/Best-Flutter-UI-Templates
This commit is contained in:
parent
e402a69826
commit
4f0da829f8
|
@ -369,7 +369,27 @@
|
|||
"description": "Copy"
|
||||
},
|
||||
"moveHistoryCopied": "Move history copied to clipboard",
|
||||
"@copy": {
|
||||
"@moveHistoryCopied": {
|
||||
"description": "Move history copied to clipboard"
|
||||
},
|
||||
"help": "Help",
|
||||
"@help": {
|
||||
"description": "Help"
|
||||
},
|
||||
"feedback": "FeedBack",
|
||||
"@feedback": {
|
||||
"description": "FeedBack"
|
||||
},
|
||||
"inviteFriend": "Invite Friend",
|
||||
"@inviteFriend": {
|
||||
"description": "Invite Friend"
|
||||
},
|
||||
"rateTheApp": "Rate The App",
|
||||
"@rateTheApp": {
|
||||
"description": "Rate The App"
|
||||
},
|
||||
"exit": "Exit",
|
||||
"@exit": {
|
||||
"description": "Exit"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,5 +92,10 @@
|
|||
"mayFly": "剩余三颗子时飞棋",
|
||||
"maxStepsLedToDraw": "连续多少步无吃子则和棋",
|
||||
"copy": "复制",
|
||||
"moveHistoryCopied": "棋谱已复制到剪贴板"
|
||||
"moveHistoryCopied": "棋谱已复制到剪贴板",
|
||||
"help": "帮助",
|
||||
"feedback": "反馈",
|
||||
"inviteFriend": "邀请",
|
||||
"rateTheApp": "投票",
|
||||
"exit": "退出"
|
||||
}
|
|
@ -25,11 +25,11 @@ import 'package:flutter/services.dart';
|
|||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:sanmill/generated/l10n.dart';
|
||||
import 'package:sanmill/widgets/navigation_home_screen.dart';
|
||||
import 'package:stack_trace/stack_trace.dart';
|
||||
|
||||
import 'services/audios.dart';
|
||||
import 'services/player.dart';
|
||||
import 'widgets/main_menu.dart';
|
||||
|
||||
//import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
|
@ -156,7 +156,7 @@ class _SanmillAppState extends State<SanmillApp> {
|
|||
Audios.release();
|
||||
return true;
|
||||
},
|
||||
child: MainMenu(),
|
||||
child: NavigationHomeScreen(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class AppTheme {
|
||||
AppTheme._();
|
||||
|
||||
static const Color notWhite = Color(0xFFEDF0F2);
|
||||
static const Color nearlyWhite = Color(0xFFFEFEFE);
|
||||
static const Color white = Color(0xFFFFFFFF);
|
||||
static const Color nearlyBlack = Color(0xFF213333);
|
||||
static const Color grey = Color(0xFF3A5160);
|
||||
static const Color dark_grey = Color(0xFF313A44);
|
||||
|
||||
static const Color darkText = Color(0xFF253840);
|
||||
static const Color darkerText = Color(0xFF17262A);
|
||||
static const Color lightText = Color(0xFF4A6572);
|
||||
static const Color deactivatedText = Color(0xFF767676);
|
||||
static const Color dismissibleBackground = Color(0xFF364A54);
|
||||
static const Color chipBackground = Color(0xFFEEF1F3);
|
||||
static const Color spacer = Color(0xFFF2F2F2);
|
||||
static const String fontName = 'WorkSans';
|
||||
|
||||
static const TextTheme textTheme = TextTheme(
|
||||
headline4: display1,
|
||||
headline5: headline,
|
||||
headline6: title,
|
||||
subtitle2: subtitle,
|
||||
bodyText2: body2,
|
||||
bodyText1: body1,
|
||||
caption: caption,
|
||||
);
|
||||
|
||||
static const TextStyle display1 = TextStyle( // h4 -> display1
|
||||
fontFamily: fontName,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 36,
|
||||
letterSpacing: 0.4,
|
||||
height: 0.9,
|
||||
color: darkerText,
|
||||
);
|
||||
|
||||
static const TextStyle headline = TextStyle( // h5 -> headline
|
||||
fontFamily: fontName,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 24,
|
||||
letterSpacing: 0.27,
|
||||
color: darkerText,
|
||||
);
|
||||
|
||||
static const TextStyle title = TextStyle( // h6 -> title
|
||||
fontFamily: fontName,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 16,
|
||||
letterSpacing: 0.18,
|
||||
color: darkerText,
|
||||
);
|
||||
|
||||
static const TextStyle subtitle = TextStyle( // subtitle2 -> subtitle
|
||||
fontFamily: fontName,
|
||||
fontWeight: FontWeight.w400,
|
||||
fontSize: 14,
|
||||
letterSpacing: -0.04,
|
||||
color: darkText,
|
||||
);
|
||||
|
||||
static const TextStyle body2 = TextStyle( // body1 -> body2
|
||||
fontFamily: fontName,
|
||||
fontWeight: FontWeight.w400,
|
||||
fontSize: 14,
|
||||
letterSpacing: 0.2,
|
||||
color: darkText,
|
||||
);
|
||||
|
||||
static const TextStyle body1 = TextStyle( // body2 -> body1
|
||||
fontFamily: fontName,
|
||||
fontWeight: FontWeight.w400,
|
||||
fontSize: 16,
|
||||
letterSpacing: -0.05,
|
||||
color: darkText,
|
||||
);
|
||||
|
||||
static const TextStyle caption = TextStyle( // Caption -> caption
|
||||
fontFamily: fontName,
|
||||
fontWeight: FontWeight.w400,
|
||||
fontSize: 12,
|
||||
letterSpacing: 0.2,
|
||||
color: lightText, // was lightText
|
||||
);
|
||||
|
||||
}
|
|
@ -0,0 +1,222 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:sanmill/style/app_theme.dart';
|
||||
import 'package:sanmill/widgets/home_drawer.dart';
|
||||
|
||||
class DrawerUserController extends StatefulWidget {
|
||||
const DrawerUserController({
|
||||
Key key,
|
||||
this.drawerWidth = 250,
|
||||
this.onDrawerCall,
|
||||
this.screenView,
|
||||
this.animatedIconData = AnimatedIcons.arrow_menu,
|
||||
this.menuView,
|
||||
this.drawerIsOpen,
|
||||
this.screenIndex,
|
||||
}) : super(key: key);
|
||||
|
||||
final double drawerWidth;
|
||||
final Function(DrawerIndex) onDrawerCall;
|
||||
final Widget screenView;
|
||||
final Function(bool) drawerIsOpen;
|
||||
final AnimatedIconData animatedIconData;
|
||||
final Widget menuView;
|
||||
final DrawerIndex screenIndex;
|
||||
|
||||
@override
|
||||
_DrawerUserControllerState createState() => _DrawerUserControllerState();
|
||||
}
|
||||
|
||||
class _DrawerUserControllerState extends State<DrawerUserController>
|
||||
with TickerProviderStateMixin {
|
||||
ScrollController scrollController;
|
||||
AnimationController iconAnimationController;
|
||||
AnimationController animationController;
|
||||
|
||||
double scrolloffset = 0.0;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
animationController = AnimationController(
|
||||
duration: const Duration(milliseconds: 2000), vsync: this);
|
||||
iconAnimationController = AnimationController(
|
||||
vsync: this, duration: const Duration(milliseconds: 0));
|
||||
iconAnimationController
|
||||
..animateTo(1.0,
|
||||
duration: const Duration(milliseconds: 0),
|
||||
curve: Curves.fastOutSlowIn);
|
||||
scrollController =
|
||||
ScrollController(initialScrollOffset: widget.drawerWidth);
|
||||
scrollController
|
||||
..addListener(() {
|
||||
if (scrollController.offset <= 0) {
|
||||
if (scrolloffset != 1.0) {
|
||||
setState(() {
|
||||
scrolloffset = 1.0;
|
||||
try {
|
||||
widget.drawerIsOpen(true);
|
||||
} catch (_) {}
|
||||
});
|
||||
}
|
||||
iconAnimationController.animateTo(0.0,
|
||||
duration: const Duration(milliseconds: 0),
|
||||
curve: Curves.fastOutSlowIn);
|
||||
} else if (scrollController.offset > 0 &&
|
||||
scrollController.offset < widget.drawerWidth.floor()) {
|
||||
iconAnimationController.animateTo(
|
||||
(scrollController.offset * 100 / (widget.drawerWidth)) / 100,
|
||||
duration: const Duration(milliseconds: 0),
|
||||
curve: Curves.fastOutSlowIn);
|
||||
} else {
|
||||
if (scrolloffset != 0.0) {
|
||||
setState(() {
|
||||
scrolloffset = 0.0;
|
||||
try {
|
||||
widget.drawerIsOpen(false);
|
||||
} catch (_) {}
|
||||
});
|
||||
}
|
||||
iconAnimationController.animateTo(1.0,
|
||||
duration: const Duration(milliseconds: 0),
|
||||
curve: Curves.fastOutSlowIn);
|
||||
}
|
||||
});
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => getInitState());
|
||||
super.initState();
|
||||
}
|
||||
|
||||
Future<bool> getInitState() async {
|
||||
scrollController.jumpTo(
|
||||
widget.drawerWidth,
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: AppTheme.white,
|
||||
body: SingleChildScrollView(
|
||||
controller: scrollController,
|
||||
scrollDirection: Axis.horizontal,
|
||||
physics: const PageScrollPhysics(parent: ClampingScrollPhysics()),
|
||||
child: SizedBox(
|
||||
height: MediaQuery.of(context).size.height,
|
||||
width: MediaQuery.of(context).size.width + widget.drawerWidth,
|
||||
//we use with as screen width and add drawerWidth (from navigation_home_screen)
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
SizedBox(
|
||||
width: widget.drawerWidth,
|
||||
//we divided first drawer Width with HomeDrawer and second full-screen Width with all home screen, we called screen View
|
||||
height: MediaQuery.of(context).size.height,
|
||||
child: AnimatedBuilder(
|
||||
animation: iconAnimationController,
|
||||
builder: (BuildContext context, Widget child) {
|
||||
return Transform(
|
||||
//transform we use for the stable drawer we, not need to move with scroll view
|
||||
transform: Matrix4.translationValues(
|
||||
scrollController.offset, 0.0, 0.0),
|
||||
child: HomeDrawer(
|
||||
screenIndex: widget.screenIndex == null
|
||||
? DrawerIndex.humanVsAi
|
||||
: widget.screenIndex,
|
||||
iconAnimationController: iconAnimationController,
|
||||
callBackIndex: (DrawerIndex indexType) {
|
||||
onDrawerClick();
|
||||
try {
|
||||
widget.onDrawerCall(indexType);
|
||||
} catch (e) {}
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width,
|
||||
height: MediaQuery.of(context).size.height,
|
||||
//full-screen Width with widget.screenView
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: AppTheme.white,
|
||||
boxShadow: <BoxShadow>[
|
||||
BoxShadow(
|
||||
color: AppTheme.grey.withOpacity(0.6),
|
||||
blurRadius: 24),
|
||||
],
|
||||
),
|
||||
child: Stack(
|
||||
children: <Widget>[
|
||||
//this IgnorePointer we use as touch(user Interface) widget.screen View, for example scrolloffset == 1 means drawer is close we just allow touching all widget.screen View
|
||||
IgnorePointer(
|
||||
ignoring: scrolloffset == 1 || false,
|
||||
child: widget.screenView,
|
||||
),
|
||||
//alternative touch(user Interface) for widget.screen, for example, drawer is close we need to tap on a few home screen area and close the drawer
|
||||
if (scrolloffset == 1.0)
|
||||
InkWell(
|
||||
onTap: () {
|
||||
onDrawerClick();
|
||||
},
|
||||
),
|
||||
// this just menu and arrow icon animation
|
||||
Padding(
|
||||
padding: EdgeInsets.only(
|
||||
top: MediaQuery.of(context).padding.top + 8,
|
||||
left: 8),
|
||||
child: SizedBox(
|
||||
width: AppBar().preferredSize.height - 8,
|
||||
height: AppBar().preferredSize.height - 8,
|
||||
child: Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
borderRadius: BorderRadius.circular(
|
||||
AppBar().preferredSize.height),
|
||||
child: Center(
|
||||
// if you use your own menu view UI you add form initialization
|
||||
child: widget.menuView != null
|
||||
? widget.menuView
|
||||
: AnimatedIcon(
|
||||
icon: widget.animatedIconData != null
|
||||
? widget.animatedIconData
|
||||
: AnimatedIcons.arrow_menu,
|
||||
color: Colors.white,
|
||||
progress: iconAnimationController),
|
||||
),
|
||||
onTap: () {
|
||||
FocusScope.of(context)
|
||||
.requestFocus(FocusNode());
|
||||
onDrawerClick();
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void onDrawerClick() {
|
||||
//if scrollcontroller.offset != 0.0 then we set to closed the drawer(with animation to offset zero position) if is not 1 then open the drawer
|
||||
if (scrollController.offset != 0.0) {
|
||||
scrollController.animateTo(
|
||||
0.0,
|
||||
duration: const Duration(milliseconds: 400),
|
||||
curve: Curves.fastOutSlowIn,
|
||||
);
|
||||
} else {
|
||||
scrollController.animateTo(
|
||||
widget.drawerWidth,
|
||||
duration: const Duration(milliseconds: 400),
|
||||
curve: Curves.fastOutSlowIn,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:sanmill/style/app_theme.dart';
|
||||
|
||||
class FeedbackScreen extends StatefulWidget {
|
||||
@override
|
||||
_FeedbackScreenState createState() => _FeedbackScreenState();
|
||||
}
|
||||
|
||||
class _FeedbackScreenState extends State<FeedbackScreen> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
color: AppTheme.nearlyWhite,
|
||||
child: SafeArea(
|
||||
top: false,
|
||||
child: Scaffold(
|
||||
backgroundColor: AppTheme.nearlyWhite,
|
||||
body: SingleChildScrollView(
|
||||
child: SizedBox(
|
||||
height: MediaQuery.of(context).size.height,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Container(
|
||||
padding: EdgeInsets.only(
|
||||
top: MediaQuery.of(context).padding.top,
|
||||
left: 16,
|
||||
right: 16),
|
||||
child: Image.asset('assets/images/feedbackImage.png'),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.only(top: 8),
|
||||
child: Text(
|
||||
'Your FeedBack',
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.only(top: 16),
|
||||
child: const Text(
|
||||
'Give your best time for this moment.',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
_buildComposer(),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 16),
|
||||
child: Center(
|
||||
child: Container(
|
||||
width: 120,
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.blue,
|
||||
borderRadius:
|
||||
const BorderRadius.all(Radius.circular(4.0)),
|
||||
boxShadow: <BoxShadow>[
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.6),
|
||||
offset: const Offset(4, 4),
|
||||
blurRadius: 8.0),
|
||||
],
|
||||
),
|
||||
child: Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
FocusScope.of(context).requestFocus(FocusNode());
|
||||
},
|
||||
child: Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
child: Text(
|
||||
'Send',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildComposer() {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(top: 16, left: 32, right: 32),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: AppTheme.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
boxShadow: <BoxShadow>[
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.8),
|
||||
offset: const Offset(4, 4),
|
||||
blurRadius: 8),
|
||||
],
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(25),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
constraints: const BoxConstraints(minHeight: 80, maxHeight: 160),
|
||||
color: AppTheme.white,
|
||||
child: SingleChildScrollView(
|
||||
padding:
|
||||
const EdgeInsets.only(left: 10, right: 10, top: 0, bottom: 0),
|
||||
child: TextField(
|
||||
maxLines: null,
|
||||
onChanged: (String txt) {},
|
||||
style: TextStyle(
|
||||
fontFamily: AppTheme.fontName,
|
||||
fontSize: 16,
|
||||
color: AppTheme.dark_grey,
|
||||
),
|
||||
cursorColor: Colors.blue,
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
hintText: 'Enter your feedback...'),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -33,7 +33,6 @@ import 'package:sanmill/style/colors.dart';
|
|||
import 'package:sanmill/style/toast.dart';
|
||||
|
||||
import 'board.dart';
|
||||
import 'settings_page.dart';
|
||||
|
||||
class GamePage extends StatefulWidget {
|
||||
//
|
||||
|
@ -74,7 +73,7 @@ class _GamePageState extends State<GamePage> with RouteAware {
|
|||
}
|
||||
|
||||
void showTips() {
|
||||
if (context == null) {
|
||||
if (!mounted || context == null) {
|
||||
//print("[showTips] context == null, return");
|
||||
return;
|
||||
}
|
||||
|
@ -214,6 +213,7 @@ class _GamePageState extends State<GamePage> with RouteAware {
|
|||
while ((Config.isAutoRestart == true ||
|
||||
Game.shared.position.winner == Color.nobody) &&
|
||||
Game.shared.isAiToMove() &&
|
||||
mounted &&
|
||||
context != null) {
|
||||
if (widget.engineType == EngineType.aiVsAi) {
|
||||
String score = Game.shared.position.score[Color.black].toString() +
|
||||
|
@ -477,14 +477,17 @@ class _GamePageState extends State<GamePage> with RouteAware {
|
|||
children: <Widget>[
|
||||
Row(
|
||||
children: <Widget>[
|
||||
/*
|
||||
IconButton(
|
||||
icon: Icon(Icons.arrow_back,
|
||||
color: UIColors.darkTextSecondaryColor),
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
),
|
||||
*/
|
||||
Expanded(child: SizedBox()),
|
||||
Text(engineTypeToString[widget.engineType], style: titleStyle),
|
||||
Expanded(child: SizedBox()),
|
||||
/*
|
||||
IconButton(
|
||||
icon: Icon(Icons.menu /* more_vert */,
|
||||
color: UIColors.darkTextSecondaryColor),
|
||||
|
@ -492,6 +495,7 @@ class _GamePageState extends State<GamePage> with RouteAware {
|
|||
MaterialPageRoute(builder: (context) => SettingsPage()),
|
||||
),
|
||||
),
|
||||
*/
|
||||
],
|
||||
),
|
||||
Container(
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:sanmill/style/app_theme.dart';
|
||||
|
||||
class HelpScreen extends StatefulWidget {
|
||||
@override
|
||||
_HelpScreenState createState() => _HelpScreenState();
|
||||
}
|
||||
|
||||
class _HelpScreenState extends State<HelpScreen> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
color: AppTheme.nearlyWhite,
|
||||
child: SafeArea(
|
||||
top: false,
|
||||
child: Scaffold(
|
||||
backgroundColor: AppTheme.nearlyWhite,
|
||||
body: Column(
|
||||
children: <Widget>[
|
||||
Container(
|
||||
padding: EdgeInsets.only(
|
||||
top: MediaQuery.of(context).padding.top,
|
||||
left: 16,
|
||||
right: 16),
|
||||
child: Icon(Icons.help),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.only(top: 8),
|
||||
child: Text(
|
||||
'How can we help you?',
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.only(top: 16),
|
||||
child: const Text(
|
||||
'It looks like you are experiencing problems\nwith our sign up process. We are here to\nhelp so please get in touch with us',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Center(
|
||||
child: Container(
|
||||
width: 140,
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.blue,
|
||||
borderRadius:
|
||||
const BorderRadius.all(Radius.circular(4.0)),
|
||||
boxShadow: <BoxShadow>[
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.6),
|
||||
offset: const Offset(4, 4),
|
||||
blurRadius: 8.0),
|
||||
],
|
||||
),
|
||||
child: Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: () {},
|
||||
child: Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
child: Text(
|
||||
'Chat with Us',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,322 @@
|
|||
import 'package:flutter/material.dart';
|
||||
// import 'package:flutter/services.dart';
|
||||
import 'package:sanmill/generated/l10n.dart';
|
||||
import 'package:sanmill/style/app_theme.dart';
|
||||
|
||||
class HomeDrawer extends StatefulWidget {
|
||||
const HomeDrawer(
|
||||
{Key key,
|
||||
this.screenIndex,
|
||||
this.iconAnimationController,
|
||||
this.callBackIndex})
|
||||
: super(key: key);
|
||||
|
||||
final AnimationController iconAnimationController;
|
||||
final DrawerIndex screenIndex;
|
||||
final Function(DrawerIndex) callBackIndex;
|
||||
|
||||
@override
|
||||
_HomeDrawerState createState() => _HomeDrawerState();
|
||||
}
|
||||
|
||||
class _HomeDrawerState extends State<HomeDrawer> {
|
||||
List<DrawerList> drawerList;
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
void setDrawerListArray() {
|
||||
drawerList = <DrawerList>[
|
||||
DrawerList(
|
||||
index: DrawerIndex.humanVsAi,
|
||||
labelName: S.of(context).humanVsAi,
|
||||
icon: Icon(Icons.person),
|
||||
),
|
||||
DrawerList(
|
||||
index: DrawerIndex.humanVsHuman,
|
||||
labelName: S.of(context).humanVsHuman,
|
||||
icon: Icon(Icons.group),
|
||||
),
|
||||
DrawerList(
|
||||
index: DrawerIndex.aiVsAi,
|
||||
labelName: S.of(context).aiVsAi,
|
||||
icon: Icon(Icons.computer),
|
||||
),
|
||||
DrawerList(
|
||||
index: DrawerIndex.settings,
|
||||
labelName: S.of(context).settings,
|
||||
icon: Icon(Icons.settings),
|
||||
),
|
||||
DrawerList(
|
||||
index: DrawerIndex.Help,
|
||||
labelName: S.of(context).help,
|
||||
icon: Icon(Icons.help),
|
||||
),
|
||||
/*
|
||||
DrawerList(
|
||||
index: DrawerIndex.FeedBack,
|
||||
labelName: S.of(context).feedback,
|
||||
icon: Icon(Icons.feedback),
|
||||
),
|
||||
DrawerList(
|
||||
index: DrawerIndex.Invite,
|
||||
labelName: S.of(context).inviteFriend,
|
||||
icon: Icon(Icons.group),
|
||||
),
|
||||
DrawerList(
|
||||
index: DrawerIndex.Share,
|
||||
labelName: S.of(context).rateTheApp,
|
||||
icon: Icon(Icons.share),
|
||||
),
|
||||
*/
|
||||
DrawerList(
|
||||
index: DrawerIndex.About,
|
||||
labelName: S.of(context).about,
|
||||
icon: Icon(Icons.info),
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
setDrawerListArray();
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: AppTheme.notWhite.withOpacity(0.5),
|
||||
body: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.only(top: 0.0),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
AnimatedBuilder(
|
||||
animation: widget.iconAnimationController,
|
||||
builder: (BuildContext context, Widget child) {
|
||||
return ScaleTransition(
|
||||
scale: AlwaysStoppedAnimation<double>(
|
||||
1.0 - (widget.iconAnimationController.value) * 0.2),
|
||||
child: RotationTransition(
|
||||
turns: AlwaysStoppedAnimation<double>(Tween<double>(
|
||||
begin: 0.0, end: 24.0)
|
||||
.animate(CurvedAnimation(
|
||||
parent: widget.iconAnimationController,
|
||||
curve: Curves.fastOutSlowIn))
|
||||
.value /
|
||||
360),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8, left: 4),
|
||||
child: Text(
|
||||
S.of(context).appName,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppTheme.grey,
|
||||
fontSize: 24,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 4,
|
||||
),
|
||||
Divider(
|
||||
height: 1,
|
||||
color: AppTheme.grey.withOpacity(0.6),
|
||||
),
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
physics: const BouncingScrollPhysics(),
|
||||
padding: const EdgeInsets.all(0.0),
|
||||
itemCount: drawerList.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return inkwell(drawerList[index]);
|
||||
},
|
||||
),
|
||||
),
|
||||
Divider(
|
||||
height: 1,
|
||||
color: AppTheme.grey.withOpacity(0.6),
|
||||
),
|
||||
/*
|
||||
Column(
|
||||
children: <Widget>[
|
||||
ListTile(
|
||||
title: Text(
|
||||
S.of(context).exit,
|
||||
style: TextStyle(
|
||||
fontFamily: AppTheme.fontName,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 16,
|
||||
color: AppTheme.darkText,
|
||||
),
|
||||
textAlign: TextAlign.left,
|
||||
),
|
||||
trailing: Icon(
|
||||
Icons.power_settings_new,
|
||||
color: Colors.red,
|
||||
),
|
||||
onTap: () async {
|
||||
await SystemChannels.platform
|
||||
.invokeMethod<void>('SystemNavigator.pop');
|
||||
},
|
||||
),
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context).padding.bottom,
|
||||
)
|
||||
],
|
||||
),
|
||||
*/
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget inkwell(DrawerList listData) {
|
||||
return Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
splashColor: Colors.grey.withOpacity(0.1),
|
||||
highlightColor: Colors.transparent,
|
||||
onTap: () {
|
||||
navigationtoScreen(listData.index);
|
||||
},
|
||||
child: Stack(
|
||||
children: <Widget>[
|
||||
Container(
|
||||
padding: const EdgeInsets.only(top: 8.0, bottom: 8.0),
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Container(
|
||||
width: 6.0,
|
||||
height: 46.0,
|
||||
// decoration: BoxDecoration(
|
||||
// color: widget.screenIndex == listData.index
|
||||
// ? Colors.blue
|
||||
// : Colors.transparent,
|
||||
// borderRadius: new BorderRadius.only(
|
||||
// topLeft: Radius.circular(0),
|
||||
// topRight: Radius.circular(16),
|
||||
// bottomLeft: Radius.circular(0),
|
||||
// bottomRight: Radius.circular(16),
|
||||
// ),
|
||||
// ),
|
||||
),
|
||||
const Padding(
|
||||
padding: EdgeInsets.all(4.0),
|
||||
),
|
||||
listData.isAssetsImage
|
||||
? Container(
|
||||
width: 24,
|
||||
height: 24,
|
||||
child: Image.asset(listData.imageName,
|
||||
color: widget.screenIndex == listData.index
|
||||
? Colors.blue
|
||||
: AppTheme.nearlyBlack),
|
||||
)
|
||||
: Icon(listData.icon.icon,
|
||||
color: widget.screenIndex == listData.index
|
||||
? Colors.blue
|
||||
: AppTheme.nearlyBlack),
|
||||
const Padding(
|
||||
padding: EdgeInsets.all(4.0),
|
||||
),
|
||||
Text(
|
||||
listData.labelName,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 16,
|
||||
color: widget.screenIndex == listData.index
|
||||
? Colors.blue
|
||||
: AppTheme.nearlyBlack,
|
||||
),
|
||||
textAlign: TextAlign.left,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
widget.screenIndex == listData.index
|
||||
? AnimatedBuilder(
|
||||
animation: widget.iconAnimationController,
|
||||
builder: (BuildContext context, Widget child) {
|
||||
return Transform(
|
||||
transform: Matrix4.translationValues(
|
||||
(MediaQuery.of(context).size.width * 0.75 - 64) *
|
||||
(1.0 -
|
||||
widget.iconAnimationController.value -
|
||||
1.0),
|
||||
0.0,
|
||||
0.0),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(top: 8, bottom: 8),
|
||||
child: Container(
|
||||
width:
|
||||
MediaQuery.of(context).size.width * 0.75 - 64,
|
||||
height: 46,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.blue.withOpacity(0.2),
|
||||
borderRadius: new BorderRadius.only(
|
||||
topLeft: Radius.circular(0),
|
||||
topRight: Radius.circular(28),
|
||||
bottomLeft: Radius.circular(0),
|
||||
bottomRight: Radius.circular(28),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
)
|
||||
: const SizedBox()
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> navigationtoScreen(DrawerIndex indexScreen) async {
|
||||
widget.callBackIndex(indexScreen);
|
||||
}
|
||||
}
|
||||
|
||||
enum DrawerIndex {
|
||||
humanVsAi,
|
||||
humanVsHuman,
|
||||
aiVsAi,
|
||||
settings,
|
||||
FeedBack,
|
||||
Help,
|
||||
Share,
|
||||
About,
|
||||
Invite,
|
||||
Testing,
|
||||
}
|
||||
|
||||
class DrawerList {
|
||||
DrawerList({
|
||||
this.isAssetsImage = false,
|
||||
this.labelName = '',
|
||||
this.icon,
|
||||
this.index,
|
||||
this.imageName = '',
|
||||
});
|
||||
|
||||
String labelName;
|
||||
Icon icon;
|
||||
bool isAssetsImage;
|
||||
String imageName;
|
||||
DrawerIndex index;
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:sanmill/engine/engine.dart';
|
||||
import 'package:sanmill/mill/game.dart';
|
||||
import 'package:sanmill/style/app_theme.dart';
|
||||
import 'package:sanmill/widgets/drawer_user_controller.dart';
|
||||
import 'package:sanmill/widgets/feedback_screen.dart';
|
||||
import 'package:sanmill/widgets/help_screen.dart';
|
||||
import 'package:sanmill/widgets/home_drawer.dart';
|
||||
|
||||
import 'game_page.dart';
|
||||
import 'settings_page.dart';
|
||||
|
||||
class NavigationHomeScreen extends StatefulWidget {
|
||||
@override
|
||||
_NavigationHomeScreenState createState() => _NavigationHomeScreenState();
|
||||
}
|
||||
|
||||
class _NavigationHomeScreenState extends State<NavigationHomeScreen> {
|
||||
Widget screenView;
|
||||
DrawerIndex drawerIndex;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
drawerIndex = DrawerIndex.humanVsAi;
|
||||
screenView = GamePage(EngineType.humanVsAi);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
color: AppTheme.nearlyWhite,
|
||||
child: SafeArea(
|
||||
top: false,
|
||||
bottom: false,
|
||||
child: Scaffold(
|
||||
backgroundColor: AppTheme.nearlyWhite,
|
||||
body: DrawerUserController(
|
||||
screenIndex: drawerIndex,
|
||||
drawerWidth: MediaQuery.of(context).size.width * 0.75,
|
||||
onDrawerCall: (DrawerIndex drawerIndexData) {
|
||||
changeIndex(drawerIndexData);
|
||||
//callback from drawer for replace screen as user need with passing DrawerIndex(Enum index)
|
||||
},
|
||||
screenView: screenView,
|
||||
//we replace screen view as we need on navigate starting screens like MyHomePage, HelpScreen, FeedbackScreen, etc...
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void changeIndex(DrawerIndex drawerIndexdata) {
|
||||
if (drawerIndex != drawerIndexdata) {
|
||||
drawerIndex = drawerIndexdata;
|
||||
if (drawerIndex == DrawerIndex.humanVsAi) {
|
||||
setState(() {
|
||||
Game.shared.setWhoIsAi(EngineType.humanVsAi);
|
||||
screenView = GamePage(EngineType.humanVsAi);
|
||||
});
|
||||
} else if (drawerIndex == DrawerIndex.humanVsHuman) {
|
||||
setState(() {
|
||||
Game.shared.setWhoIsAi(EngineType.humanVsHuman);
|
||||
screenView = GamePage(EngineType.humanVsHuman);
|
||||
});
|
||||
} else if (drawerIndex == DrawerIndex.aiVsAi) {
|
||||
setState(() {
|
||||
Game.shared.setWhoIsAi(EngineType.aiVsAi);
|
||||
screenView = GamePage(EngineType.aiVsAi);
|
||||
});
|
||||
} else if (drawerIndex == DrawerIndex.settings) {
|
||||
setState(() {
|
||||
screenView = SettingsPage();
|
||||
});
|
||||
} else if (drawerIndex == DrawerIndex.Help) {
|
||||
setState(() {
|
||||
screenView = HelpScreen();
|
||||
});
|
||||
} else if (drawerIndex == DrawerIndex.FeedBack) {
|
||||
setState(() {
|
||||
screenView = FeedbackScreen();
|
||||
});
|
||||
} else if (drawerIndex == DrawerIndex.Invite) {
|
||||
setState(() {
|
||||
screenView = HelpScreen();
|
||||
});
|
||||
} else {
|
||||
//do in your way......
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -481,7 +481,7 @@ class _SettingsPageState extends State<SettingsPage> {
|
|||
|
||||
return Scaffold(
|
||||
backgroundColor: UIColors.lightBackgroundColor,
|
||||
appBar: AppBar(title: Text(S.of(context).settings)),
|
||||
appBar: AppBar(centerTitle: true, title: Text(S.of(context).settings)),
|
||||
body: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
|
|
Loading…
Reference in New Issue