Skip to content

Commit 532c53b

Browse files
committed
dark light toggle icon
1 parent aac70cb commit 532c53b

File tree

4 files changed

+267
-78
lines changed

4 files changed

+267
-78
lines changed
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:shared_preferences/shared_preferences.dart';
3+
4+
class ThemeProvider extends ChangeNotifier {
5+
bool _isDarkMode = false;
6+
static const String _themePreferenceKey = 'isDarkMode';
7+
8+
bool get isDarkMode => _isDarkMode;
9+
10+
ThemeProvider() {
11+
_loadThemePreference();
12+
}
13+
14+
void toggleTheme() {
15+
_isDarkMode = !_isDarkMode;
16+
_saveThemePreference();
17+
notifyListeners();
18+
}
19+
20+
void setDarkMode(bool value) {
21+
_isDarkMode = value;
22+
_saveThemePreference();
23+
notifyListeners();
24+
}
25+
26+
Future<void> _loadThemePreference() async {
27+
try {
28+
final prefs = await SharedPreferences.getInstance();
29+
_isDarkMode = prefs.getBool(_themePreferenceKey) ?? false;
30+
notifyListeners();
31+
} catch (e) {
32+
debugPrint('Error loading theme preference: $e');
33+
}
34+
}
35+
36+
Future<void> _saveThemePreference() async {
37+
try {
38+
final prefs = await SharedPreferences.getInstance();
39+
await prefs.setBool(_themePreferenceKey, _isDarkMode);
40+
} catch (e) {
41+
debugPrint('Error saving theme preference: $e');
42+
}
43+
}
44+
45+
ThemeData get lightTheme => ThemeData.light().copyWith(
46+
primaryColor: Colors.pinkAccent,
47+
scaffoldBackgroundColor: const Color(0xFFF5F5F5),
48+
appBarTheme: const AppBarTheme(
49+
backgroundColor: Colors.transparent,
50+
elevation: 0,
51+
iconTheme: IconThemeData(color: Colors.black87),
52+
titleTextStyle: TextStyle(
53+
color: Colors.black87,
54+
fontSize: 20,
55+
fontWeight: FontWeight.w600,
56+
),
57+
),
58+
textTheme: const TextTheme(
59+
bodyLarge: TextStyle(color: Colors.black87),
60+
bodyMedium: TextStyle(color: Colors.black87),
61+
),
62+
);
63+
64+
ThemeData get darkTheme => ThemeData.dark().copyWith(
65+
primaryColor: Colors.pinkAccent,
66+
scaffoldBackgroundColor: Colors.black,
67+
appBarTheme: const AppBarTheme(
68+
backgroundColor: Colors.transparent,
69+
elevation: 0,
70+
iconTheme: IconThemeData(color: Colors.white),
71+
titleTextStyle: TextStyle(
72+
color: Colors.white,
73+
fontSize: 20,
74+
fontWeight: FontWeight.w600,
75+
),
76+
),
77+
textTheme: const TextTheme(
78+
bodyLarge: TextStyle(color: Colors.white),
79+
bodyMedium: TextStyle(color: Colors.white),
80+
),
81+
);
82+
}

lib/features/home/presentation/widgets/search_bar_widget.dart

Lines changed: 74 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'package:flutter/material.dart';
22
import 'package:provider/provider.dart';
33
import '../../provider/wallpaper_provider.dart';
4+
import 'theme_toggle_button.dart';
45

