Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
71a9ccbf
Unverified
Commit
71a9ccbf
authored
May 30, 2022
by
Taha Tesser
Committed by
GitHub
May 30, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
`InheritedModel`: Add a complete interactive example and update snippet for null safety (#104174)
parent
c2cc31b1
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
224 additions
and
12 deletions
+224
-12
inherited_model.0.dart
...es/api/lib/widgets/inherited_model/inherited_model.0.dart
+165
-0
inherited_model.0_test.dart
.../test/widgets/inherited_model/inherited_model.0_test.dart
+34
-0
inherited_model.dart
packages/flutter/lib/src/widgets/inherited_model.dart
+25
-12
No files found.
examples/api/lib/widgets/inherited_model/inherited_model.0.dart
0 → 100644
View file @
71a9ccbf
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flutter code sample for InheritedModel
import
'package:flutter/material.dart'
;
enum
LogoAspect
{
backgroundColor
,
large
}
void
main
(
)
=>
runApp
(
const
InheritedModelApp
());
class
InheritedModelApp
extends
StatelessWidget
{
const
InheritedModelApp
({
super
.
key
});
@override
Widget
build
(
BuildContext
context
)
{
return
const
MaterialApp
(
home:
InheritedModelExample
(),
);
}
}
class
LogoModel
extends
InheritedModel
<
LogoAspect
>
{
const
LogoModel
({
super
.
key
,
this
.
backgroundColor
,
this
.
large
,
required
super
.
child
,
});
final
Color
?
backgroundColor
;
final
bool
?
large
;
static
Color
?
backgroundColorOf
(
BuildContext
context
)
{
return
InheritedModel
.
inheritFrom
<
LogoModel
>(
context
,
aspect:
LogoAspect
.
backgroundColor
)?.
backgroundColor
;
}
static
bool
sizeOf
(
BuildContext
context
)
{
return
InheritedModel
.
inheritFrom
<
LogoModel
>(
context
,
aspect:
LogoAspect
.
large
)?.
large
??
false
;
}
@override
bool
updateShouldNotify
(
LogoModel
oldWidget
)
{
return
backgroundColor
!=
oldWidget
.
backgroundColor
||
large
!=
oldWidget
.
large
;
}
@override
bool
updateShouldNotifyDependent
(
LogoModel
oldWidget
,
Set
<
LogoAspect
>
dependencies
)
{
if
(
backgroundColor
!=
oldWidget
.
backgroundColor
&&
dependencies
.
contains
(
LogoAspect
.
backgroundColor
))
{
return
true
;
}
if
(
large
!=
oldWidget
.
large
&&
dependencies
.
contains
(
LogoAspect
.
large
))
{
return
true
;
}
return
false
;
}
}
class
InheritedModelExample
extends
StatefulWidget
{
const
InheritedModelExample
({
super
.
key
});
@override
State
<
InheritedModelExample
>
createState
()
=>
_InheritedModelExampleState
();
}
class
_InheritedModelExampleState
extends
State
<
InheritedModelExample
>
{
bool
large
=
false
;
Color
color
=
Colors
.
blue
;
@override
Widget
build
(
BuildContext
context
)
{
return
Scaffold
(
appBar:
AppBar
(
title:
const
Text
(
'InheritedModel Sample'
)),
body:
Column
(
mainAxisAlignment:
MainAxisAlignment
.
spaceEvenly
,
children:
<
Widget
>[
Center
(
child:
LogoModel
(
backgroundColor:
color
,
large:
large
,
child:
const
BackgroundWidget
(
child:
LogoWidget
(),
),
),
),
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceEvenly
,
children:
<
Widget
>[
ElevatedButton
(
onPressed:
()
{
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
const
SnackBar
(
content:
Text
(
'Rebuilt Background'
),
duration:
Duration
(
milliseconds:
500
),
),
);
setState
(()
{
if
(
color
==
Colors
.
blue
){
color
=
Colors
.
red
;
}
else
{
color
=
Colors
.
blue
;
}
});
},
child:
const
Text
(
'Update background'
),
),
ElevatedButton
(
onPressed:
()
{
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
const
SnackBar
(
content:
Text
(
'Rebuilt LogoWidget'
),
duration:
Duration
(
milliseconds:
500
),
),
);
setState
(()
{
large
=
!
large
;
});
},
child:
const
Text
(
'Resize Logo'
),
),
],
)
],
),
);
}
}
class
BackgroundWidget
extends
StatelessWidget
{
const
BackgroundWidget
({
super
.
key
,
required
this
.
child
});
final
Widget
child
;
@override
Widget
build
(
BuildContext
context
)
{
final
Color
color
=
LogoModel
.
backgroundColorOf
(
context
)!;
return
AnimatedContainer
(
padding:
const
EdgeInsets
.
all
(
12.0
),
color:
color
,
duration:
const
Duration
(
seconds:
2
),
curve:
Curves
.
fastOutSlowIn
,
child:
child
,
);
}
}
class
LogoWidget
extends
StatelessWidget
{
const
LogoWidget
({
super
.
key
});
@override
Widget
build
(
BuildContext
context
)
{
final
bool
largeLogo
=
LogoModel
.
sizeOf
(
context
);
return
AnimatedContainer
(
padding:
const
EdgeInsets
.
all
(
20.0
),
duration:
const
Duration
(
seconds:
2
),
curve:
Curves
.
fastLinearToSlowEaseIn
,
alignment:
Alignment
.
center
,
child:
FlutterLogo
(
size:
largeLogo
?
200.0
:
100.0
),
);
}
}
examples/api/test/widgets/inherited_model/inherited_model.0_test.dart
0 → 100644
View file @
71a9ccbf
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter/material.dart'
;
import
'package:flutter_api_samples/widgets/inherited_model/inherited_model.0.dart'
as
example
;
import
'package:flutter_test/flutter_test.dart'
;
void
main
(
)
{
testWidgets
(
'Rebuild widget using InheritedModel'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
const
example
.
InheritedModelApp
(),
);
BoxDecoration
?
decoration
=
tester
.
widget
<
AnimatedContainer
>(
find
.
byType
(
AnimatedContainer
).
first
,
).
decoration
as
BoxDecoration
?;
expect
(
decoration
!.
color
,
Colors
.
blue
);
await
tester
.
tap
(
find
.
text
(
'Update background'
));
await
tester
.
pumpAndSettle
();
decoration
=
tester
.
widget
<
AnimatedContainer
>(
find
.
byType
(
AnimatedContainer
).
first
,
).
decoration
as
BoxDecoration
?;
expect
(
decoration
!.
color
,
Colors
.
red
);
double
?
size
=
tester
.
widget
<
FlutterLogo
>(
find
.
byType
(
FlutterLogo
)).
size
;
expect
(
size
,
100.0
);
await
tester
.
tap
(
find
.
text
(
'Resize Logo'
));
await
tester
.
pumpAndSettle
();
size
=
tester
.
widget
<
FlutterLogo
>(
find
.
byType
(
FlutterLogo
)).
size
;
expect
(
size
,
200.0
);
});
}
packages/flutter/lib/src/widgets/inherited_model.dart
View file @
71a9ccbf
...
...
@@ -34,7 +34,7 @@ import 'framework.dart';
/// ```dart
/// class MyModel extends InheritedModel<String> {
/// // ...
/// static MyModel of(BuildContext context, String aspect) {
/// static MyModel
?
of(BuildContext context, String aspect) {
/// return InheritedModel.inheritFrom<MyModel>(context, aspect: aspect);
/// }
/// }
...
...
@@ -44,37 +44,42 @@ import 'framework.dart';
/// be rebuilt when the `foo` aspect of `MyModel` changes. If the aspect
/// is null, then the model supports all aspects.
///
/// {@tool snippet}
/// When the inherited model is rebuilt the [updateShouldNotify] and
/// [updateShouldNotifyDependent] methods are used to decide what
/// should be rebuilt. If [updateShouldNotify] returns true, then the
/// inherited model's [updateShouldNotifyDependent] method is tested for
/// each dependent and the set of aspect objects it depends on.
/// The [updateShouldNotifyDependent] method must compare the set of aspect
/// dependencies with the changes in the model itself.
///
/// For example:
/// dependencies with the changes in the model itself. For example:
///
/// ```dart
/// class ABModel extends InheritedModel<String> {
/// ABModel({ this.a, this.b, Widget child }) : super(child: child);
/// const ABModel({
/// super.key,
/// this.a,
/// this.b,
/// required super.child,
/// });
///
/// final int a;
/// final int b;
/// final int
?
a;
/// final int
?
b;
///
/// @override
/// bool updateShouldNotify(ABModel old) {
/// return a != old
.a || b != old
.b;
/// bool updateShouldNotify(ABModel old
Widget
) {
/// return a != old
Widget.a || b != oldWidget
.b;
/// }
///
/// @override
/// bool updateShouldNotifyDependent(ABModel old
, Set<String> aspect
s) {
/// return (a != old
.a && aspect
s.contains('a'))
///
|| (b != old.b && aspects.contains('b'))
/// bool updateShouldNotifyDependent(ABModel old
Widget, Set<String> dependencie
s) {
/// return (a != old
Widget.a && dependencie
s.contains('a'))
///
|| (b != oldWidget.b && dependencies.contains('b'));
/// }
///
/// // ...
/// }
/// ```
/// {@end-tool}
///
/// In the previous example the dependencies checked by
/// [updateShouldNotifyDependent] are just the aspect strings passed to
...
...
@@ -84,6 +89,14 @@ import 'framework.dart';
/// then changes in the model will cause the widget to be rebuilt
/// unconditionally.
///
/// {@tool dartpad}
/// This example shows how to implement [InheritedModel] to rebuild a
/// widget based on a qualified dependence. When tapped on the "Resize Logo" button
/// only the logo widget is rebuilt while the background widget remains unaffected.
///
/// ** See code in examples/api/lib/widgets/inherited_model/inherited_model.0.dart **
/// {@end-tool}
///
/// See also:
///
/// * [InheritedWidget], an inherited widget that only notifies dependents
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment