diff --git a/packages/flutter/lib/src/material/theme.dart b/packages/flutter/lib/src/material/theme.dart index c6c5bb8e88..c036033cba 100644 --- a/packages/flutter/lib/src/material/theme.dart +++ b/packages/flutter/lib/src/material/theme.dart @@ -155,7 +155,7 @@ class _InheritedTheme extends InheritedWidget { final Theme theme; @override - bool updateShouldNotify(_InheritedTheme old) => theme != old.theme; + bool updateShouldNotify(_InheritedTheme old) => theme.data != old.theme.data; } /// An interpolation between two [ThemeData]s. diff --git a/packages/flutter/test/material/theme_test.dart b/packages/flutter/test/material/theme_test.dart index bb2ae1b844..b934e6a405 100644 --- a/packages/flutter/test/material/theme_test.dart +++ b/packages/flutter/test/material/theme_test.dart @@ -265,4 +265,72 @@ void main() { expect(glyphText.text.style.color, Colors.orange); expect(glyphText.text.style.fontSize, 20.0); }); + + testWidgets( + 'Same ThemeData reapplied does not trigger descendents rebuilds', + (WidgetTester tester) async { + testBuildCalled = 0; + ThemeData themeData = new ThemeData(primaryColor: const Color(0xFF000000)); + + await tester.pumpWidget( + new Theme( + data: themeData, + child: const Test(), + ), + ); + expect(testBuildCalled, 1); + + // Pump the same widgets again. + await tester.pumpWidget( + new Theme( + data: themeData, + child: const Test(), + ), + ); + // No repeated build calls to the child since it's the same theme data. + expect(testBuildCalled, 1); + + // New instance of theme data but still the same content. + themeData = new ThemeData(primaryColor: const Color(0xFF000000)); + await tester.pumpWidget( + new Theme( + data: themeData, + child: const Test(), + ), + ); + // Still no repeated calls. + expect(testBuildCalled, 1); + + // Different now. + themeData = new ThemeData(primaryColor: const Color(0xFF222222)); + await tester.pumpWidget( + new Theme( + data: themeData, + child: const Test(), + ), + ); + // Should call build again. + expect(testBuildCalled, 2); + }, + ); +} + +int testBuildCalled; +class Test extends StatefulWidget { + const Test(); + + @override + _TestState createState() => new _TestState(); +} + +class _TestState extends State { + @override + Widget build(BuildContext context) { + testBuildCalled += 1; + return new Container( + decoration: new BoxDecoration( + color: Theme.of(context).primaryColor, + ), + ); + } }