Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added theme toggle functionality with dark and light mode #30

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
compileSdkVersion 33
compileSdkVersion 34

sourceSets {
main.java.srcDirs += 'src/main/kotlin'
Expand Down
53 changes: 27 additions & 26 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,45 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.nankai.flutter_nearby_connections_example">
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application android:name="${applicationName}"

<application
android:name="${applicationName}"
android:label="flutter_nearby_connections_example"
android:icon="@mipmap/ic_launcher">
<activity android:name="io.flutter.embedding.android.FlutterActivity"

<!-- Main Activity -->
<activity
android:name="io.flutter.embedding.android.FlutterActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<!-- Displays an Android View that continues showing the launch screen
Drawable until Flutter paints its first frame, then this splash
screen fades out. A splash screen is useful to avoid any visual
gap between the end of Android's launch screen and the painting of
Flutter's first frame. -->
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme" />
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background"
/>
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background" />
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->

<!-- Nearby Service -->
<service
android:name="com.nankai.flutter_nearby_connections.NearbyService"
android:exported="true"
android:foregroundServiceType="location"
android:permission="android.permission.BIND_JOB_SERVICE"
tools:replace="android:exported" />

<!-- Flutter Metadata -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>

</manifest>
2 changes: 1 addition & 1 deletion android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.1-all.zip
46 changes: 46 additions & 0 deletions lib/home_screen.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'themes/theme_provider.dart';
import 'themes/theme_data.dart'; // Import AppThemes
import 'settings_page.dart'; // Import SettingsPage

class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
final themeProvider = Provider.of<ThemeProvider>(context);

return Scaffold(
appBar: AppBar(
title: Text('P2P Messaging - AOSSIE'),
actions: [
IconButton(
icon: Icon(Icons.settings),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SettingsPage()),
);
},
),
],
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Your app\'s main content goes here.',
style: TextStyle(fontSize: 18),
),
SizedBox(height: 20),
SwitchListTile(
title: Text('Dark Mode'),
value: themeProvider.currentTheme == AppThemes.darkTheme,
onChanged: (_) => themeProvider.toggleTheme(),
),
],
),
),
);
}
}
42 changes: 8 additions & 34 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,52 +1,26 @@
/// The logic for the Adhoc and the UI are separated.
/// The different section are listed as follows
/// - p2p => Backend of application where message protocols, connections, state are managed
/// - pages => This is the UI section of the application
/// - encryption => The messages are encrypted here.
/// - database => Storage for our messages and conversations
/// - classes => Different model classes for databases
/// - components => Common UI components

import 'package:flutter/material.dart';
import 'classes/Global.dart';
import 'package:provider/provider.dart';
import 'pages/Profile.dart';
import 'themes/theme_provider.dart';
import 'home_screen.dart';

void main() {
runApp(
// Provider is used for state management. The state management will help us
// to know when a new message has arrived and to refresh the chat page.
MultiProvider(
providers: [
ChangeNotifierProvider(
// Currently we have single class for to manage which contains the
// required data and streams
create: (_) => Global(),
),
],
ChangeNotifierProvider(
create: (_) => ThemeProvider(), // Provide ThemeProvider for theme management
child: MyApp(),
),
);
}

Route<dynamic> generateRoute(RouteSettings settings) {
// Initially app opens the profile page where we need to either create
// new profile or
// navigate to the home screen
return MaterialPageRoute(
builder: (_) => Profile(
onLogin: true,
),
);
}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final themeProvider = Provider.of<ThemeProvider>(context);

return MaterialApp(
debugShowCheckedModeBanner: false,
onGenerateRoute: generateRoute,
initialRoute: '/',
theme: themeProvider.currentTheme, // Dynamically set the theme
home: HomeScreen(), // Home screen of the app
);
}
}
31 changes: 31 additions & 0 deletions lib/settings_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'themes/theme_provider.dart';
import 'themes/theme_data.dart'; // Import AppThemes

class SettingsPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
// Access the ThemeProvider to manage theme toggling
final themeProvider = Provider.of<ThemeProvider>(context);

return Scaffold(
appBar: AppBar(
title: Text("Settings"), // Title for the AppBar
),
body: ListView(
children: [
ListTile(
title: Text("Dark Mode"),
trailing: Switch(
value: themeProvider.currentTheme == AppThemes.darkTheme,
onChanged: (value) {
themeProvider.toggleTheme();
},
),
),
],
),
);
}
}
23 changes: 23 additions & 0 deletions lib/themes/theme_data.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import 'package:flutter/material.dart';

class AppThemes {
static final ThemeData lightTheme = ThemeData(
brightness: Brightness.light,
primarySwatch: Colors.blue,
scaffoldBackgroundColor: Colors.white,
appBarTheme: AppBarTheme(
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
),
);

static final ThemeData darkTheme = ThemeData(
brightness: Brightness.dark,
primarySwatch: Colors.teal,
scaffoldBackgroundColor: Colors.black,
appBarTheme: AppBarTheme(
backgroundColor: Colors.teal,
foregroundColor: Colors.white,
),
);
}
30 changes: 30 additions & 0 deletions lib/themes/theme_provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'theme_data.dart';

class ThemeProvider extends ChangeNotifier {
ThemeData _currentTheme = AppThemes.lightTheme;

ThemeProvider() {
_loadTheme();
}

ThemeData get currentTheme => _currentTheme;

void toggleTheme() async {
_currentTheme =
_currentTheme == AppThemes.lightTheme ? AppThemes.darkTheme : AppThemes.lightTheme;
notifyListeners();

// Persist theme choice
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setBool('isDarkTheme', _currentTheme == AppThemes.darkTheme);
}

void _loadTheme() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
bool isDarkTheme = prefs.getBool('isDarkTheme') ?? false;
_currentTheme = isDarkTheme ? AppThemes.darkTheme : AppThemes.lightTheme;
notifyListeners();
}
}
8 changes: 4 additions & 4 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ dependencies:
intl: ^0.17.0
rsa_encrypt: ^2.0.0
pointycastle: ^3.0.1
shared_preferences: ^2.0.15
provider: ^6.0.3
shared_preferences: ^2.0.15 # Required for saving theme preference
provider: ^6.0.3 # Required for state management (e.g., ThemeProvider)

dev_dependencies:
flutter_test:
sdk: flutter

flutter:
uses-material-design: true
uses-material-design: true