diff --git a/lib/main.dart b/lib/main.dart index d7f3bd0..2f6bb02 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -2,13 +2,20 @@ import 'package:flutter/material.dart'; import 'package:adaptive_theme/adaptive_theme.dart'; import 'package:learn/landing_page.dart'; import 'package:learn/utils/route/routes.dart'; +import 'package:learn/theme_provider.dart'; +import 'package:provider/provider.dart'; DateTime? currentBackPressTime; void main() async { WidgetsFlutterBinding.ensureInitialized(); final savedThemeMode = await AdaptiveTheme.getThemeMode(); - runApp(MyApp(savedThemeMode: savedThemeMode)); + runApp( + ChangeNotifierProvider( + create: (context) => ThemeProvider(), + child: MyApp(savedThemeMode: savedThemeMode), + ), + ); } class MyApp extends StatelessWidget { @@ -18,12 +25,18 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { - return const MaterialApp( - debugShowCheckedModeBanner: false, - title: 'Learn', - themeMode: ThemeMode.system, - home: LandingPage(), - onGenerateRoute: Routers.generateRoute, + return Consumer( + builder: (context, themeProvider, child) { + return MaterialApp( + debugShowCheckedModeBanner: false, + title: 'Learn', + theme: ThemeData.light(), + darkTheme: ThemeData.dark(), + themeMode: themeProvider.themeMode, + home: const LandingPage(), + onGenerateRoute: Routers.generateRoute, + ); + }, ); } } \ No newline at end of file diff --git a/lib/pages/explore/explore.dart b/lib/pages/explore/explore.dart index a2fbfdc..22c2f5a 100644 --- a/lib/pages/explore/explore.dart +++ b/lib/pages/explore/explore.dart @@ -2,15 +2,26 @@ import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:learn/pages/explore/quiz.dart'; +import 'package:learn/pages/modules/atoz.dart'; +import 'package:learn/pages/modules/birds.dart'; +import 'package:learn/pages/modules/colours.dart'; +import 'package:learn/pages/modules/planets.dart'; +import 'package:learn/pages/modules/shapes.dart'; import 'package:learn/utils/constants.dart'; import 'package:learn/utils/route/route_constant.dart'; import '../../utils/const_dimensions.dart'; // Explore Page -class ExplorePage extends StatelessWidget { +class ExplorePage extends StatefulWidget { const ExplorePage({super.key}); + @override + State createState() => _ExplorePageState(); +} + +class _ExplorePageState extends State { @override Widget build(BuildContext context) { return SafeArea( @@ -33,7 +44,7 @@ class ExplorePage extends StatelessWidget { [ GestureDetector( onTap: () { - Navigator.pushNamed(context, '/quiz'); + Navigator.push(context, (MaterialPageRoute(builder: (context) => const QuizPage()))); }, child: Container( margin: const EdgeInsets.all(5.0), @@ -105,10 +116,38 @@ class ExplorePage extends StatelessWidget { delegate: SliverChildBuilderDelegate( (context, index) { return GestureDetector( - onTap: () => Navigator.push( - context, - AppConstants.modules[index].route, - ), + onTap: () { + try{ + switch (index) { + case 0: + Navigator.push(context, (MaterialPageRoute(builder: (context) => const QuizPage()))); + break; + case 1: + Navigator.push(context, (MaterialPageRoute(builder: (context) => const AtoZ()))); + break; + case 2: + Navigator.push(context, (MaterialPageRoute(builder: (context) => BirdsPage()))); + break; + case 3: + Navigator.push(context, (MaterialPageRoute(builder: (context) => const ColoursPage()))); + break; + case 4: + Navigator.push(context, (MaterialPageRoute(builder: (context) => BirdsPage()))); + break; + case 5: + Navigator.push(context, (MaterialPageRoute(builder: (context) => const ShapesPage()))); + break; + case 6: + Navigator.push(context, (MaterialPageRoute(builder: (context) => PlanetsPage()))); + break; + default: + break; + } + } + catch (e) { + print(e); + } + }, child: Container( margin: const EdgeInsets.symmetric( horizontal: 24, vertical: 12), diff --git a/lib/pages/home.dart b/lib/pages/home.dart index 3f70e28..9375deb 100644 --- a/lib/pages/home.dart +++ b/lib/pages/home.dart @@ -1,11 +1,11 @@ -// ignore_for_file: deprecated_member_use - import 'package:adaptive_theme/adaptive_theme.dart'; import 'package:flutter/material.dart'; import 'package:learn/utils/assets_path.dart'; import 'package:learn/utils/const_dimensions.dart'; import 'package:learn/utils/route/route_constant.dart'; +import 'package:provider/provider.dart'; import '../widgets/drawer.dart'; +import '../theme_provider.dart'; class MyHomePage extends StatefulWidget { const MyHomePage({Key? key}) : super(key: key); @@ -16,10 +16,10 @@ class MyHomePage extends StatefulWidget { class _MyHomePageState extends State { final List _isImageClicked = List.generate(7, (index) => false); - bool _isDarkTheme = false; @override Widget build(BuildContext context) { + final themeProvider = Provider.of(context); return Scaffold( appBar: AppBar( title: const Text( @@ -31,17 +31,10 @@ class _MyHomePageState extends State { padding: const EdgeInsets.only(right: 16, top: 1), child: IconButton( icon: Icon( - _isDarkTheme ? Icons.dark_mode : Icons.light_mode, + themeProvider.themeMode == ThemeMode.dark ? Icons.dark_mode : Icons.light_mode, ), onPressed: () { - setState(() { - _isDarkTheme = !_isDarkTheme; - }); - final themeMode = - Theme.of(context).brightness == Brightness.dark - ? AdaptiveThemeMode.light - : AdaptiveThemeMode.dark; - AdaptiveTheme.of(context).setThemeMode(themeMode); + themeProvider.toggleTheme(); }, ), ), @@ -56,8 +49,7 @@ class _MyHomePageState extends State { context: context, title: "ALPHABETS", image: AssetsPath.getAlphabetImage(Alphabets.alphabets), - shortDescription: - "Learn A to Z with pronunciation and an example", + shortDescription: "Learn A to Z with pronunciation and an example", route: AllRoutesConstant.atozRoute, index: 0, ), @@ -79,8 +71,7 @@ class _MyHomePageState extends State { context: context, title: "BODY PARTS", image: AssetsPath.getBodyImage(Body.body), - shortDescription: - "Know about body parts and their pronunciation.", + shortDescription: "Know about body parts and their pronunciation.", route: AllRoutesConstant.partsRoute, index: 2, ), @@ -124,8 +115,7 @@ class _MyHomePageState extends State { context: context, title: "FRUITS & VEGETABLES", image: 'assets/fruitsVeges/cover.jpg', - shortDescription: - "Explore and learn about Fruits and Vegetables!", + shortDescription: "Explore and learn about Fruits and Vegetables!", route: AllRoutesConstant.fruitRoute, index: 6, ), diff --git a/lib/pages/modules/animals.dart b/lib/pages/modules/animals.dart index 81fe262..c40495b 100644 --- a/lib/pages/modules/animals.dart +++ b/lib/pages/modules/animals.dart @@ -10,8 +10,6 @@ import 'package:learn/utils/constants.dart'; import '../../utils/const_dimensions.dart'; class AnimalsPage extends StatelessWidget { - - final FlutterTts flutterTts = FlutterTts(); final AudioPlayer audioPlayer = AudioPlayer(); @@ -31,7 +29,7 @@ class AnimalsPage extends StatelessWidget { itemBuilder: (context, index) { return GestureDetector( onTap: () { - _showAnimalPopup(context, AppConstants.animals[index],index); + _showAnimalPopup(context, AppConstants.animals[index], index); }, child: Container( margin: const EdgeInsets.all(5.0), @@ -46,7 +44,8 @@ class AnimalsPage extends StatelessWidget { SizedBox( width: ConstantDimensions.widthExtraLarge, height: ConstantDimensions.heightExtraLarge, - child: SvgPicture.asset(AppConstants.animals[index].svgAsset), + child: + SvgPicture.asset(AppConstants.animals[index].svgAsset), ), const SizedBox(width: ConstantDimensions.widthMedium_Large), Text( @@ -66,7 +65,8 @@ class AnimalsPage extends StatelessWidget { ); } - Future _showAnimalPopup(BuildContext context, Animal animal, int currentIndex) async { + Future _showAnimalPopup( + BuildContext context, Animal animal, int currentIndex) async { await flutterTts.setVolume(1.0); await flutterTts.setSpeechRate(.5); await flutterTts.setLanguage("EN-IN"); @@ -140,13 +140,11 @@ class _AnimalPopupState extends State { isTapped = !isTapped; }); }, - child: SizedBox( - width: ConstantDimensions.widthExtraLarge * 4, - height: ConstantDimensions.heightExtraLarge * 4, - child: SvgPicture.asset( - widget.animal.svgAsset, - color: isTapped ? const Color.fromARGB(81, 118, 96, 94) : null, - ), + child: SvgPicture.asset( + widget.animal.svgAsset, + color: isTapped ? const Color.fromARGB(81, 118, 96, 94) : null, + width: MediaQuery.of(context).size.width * 0.3, + height: MediaQuery.of(context).size.height * 0.3, ), ), const SizedBox(height: ConstantDimensions.heightSmall_Medium), @@ -157,12 +155,14 @@ class _AnimalPopupState extends State { child: const Text('Play Sound'), ), Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ IconButton( onPressed: () { _navigateToPreviousAnimal(); }, icon: const Icon(Icons.arrow_back), + iconSize: 30, ), SizedBox( width: ConstantDimensions.exceptions[0], @@ -172,6 +172,7 @@ class _AnimalPopupState extends State { _navigateToNextAnimal(); }, icon: const Icon(Icons.arrow_forward), + iconSize: 30, ), ], ) @@ -195,7 +196,7 @@ class _AnimalPopupState extends State { ); } -void _navigateToPreviousAnimal() { + void _navigateToPreviousAnimal() { setState(() { widget.currentIndex = (widget.currentIndex - 1) % widget.animals.length; if (widget.currentIndex < 0) { @@ -212,7 +213,6 @@ void _navigateToPreviousAnimal() { }); } - Future _playAnimalSound(String soundAsset) async { await widget.audioPlayer.setAsset(soundAsset); await widget.audioPlayer.play(); diff --git a/lib/pages/modules/atoz.dart b/lib/pages/modules/atoz.dart index 98a1b12..4505007 100644 --- a/lib/pages/modules/atoz.dart +++ b/lib/pages/modules/atoz.dart @@ -1,4 +1,3 @@ - import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'dart:async'; @@ -38,7 +37,7 @@ class ItemTile extends StatelessWidget { ); }, child: Padding( - padding: const EdgeInsets.all(6), + padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 5), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.stretch, @@ -51,27 +50,25 @@ class ItemTile extends StatelessWidget { ), textAlign: TextAlign.center, ), - const SizedBox(height: 3), LayoutBuilder( - builder: (BuildContext context, BoxConstraints constraints){ - if (MediaQuery.of(context).orientation == - Orientation.portrait) { - return SvgPicture.asset( - item.iconAsset, - width: MediaQuery.of(context).size.width * 0.3, - height: MediaQuery.of(context).size.width * 0.3, - alignment: Alignment.center, - ); - } else { - return SvgPicture.asset( - item.iconAsset, - width: MediaQuery.of(context).size.width * 0.3, - height: MediaQuery.of(context).size.width * 0.2, - alignment: Alignment.center, - ); - } + builder: (BuildContext context, BoxConstraints constraints) { + if (MediaQuery.of(context).orientation == + Orientation.portrait) { + return SvgPicture.asset( + item.iconAsset, + width: MediaQuery.of(context).size.width * 0.2, + height: MediaQuery.of(context).size.height * 0.1, + alignment: Alignment.center, + ); + } else { + return SvgPicture.asset( + item.iconAsset, + width: MediaQuery.of(context).size.width * 0.2, + height: MediaQuery.of(context).size.height * 0.2, + alignment: Alignment.center, + ); } - ), + }), const SizedBox(height: ConstantDimensions.heightExtraSmall / 2), Text(item.description, textAlign: TextAlign.center), ], @@ -157,86 +154,87 @@ class _PopupDialogState extends State<_PopupDialog> { @override Widget build(BuildContext context) { final currentItem = widget.items[currentIndex]; - return SingleChildScrollView( - child: AlertDialog( - contentPadding: EdgeInsets.zero, - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), - content: Container( - padding: EdgeInsets.zero, - width: MediaQuery.of(context).size.width * 0.7, - decoration: BoxDecoration( - color: currentItem.backgroundColor, - borderRadius: BorderRadius.circular(15)), - child: Padding( - padding: const EdgeInsets.all(20), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - mainAxisSize: MainAxisSize.min, - children: [ - Text( - currentItem.title, - style: const TextStyle( - fontWeight: FontWeight.bold, - fontSize: 40, + return AlertDialog( + contentPadding: EdgeInsets.zero, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), + content: Container( + padding: EdgeInsets.zero, + width: MediaQuery.of(context).size.width * 0.75, + height: MediaQuery.of(context).size.height * 0.75, + decoration: BoxDecoration( + color: currentItem.backgroundColor, + borderRadius: BorderRadius.circular(15)), + child: Padding( + padding: const EdgeInsets.all(18), + child: Center( + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + currentItem.title, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 40, + ), + textAlign: TextAlign.center, ), - textAlign: TextAlign.center, - ), - const SizedBox(height: ConstantDimensions.heightMedium), - GestureDetector( - onTap: () { - _speakText(currentItem.description); - }, - child: SvgPicture.asset( - currentItem.iconAsset, - width: MediaQuery.of(context).size.width * 0.5, - height: MediaQuery.of(context).size.width * 0.5, - alignment: Alignment.center, + const SizedBox(height: ConstantDimensions.heightMedium), + GestureDetector( + onTap: () { + _speakText(currentItem.description); + }, + child: SvgPicture.asset( + currentItem.iconAsset, + width: MediaQuery.of(context).size.width * 0.5, + height: MediaQuery.of(context).size.height * 0.3, + alignment: Alignment.center, + ), ), - ), - const SizedBox(height: ConstantDimensions.heightMedium), - Text( - currentItem.description, - textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 28, - - ), - ), - const SizedBox(height: ConstantDimensions.heightMedium), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - ElevatedButton( - onPressed: _previousItem, - child: const Text('Prev'), + const SizedBox(height: ConstantDimensions.heightMedium), + Text( + currentItem.description, + textAlign: TextAlign.center, + style: const TextStyle( + fontSize: 28, + ), ), - ElevatedButton( - onPressed: _nextItem, - child: const Text('Next'), + const SizedBox(height: ConstantDimensions.heightMedium), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + ElevatedButton( + onPressed: _previousItem, + child: const Text('Prev'), + ), + ElevatedButton( + onPressed: _nextItem, + child: const Text('Next'), + ), + ], ), - ], - ), - const SizedBox(height: ConstantDimensions.heightMedium), - ElevatedButton( - style: ButtonStyle( - backgroundColor: WidgetStateProperty.all( - const Color.fromARGB(216, 233, 101, 92), + const SizedBox(height: ConstantDimensions.heightMedium), + ElevatedButton( + style: ButtonStyle( + backgroundColor: WidgetStateProperty.all( + const Color.fromARGB(216, 233, 101, 92), + ), + ), + onPressed: () { + Navigator.pop(context); + }, + child: const Text( + 'Close', + style: TextStyle(color: Colors.white), + ), ), - ), - onPressed: () { - Navigator.pop(context); - }, - child: const Text( - 'Close', - style: TextStyle(color: Colors.white), - ), + ], ), - const SizedBox(height: ConstantDimensions.heightExtraLarge), - ], + ), ), ), ), - ) ); } } @@ -293,7 +291,7 @@ class _AtoZState extends State { child: GridView.count( crossAxisCount: MediaQuery.of(context).size.width ~/ 200, // Adjust the value based on screen width - childAspectRatio: 1.0, // Aspect ratio of items + childAspectRatio: 0.8, // Aspect ratio of items children: List.generate( items.length, (index) => ItemTile( diff --git a/lib/theme_provider.dart b/lib/theme_provider.dart new file mode 100644 index 0000000..6523b4e --- /dev/null +++ b/lib/theme_provider.dart @@ -0,0 +1,12 @@ +import 'package:flutter/material.dart'; + +class ThemeProvider with ChangeNotifier { + ThemeMode _themeMode = ThemeMode.light; + + ThemeMode get themeMode => _themeMode; + + void toggleTheme() { + _themeMode = _themeMode == ThemeMode.light ? ThemeMode.dark : ThemeMode.light; + notifyListeners(); + } +} diff --git a/pubspec.yaml b/pubspec.yaml index d679592..30a1172 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,7 +2,7 @@ name: learn description: "Learning app for kids" # The following line prevents the package from being accidentally published to # pub.dev using `flutter pub publish`. This is preferred for private packages. -publish_to: 'none' # Remove this line if you wish to publish to pub.dev +publish_to: "none" # Remove this line if you wish to publish to pub.dev # The following defines the version and build number for your application. # A version number is three numbers separated by dots, like 1.2.43 @@ -19,7 +19,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.1.0+15 environment: - sdk: '>=3.2.0 <4.0.0' + sdk: ">=3.2.0 <4.0.0" # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions @@ -31,7 +31,6 @@ dependencies: flutter: sdk: flutter - # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. google_fonts: ^6.1.0 @@ -42,7 +41,7 @@ dependencies: card_swiper: ^3.0.1 flutter_card_swiper: ^7.0.0 adaptive_theme: ^3.6.0 - fluttertoast: 8.0.9 + fluttertoast: ^8.2.5 google_nav_bar: ^5.0.6 flutter_bloc: ^8.1.5 animated_text_kit: ^4.2.2 @@ -51,6 +50,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter + provider: ^6.0.3 # The "flutter_lints" package below contains a set of recommended lints to # encourage good coding practices. The lint set provided by the package is @@ -64,7 +64,6 @@ dev_dependencies: # The following section is specific to Flutter packages. flutter: - # The following line ensures that the Material Icons font is # included with your application, so that you can use the icons in # the material Icons class.