D1APP-25 BNB

This commit is contained in:
MohammadTaha Basiri 2021-12-12 18:23:53 +03:30
parent 0276f996cc
commit dc7ed94382
12 changed files with 177 additions and 17 deletions

Binary file not shown.

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
class DesignConfig { class DesignConfig {
static const Color lightPrimaryColor2 = Color(0XFFE6F3FA);
static const Color lightPrimaryColor3 = Color(0XFFF5FAFC); static const Color lightPrimaryColor3 = Color(0XFFF5FAFC);
static const Color primaryColor = Color(0XFF007EA7); static const Color primaryColor = Color(0XFF007EA7);
static const Color darkPrimaryColor2 = Color(0XFF1B3C59); static const Color darkPrimaryColor2 = Color(0XFF1B3C59);
@ -40,7 +41,7 @@ class DesignConfig {
brightness: Brightness.light, brightness: Brightness.light,
); );
static const currentColorScheme = lightColorScheme; static const ColorScheme currentColorScheme = lightColorScheme;
static const TextStyle subtitle1Text = TextStyle( static const TextStyle subtitle1Text = TextStyle(
fontSize: 17, fontSize: 17,
@ -74,14 +75,14 @@ class DesignConfig {
); );
static final List<BoxShadow> defaultShadow = [ static final List<BoxShadow> defaultShadow = [
BoxShadow( BoxShadow(
color: const Color(0XFF4D4D4D).withOpacity(0.25), color: currentColorScheme.primaryVariant.withOpacity(0.25),
offset: const Offset(0, 4), blurRadius: 16,
blurRadius: 8,
spreadRadius: 0, spreadRadius: 0,
) )
]; ];
static const Duration defaultAnimationDuration = Duration(milliseconds: 600); static const Duration lowAnimationDuration = Duration(milliseconds: 300);
static const Duration mediumAnimationDuration = Duration(milliseconds: 600);
static final SystemUiOverlayStyle systemUIOverlayStyle = SystemUiOverlayStyle( static final SystemUiOverlayStyle systemUIOverlayStyle = SystemUiOverlayStyle(
statusBarBrightness: Brightness.dark, statusBarBrightness: Brightness.dark,

View File

@ -27,7 +27,7 @@ class _AuthenticationState extends State<Authentication> {
return Scaffold( return Scaffold(
body: Consumer<AuthenticationState>( body: Consumer<AuthenticationState>(
builder: (context, state, child) => AnimatedSwitcher( builder: (context, state, child) => AnimatedSwitcher(
duration: DesignConfig.defaultAnimationDuration, duration: DesignConfig.mediumAnimationDuration,
child: _pages[state.currentPageIndex], child: _pages[state.currentPageIndex],
), ),
), ),

View File

@ -1,9 +1,11 @@
import 'package:didvan/pages/home/home_state.dart';
import 'package:didvan/pages/home/news/news.dart'; import 'package:didvan/pages/home/news/news.dart';
import 'package:didvan/pages/home/profile/profile.dart'; import 'package:didvan/pages/home/profile/profile.dart';
import 'package:didvan/pages/home/radar/radar.dart'; import 'package:didvan/pages/home/radar/radar.dart';
import 'package:didvan/pages/home/radar/radar_state.dart'; import 'package:didvan/pages/home/radar/radar_state.dart';
import 'package:didvan/pages/home/statistics/statistics.dart'; import 'package:didvan/pages/home/statistics/statistics.dart';
import 'package:didvan/pages/home/studio/studio..dart'; import 'package:didvan/pages/home/studio/studio..dart';
import 'package:didvan/pages/home/widgets/didvan_bnb.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -20,7 +22,9 @@ class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
@override @override
void initState() { void initState() {
_tabController = TabController(length: 5, vsync: this); _tabController = TabController(length: 5, vsync: this);
_tabController.addListener(() {}); _tabController.addListener(() {
context.read<HomeState>().currentPageIndex = _tabController.index;
});
super.initState(); super.initState();
} }
@ -44,6 +48,15 @@ class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
], ],
), ),
), ),
bottomNavigationBar: Consumer<HomeState>(
builder: (context, state, child) => DidvanBNB(
currentTabIndex: state.currentPageIndex,
onTabChanged: (index) {
state.currentPageIndex = index;
_tabController.animateTo(index);
},
),
),
); );
} }
} }

View File

@ -0,0 +1,12 @@
import 'package:didvan/providers/core_provider.dart';
class HomeState extends CoreProvier {
int _currentPageIndex = 0;
set currentPageIndex(int value) {
_currentPageIndex = value;
notifyListeners();
}
int get currentPageIndex => _currentPageIndex;
}

View File