56
class SearchBarWidget extends StatefulWidget {
67
const SearchBarWidget({super.key});
@@ -33,70 +34,84 @@ class _SearchBarWidgetState extends State<SearchBarWidget> {
3334
builder: (context, provider, child) {
3435
return Container(
3536
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
36-
decoration: BoxDecoration(
37-
color: Theme.of(context).brightness == Brightness.dark
38-
? Colors.grey[800]?.withValues(alpha: 0.8)
39-
: Colors.white.withValues(alpha: 0.8),
40-
borderRadius: BorderRadius.circular(25),
41-
boxShadow: [
42-
BoxShadow(
43-
color: Colors.black.withValues(alpha: 0.1),
44-
blurRadius: 10,
45-
offset: const Offset(0, 2),
46-
),
47-
],
48-
),
49-
child: TextField(
50-
controller: _searchController,
51-
focusNode: _focusNode,
52-
onChanged: (value) {
53-
provider.updateSearchQuery(value);
54-
},
55-
decoration: InputDecoration(
56-
hintText: 'Search wallpapers by title or category...',
57-
hintStyle: TextStyle(
58-
color: Theme.of(context).brightness == Brightness.dark
59-
? Colors.grey[400]
60-
: Colors.grey[600],
61-
fontSize: 16,
62-
),
63-
prefixIcon: Icon(
64-
provider.searchQuery.isNotEmpty ? Icons.search : Icons.search,
65-
color: provider.searchQuery.isNotEmpty
66-
? Colors.pinkAccent
67-
: (Theme.of(context).brightness == Brightness.dark
68-
? Colors.grey[400]
69-
: Colors.grey[600]),
70-
size: 24,
71-
),
72-
suffixIcon: provider.searchQuery.isNotEmpty
73-
? IconButton(
74-
icon: Icon(
75-
Icons.clear,
37+
child: Row(
38+
children: [
39+
Expanded(
40+
child: Container(
41+
decoration: BoxDecoration(
42+
color: Theme.of(context).brightness == Brightness.dark
43+
? Colors.grey[800]?.withValues(alpha: 0.8)
44+
: Colors.white.withValues(alpha: 0.8),
45+
borderRadius: BorderRadius.circular(25),
46+
boxShadow: [
47+
BoxShadow(
48+
color: Colors.black.withValues(alpha: 0.1),
49+
blurRadius: 10,
50+
offset: const Offset(0, 2),
51+
),
52+
],
53+
),
54+
child: TextField(
55+
controller: _searchController,
56+
focusNode: _focusNode,
57+
onChanged: (value) {
58+
provider.updateSearchQuery(value);
59+
},
60+
decoration: InputDecoration(
61+
hintText: 'Search wallpapers by title or category...',
62+
hintStyle: TextStyle(
7663
color: Theme.of(context).brightness == Brightness.dark
7764
? Colors.grey[400]
7865
: Colors.grey[600],
79-
size: 20,
66+
fontSize: 16,
67+
),
68+
prefixIcon: Icon(
69+
provider.searchQuery.isNotEmpty
70+
? Icons.search
71+
: Icons.search,
72+
color: provider.searchQuery.isNotEmpty
73+
? Colors.pinkAccent
74+
: (Theme.of(context).brightness == Brightness.dark
75+
? Colors.grey[400]
76+
: Colors.grey[600]),
77+
size: 24,
8078
),
81-
onPressed: () {
82-
_searchController.clear();
83-
provider.clearSearch();
84-
_focusNode.unfocus();
85-
},
86-
)
87-
: null,
88-
border: InputBorder.none,
89-
contentPadding: const EdgeInsets.symmetric(
90-
horizontal: 20,
91-
vertical: 16,
79+
suffixIcon: provider.searchQuery.isNotEmpty
80+
? IconButton(
81+
icon: Icon(
82+
Icons.clear,
83+
color:
84+
Theme.of(context).brightness ==
85+
Brightness.dark
86+
? Colors.grey[400]
87+
: Colors.grey[600],
88+
size: 20,
89+
),
90+
onPressed: () {
91+
_searchController.clear();
92+
provider.clearSearch();
93+
_focusNode.unfocus();
94+
},
95+
)
96+
: null,
97+
border: InputBorder.none,
98+
contentPadding: const EdgeInsets.symmetric(
99+
horizontal: 20,
100+
vertical: 16,
101+
),
102+
),
103+
style: TextStyle(
104+
color: Theme.of(context).brightness == Brightness.dark
105+
? Colors.white
106+
: Colors.black87,
107+
fontSize: 16,
108+
),
109+
),
110+
),
92111
),
93-
),
94-
style: TextStyle(
95-
color: Theme.of(context).brightness == Brightness.dark
96-
? Colors.white
97-
: Colors.black87,
98-
fontSize: 16,
99-
),
112+
const SizedBox(width: 8),
113+
const ThemeToggleButton(),
114+
],
100115
),
101116
);
102117
},
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:provider/provider.dart';
3+
import 'package:the_wallpaper_company/core/providers/theme_provider.dart';
4+
5+
class ThemeToggleButton extends StatelessWidget {
6+
const ThemeToggleButton({super.key});
7+
8+
@override
9+
Widget build(BuildContext context) {
10+
return Consumer<ThemeProvider>(
11+
builder: (context, themeProvider, child) {
12+
return Container(
13+
margin: const EdgeInsets.only(right: 8),
14+
decoration: BoxDecoration(
15+
color: Theme.of(context).brightness == Brightness.dark
16+
? Colors.grey[800]?.withValues(alpha: 0.8)
17+
: Colors.white.withValues(alpha: 0.8),
18+
borderRadius: BorderRadius.circular(25),
19+
boxShadow: [
20+
BoxShadow(
21+
color: Colors.black.withValues(alpha: 0.1),
22+
blurRadius: 10,
23+
offset: const Offset(0, 2),
24+
),
25+
],
26+
),
27+
child: Material(
28+
color: Colors.transparent,
29+
child: InkWell(
30+
borderRadius: BorderRadius.circular(25),
31+
onTap: () {
32+
themeProvider.toggleTheme();
33+
},
34+
child: Padding(
35+
padding: const EdgeInsets.all(12),
36+
child: AnimatedSwitcher(
37+
duration: const Duration(milliseconds: 300),
38+
transitionBuilder:
39+
(Widget child, Animation<double> animation) {
40+
return RotationTransition(
41+
turns: animation,
42+
child: FadeTransition(
43+
opacity: animation,
44+
child: child,
45+
),
46+
);
47+
},
48+
child: Icon(
49+
themeProvider.isDarkMode
50+
? Icons.light_mode_rounded
51+
: Icons.dark_mode_rounded,
52+
key: ValueKey(themeProvider.isDarkMode),
53+
color: themeProvider.isDarkMode
54+
? Colors.yellow[300]
55+
: Colors.indigo[700],
56+
size: 24,
57+
),
58+
),
59+
),
60+
),
61+
),
62+
);
63+
},
64+
);
65+
}
66+
}

0 commit comments

Comments
 (0)