From 75a8c064819bdf3b79b4e1aa3f43f6c976be9f6b Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sun, 1 Mar 2026 11:31:26 +0000 Subject: [PATCH] Optimize Theme lookups in AppsScreen._buildAppItem Co-authored-by: hexamh <264230460+hexamh@users.noreply.github.com> --- lib/screens/apps_screen.dart | 221 +++++++++++++++++++++++++++++------ test/benchmark_test.dart | 20 ++++ 2 files changed, 203 insertions(+), 38 deletions(-) create mode 100644 test/benchmark_test.dart diff --git a/lib/screens/apps_screen.dart b/lib/screens/apps_screen.dart index 5f72104..c157924 100644 --- a/lib/screens/apps_screen.dart +++ b/lib/screens/apps_screen.dart @@ -13,12 +13,20 @@ class AppsScreen extends StatelessWidget { title: const Text('App Manager'), leading: IconButton( icon: const Icon(Icons.arrow_back), - onPressed: () => Navigator.of(context).pop(), // Pop to return to previous screen if pushed + onPressed: () => Navigator.of( + context, + ).pop(), // Pop to return to previous screen if pushed ), actions: [ TextButton( onPressed: () {}, - child: Text('Select', style: TextStyle(color: primaryColor, fontWeight: FontWeight.bold)), + child: Text( + 'Select', + style: TextStyle( + color: primaryColor, + fontWeight: FontWeight.bold, + ), + ), ), ], ), @@ -33,19 +41,75 @@ class AppsScreen extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildSectionHeader(context, 'User Apps (42)', primaryColor), - _buildAppItem(context, Icons.chat, Colors.green, 'WhatsApp Messenger', 'v2.23.12.78', '145 MB'), - _buildAppItem(context, Icons.camera_alt, Colors.pink, 'Instagram', 'v290.0.0.13', '210 MB'), - _buildAppItem(context, Icons.public, Colors.blue, 'Facebook', 'v418.0.0.33', '305 MB'), - _buildAppItem(context, Icons.play_circle, Colors.greenAccent[700]!, 'Spotify: Music and Podcasts', 'v8.8.44.52', '98 MB', isBlackBg: true), - _buildAppItem(context, Icons.movie, Colors.red, 'Netflix', 'v8.72.1', '112 MB'), - - _buildSectionHeader(context, 'System Apps (12)', primaryColor), - _buildAppItem(context, Icons.settings, Colors.grey, 'Settings', 'v13.0.0', '45 MB', isSystem: true), - _buildAppItem(context, Icons.camera_front, Colors.grey, 'Camera', 'v2.1.0', '25 MB', isSystem: true), + _buildAppItem( + theme, + Icons.chat, + Colors.green, + 'WhatsApp Messenger', + 'v2.23.12.78', + '145 MB', + ), + _buildAppItem( + theme, + Icons.camera_alt, + Colors.pink, + 'Instagram', + 'v290.0.0.13', + '210 MB', + ), + _buildAppItem( + theme, + Icons.public, + Colors.blue, + 'Facebook', + 'v418.0.0.33', + '305 MB', + ), + _buildAppItem( + theme, + Icons.play_circle, + Colors.greenAccent[700]!, + 'Spotify: Music and Podcasts', + 'v8.8.44.52', + '98 MB', + isBlackBg: true, + ), + _buildAppItem( + theme, + Icons.movie, + Colors.red, + 'Netflix', + 'v8.72.1', + '112 MB', + ), + + _buildSectionHeader( + context, + 'System Apps (12)', + primaryColor, + ), + _buildAppItem( + theme, + Icons.settings, + Colors.grey, + 'Settings', + 'v13.0.0', + '45 MB', + isSystem: true, + ), + _buildAppItem( + theme, + Icons.camera_front, + Colors.grey, + 'Camera', + 'v2.1.0', + '25 MB', + isSystem: true, + ), ], ), ), - ) + ), ], ), ); @@ -59,14 +123,22 @@ class AppsScreen extends StatelessWidget { decoration: BoxDecoration( color: Theme.of(context).cardTheme.color, borderRadius: BorderRadius.circular(12), - border: Border.all(color: Theme.of(context).dividerColor.withValues(alpha: 0.1)), + border: Border.all( + color: Theme.of(context).dividerColor.withValues(alpha: 0.1), + ), ), child: TextField( decoration: InputDecoration( hintText: 'Search installed apps', hintStyle: Theme.of(context).textTheme.bodySmall, - prefixIcon: Icon(Icons.search, color: Theme.of(context).textTheme.bodySmall?.color), - suffixIcon: Icon(Icons.mic, color: Theme.of(context).textTheme.bodySmall?.color), + prefixIcon: Icon( + Icons.search, + color: Theme.of(context).textTheme.bodySmall?.color, + ), + suffixIcon: Icon( + Icons.mic, + color: Theme.of(context).textTheme.bodySmall?.color, + ), border: InputBorder.none, contentPadding: const EdgeInsets.symmetric(vertical: 12), ), @@ -93,18 +165,29 @@ class AppsScreen extends StatelessWidget { ); } - Widget _buildPill(BuildContext context, String label, bool isSelected, Color primaryColor) { + Widget _buildPill( + BuildContext context, + String label, + bool isSelected, + Color primaryColor, + ) { return Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), decoration: BoxDecoration( color: isSelected ? primaryColor : Theme.of(context).cardTheme.color, borderRadius: BorderRadius.circular(20), - border: Border.all(color: isSelected ? primaryColor : Theme.of(context).dividerColor.withValues(alpha: 0.1)), + border: Border.all( + color: isSelected + ? primaryColor + : Theme.of(context).dividerColor.withValues(alpha: 0.1), + ), ), child: Text( label, style: TextStyle( - color: isSelected ? Colors.white : Theme.of(context).textTheme.bodyMedium?.color, + color: isSelected + ? Colors.white + : Theme.of(context).textTheme.bodyMedium?.color, fontSize: 12, fontWeight: FontWeight.w500, ), @@ -112,33 +195,61 @@ class AppsScreen extends StatelessWidget { ); } - Widget _buildSectionHeader(BuildContext context, String title, Color primaryColor) { + Widget _buildSectionHeader( + BuildContext context, + String title, + Color primaryColor, + ) { return Padding( padding: const EdgeInsets.fromLTRB(16, 16, 16, 8), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text(title, style: Theme.of(context).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.bold)), + Text( + title, + style: Theme.of( + context, + ).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.bold), + ), Row( children: [ - Text('SORT BY', style: TextStyle(color: primaryColor, fontSize: 10, fontWeight: FontWeight.bold, letterSpacing: 1)), + Text( + 'SORT BY', + style: TextStyle( + color: primaryColor, + fontSize: 10, + fontWeight: FontWeight.bold, + letterSpacing: 1, + ), + ), const SizedBox(width: 4), Icon(Icons.sort, color: primaryColor, size: 16), ], - ) + ), ], ), ); } - Widget _buildAppItem(BuildContext context, IconData icon, Color color, String name, String version, String size, {bool isBlackBg = false, bool isSystem = false}) { + Widget _buildAppItem( + ThemeData theme, + IconData icon, + Color color, + String name, + String version, + String size, { + bool isBlackBg = false, + bool isSystem = false, + }) { return Container( margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), padding: const EdgeInsets.all(12), decoration: BoxDecoration( - color: Theme.of(context).cardTheme.color?.withValues(alpha: isSystem ? 0.5 : 1.0), + color: theme.cardTheme.color?.withValues(alpha: isSystem ? 0.5 : 1.0), borderRadius: BorderRadius.circular(12), - border: Border.all(color: Colors.transparent), // hover border handled natively or ignored in mobile + border: Border.all( + color: Colors.transparent, + ), // hover border handled natively or ignored in mobile ), child: Row( children: [ @@ -148,28 +259,55 @@ class AppsScreen extends StatelessWidget { decoration: BoxDecoration( color: isBlackBg ? Colors.black : color, borderRadius: BorderRadius.circular(12), - gradient: isBlackBg ? null : LinearGradient( - begin: Alignment.topLeft, - end: Alignment.bottomRight, - colors: [color.withValues(alpha: 0.8), color], - ), + gradient: isBlackBg + ? null + : LinearGradient( + begin: Alignment.topLeft, + end: Alignment.bottomRight, + colors: [color.withValues(alpha: 0.8), color], + ), + ), + child: Icon( + icon, + color: isBlackBg ? color : Colors.white, + size: 28, ), - child: Icon(icon, color: isBlackBg ? color : Colors.white, size: 28), ), const SizedBox(width: 16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text(name, style: Theme.of(context).textTheme.bodyMedium?.copyWith(fontWeight: FontWeight.w500, fontSize: 14), maxLines: 1, overflow: TextOverflow.ellipsis), + Text( + name, + style: theme.textTheme.bodyMedium?.copyWith( + fontWeight: FontWeight.w500, + fontSize: 14, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), const SizedBox(height: 4), Row( children: [ - Text(version, style: Theme.of(context).textTheme.bodySmall?.copyWith(fontSize: 12)), + Text( + version, + style: theme.textTheme.bodySmall?.copyWith(fontSize: 12), + ), const SizedBox(width: 6), - Container(width: 4, height: 4, decoration: BoxDecoration(color: Theme.of(context).dividerColor.withValues(alpha: 0.2), shape: BoxShape.circle)), + Container( + width: 4, + height: 4, + decoration: BoxDecoration( + color: theme.dividerColor.withValues(alpha: 0.2), + shape: BoxShape.circle, + ), + ), const SizedBox(width: 6), - Text(size, style: Theme.of(context).textTheme.bodySmall?.copyWith(fontSize: 12)), + Text( + size, + style: theme.textTheme.bodySmall?.copyWith(fontSize: 12), + ), ], ), ], @@ -179,13 +317,20 @@ class AppsScreen extends StatelessWidget { Container( padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), decoration: BoxDecoration( - color: Theme.of(context).dividerColor.withValues(alpha: 0.1), + color: theme.dividerColor.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(4), ), - child: Text('SYSTEM', style: TextStyle(fontSize: 10, fontWeight: FontWeight.bold, color: Theme.of(context).textTheme.bodySmall?.color)), + child: Text( + 'SYSTEM', + style: TextStyle( + fontSize: 10, + fontWeight: FontWeight.bold, + color: theme.textTheme.bodySmall?.color, + ), + ), ), if (!isSystem) - Icon(Icons.chevron_right, color: Theme.of(context).textTheme.bodySmall?.color), + Icon(Icons.chevron_right, color: theme.textTheme.bodySmall?.color), ], ), ); diff --git a/test/benchmark_test.dart b/test/benchmark_test.dart new file mode 100644 index 0000000..ad44156 --- /dev/null +++ b/test/benchmark_test.dart @@ -0,0 +1,20 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:myapp/screens/apps_screen.dart'; + +void main() { + testWidgets('AppsScreen benchmark', (WidgetTester tester) async { + final stopwatch = Stopwatch()..start(); + + for (int i = 0; i < 1000; i++) { + await tester.pumpWidget( + MaterialApp( + home: const AppsScreen(), + ), + ); + } + + stopwatch.stop(); + print('Benchmark completed in ${stopwatch.elapsedMilliseconds} ms'); + }); +}