@ -30,7 +30,7 @@ class _RadarState extends State<Radar> {
_isAnimating = true; _isAnimating = true;
await _scrollController.animateTo( await _scrollController.animateTo(
380, 380,
duration: DesignConfig.defaultAnimationDuration, duration: DesignConfig.mediumAnimationDuration,
curve: Curves.ease, curve: Curves.ease,
); );
_isAnimating = false; _isAnimating = false;
@ -40,7 +40,7 @@ class _RadarState extends State<Radar> {
_isAnimating = true; _isAnimating = true;
await _scrollController.animateTo( await _scrollController.animateTo(
0, 0,
duration: DesignConfig.defaultAnimationDuration, duration: DesignConfig.mediumAnimationDuration,
curve: Curves.ease, curve: Curves.ease,
); );
_isAnimating = false; _isAnimating = false;

View File

@ -12,7 +12,7 @@ class CategoriesRow1 extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final MediaQueryData d = MediaQuery.of(context); final MediaQueryData d = MediaQuery.of(context);
return AnimatedPositioned( return AnimatedPositioned(
duration: DesignConfig.defaultAnimationDuration, duration: DesignConfig.mediumAnimationDuration,
top: isColapsed ? 12 : 176 + d.padding.top, top: isColapsed ? 12 : 176 + d.padding.top,
left: isColapsed ? -d.size.width : 0, left: isColapsed ? -d.size.width : 0,
right: isColapsed ? d.size.width : 0, right: isColapsed ? d.size.width : 0,
@ -51,7 +51,7 @@ class CategoriesRow2 extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final MediaQueryData d = MediaQuery.of(context); final MediaQueryData d = MediaQuery.of(context);
return AnimatedPositioned( return AnimatedPositioned(
duration: DesignConfig.defaultAnimationDuration, duration: DesignConfig.mediumAnimationDuration,
top: isColapsed ? -60 : 300 + d.padding.top, top: isColapsed ? -60 : 300 + d.padding.top,
left: isColapsed ? -80 : 0, left: isColapsed ? -80 : 0,
right: isColapsed ? 124 : 0, right: isColapsed ? 124 : 0,

View File

@ -24,7 +24,7 @@ class CategoriesList extends StatelessWidget {
child: AnimatedCrossFade( child: AnimatedCrossFade(
crossFadeState: crossFadeState:
isColapsed ? CrossFadeState.showSecond : CrossFadeState.showFirst, isColapsed ? CrossFadeState.showSecond : CrossFadeState.showFirst,
duration: DesignConfig.defaultAnimationDuration, duration: DesignConfig.mediumAnimationDuration,
firstChild: const SizedBox(), firstChild: const SizedBox(),
secondChild: Container( secondChild: Container(
height: 60 + d.padding.top, height: 60 + d.padding.top,
@ -44,7 +44,7 @@ class CategoriesList extends StatelessWidget {
children: [ children: [
AnimatedVisibility( AnimatedVisibility(
isVisible: isColapsed, isVisible: isColapsed,
duration: DesignConfig.defaultAnimationDuration, duration: DesignConfig.mediumAnimationDuration,
child: _itemBuilder( child: _itemBuilder(
RadarCategory(title: 'همه', asset: '', id: 0), RadarCategory(title: 'همه', asset: '', id: 0),
), ),

View File

@ -20,7 +20,7 @@ class CategoryItem extends StatelessWidget {
final Size ds = MediaQuery.of(context).size; final Size ds = MediaQuery.of(context).size;
return Center( return Center(
child: AnimatedContainer( child: AnimatedContainer(
duration: DesignConfig.defaultAnimationDuration, duration: DesignConfig.mediumAnimationDuration,
padding: isColapsed ? const EdgeInsets.all(4) : EdgeInsets.zero, padding: isColapsed ? const EdgeInsets.all(4) : EdgeInsets.zero,
width: isColapsed ? 100 : ds.width / 3, width: isColapsed ? 100 : ds.width / 3,
alignment: Alignment.center, alignment: Alignment.center,
@ -33,7 +33,7 @@ class CategoryItem extends StatelessWidget {
child: Column( child: Column(
children: [ children: [
AnimatedVisibility( AnimatedVisibility(
duration: DesignConfig.defaultAnimationDuration, duration: DesignConfig.mediumAnimationDuration,
isVisible: !isColapsed, isVisible: !isColapsed,
child: Container( child: Container(
width: ds.width / 5, width: ds.width / 5,

View File

@ -0,0 +1,129 @@
import 'package:didvan/config/design_config.dart';
import 'package:didvan/constants/app_icons.dart';
import 'package:didvan/widgets/didvan/text.dart';
import 'package:flutter/material.dart';
class DidvanBNB extends StatelessWidget {
final int currentTabIndex;
final void Function(int index) onTabChanged;
const DidvanBNB(
{Key? key, required this.currentTabIndex, required this.onTabChanged})
: super(key: key);
@override
Widget build(BuildContext context) {
return Container(
height: 64,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
borderRadius: const BorderRadius.vertical(top: Radius.circular(16)),
boxShadow: DesignConfig.defaultShadow,
),
padding: const EdgeInsets.symmetric(horizontal: 12),
child: Row(
children: [
_NavBarItem(
isSelected: currentTabIndex == 0,
title: 'اخبار',
selectedIcon: DidvanIcons.news_solid,
unselectedIcon: DidvanIcons.news_light,
onTap: () => onTabChanged(0),
),
_NavBarItem(
isSelected: currentTabIndex == 1,
title: 'آمار',
selectedIcon: DidvanIcons.chart_solid,
unselectedIcon: DidvanIcons.chart_light,
onTap: () => onTabChanged(1),
),
_NavBarItem(
isSelected: currentTabIndex == 2,
title: 'رادار',
selectedIcon: DidvanIcons.news_solid,
unselectedIcon: DidvanIcons.news_regular,
onTap: () => onTabChanged(2),
),
_NavBarItem(
isSelected: currentTabIndex == 3,
title: 'استودیو',
selectedIcon: DidvanIcons.play_circle_solid,
unselectedIcon: DidvanIcons.play_circle_light,
onTap: () => onTabChanged(3),
),
_NavBarItem(
isSelected: currentTabIndex == 4,
title: 'پروفایل',
selectedIcon: DidvanIcons.profile_solid,
unselectedIcon: DidvanIcons.profile_light,
onTap: () => onTabChanged(4),
),
],
),
);
}
}
class _NavBarItem extends StatelessWidget {
final VoidCallback onTap;
final bool isSelected;
final String title;
final IconData selectedIcon;
final IconData unselectedIcon;
const _NavBarItem({
Key? key,
required this.isSelected,
required this.title,
required this.selectedIcon,
required this.unselectedIcon,
required this.onTap,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Expanded(
child: Tooltip(
message: title,
decoration: BoxDecoration(
color: DesignConfig.darkPrimaryColor2,
borderRadius: DesignConfig.highBorderRadius,
boxShadow: DesignConfig.defaultShadow,
),
child: GestureDetector(
onTap: onTap,
child: Container(
color: Colors.transparent,
child: Column(
children: [
const SizedBox(
height: 4,
),
AnimatedContainer(
padding: const EdgeInsets.all(4),
duration: DesignConfig.lowAnimationDuration,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: isSelected
? DesignConfig.lightPrimaryColor2
: Theme.of(context).colorScheme.surface,
),
child: Icon(
isSelected ? selectedIcon : unselectedIcon,
size: 32,
color: isSelected ? DesignConfig.darkPrimaryColor2 : null,
),
),
DidvanText(
title,
style: Theme.of(context).textTheme.caption,
color: DesignConfig.darkPrimaryColor2,
),
const Spacer(),
],
),
),
),
),
);
}
}

View File

@ -1,6 +1,7 @@
import 'package:didvan/pages/authentication/authentication.dart'; import 'package:didvan/pages/authentication/authentication.dart';
import 'package:didvan/pages/authentication/authentication_state.dart'; import 'package:didvan/pages/authentication/authentication_state.dart';
import 'package:didvan/pages/home/home.dart'; import 'package:didvan/pages/home/home.dart';
import 'package:didvan/pages/home/home_state.dart';
import 'package:didvan/pages/home/radar/radar.dart'; import 'package:didvan/pages/home/radar/radar.dart';
import 'package:didvan/pages/home/radar/radar_state.dart'; import 'package:didvan/pages/home/radar/radar_state.dart';
import 'package:didvan/pages/splash/splash.dart'; import 'package:didvan/pages/splash/splash.dart';
@ -28,7 +29,10 @@ class RouteGenerator {
); );
case Routes.home: case Routes.home:
return _materialPageRouteGenerator( return _materialPageRouteGenerator(
const Home(), ChangeNotifierProvider<HomeState>(
create: (context) => HomeState(),
child: const Home(),
),
); );
default: default:
return _errorRoute(); return _errorRoute();

View File

@ -10,7 +10,8 @@ class ActionSheetUtils {
context: context, context: context,
builder: (context) => Padding( builder: (context) => Padding(
padding: EdgeInsets.symmetric( padding: EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width / 3), horizontal: MediaQuery.of(context).size.width / 3,
),
child: const RiveAnimation.asset(Assets.logoLoadingAnimation), child: const RiveAnimation.asset(Assets.logoLoadingAnimation),
), ),
); );