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
f4f23ecb
Unverified
Commit
f4f23ecb
authored
3 years ago
by
Hans Muller
Committed by
GitHub
3 years ago
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added SharedAppData to the widgets library (#93175)
parent
6bc33812
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
564 additions
and
11 deletions
+564
-11
shared_app_data.0.dart
...es/api/lib/widgets/shared_app_data/shared_app_data.0.dart
+75
-0
shared_app_data.1.dart
...es/api/lib/widgets/shared_app_data/shared_app_data.1.dart
+66
-0
app.dart
packages/flutter/lib/src/widgets/app.dart
+14
-11
shared_app_data.dart
packages/flutter/lib/src/widgets/shared_app_data.dart
+201
-0
widgets.dart
packages/flutter/lib/widgets.dart
+1
-0
debug_test.dart
packages/flutter/test/material/debug_test.dart
+2
-0
shared_app_data_test.dart
packages/flutter/test/widgets/shared_app_data_test.dart
+205
-0
No files found.
examples/api/lib/widgets/shared_app_data/shared_app_data.0.dart
0 → 100644
View file @
f4f23ecb
// 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 SharedAppData
import
'package:flutter/material.dart'
;
class
ShowSharedValue
extends
StatelessWidget
{
const
ShowSharedValue
({
Key
?
key
,
required
this
.
appDataKey
})
:
super
(
key:
key
);
final
String
appDataKey
;
@override
Widget
build
(
BuildContext
context
)
{
// The SharedAppData.getValue() call here causes this widget to depend
// on the value of the SharedAppData's 'foo' key. If it's changed, with
// SharedAppData.setValue(), then this widget will be rebuilt.
final
String
value
=
SharedAppData
.
getValue
<
String
,
String
>(
context
,
appDataKey
,
()
=>
'initial'
);
return
Text
(
'
$appDataKey
:
$value
'
);
}
}
// Demonstrates that changes to the SharedAppData _only_ cause the dependent widgets
// to be rebuilt. In this case that's the ShowSharedValue widget that's
// displaying the value of a key whose value has been updated.
class
Home
extends
StatefulWidget
{
const
Home
({
Key
?
key
})
:
super
(
key:
key
);
@override
State
<
Home
>
createState
()
=>
_HomeState
();
}
class
_HomeState
extends
State
<
Home
>
{
int
_fooVersion
=
0
;
int
_barVersion
=
0
;
@override
Widget
build
(
BuildContext
context
)
{
return
Scaffold
(
body:
Center
(
child:
Column
(
mainAxisSize:
MainAxisSize
.
min
,
children:
<
Widget
>[
const
ShowSharedValue
(
appDataKey:
'foo'
),
const
SizedBox
(
height:
16
),
const
ShowSharedValue
(
appDataKey:
'bar'
),
const
SizedBox
(
height:
16
),
ElevatedButton
(
child:
const
Text
(
'change foo'
),
onPressed:
()
{
_fooVersion
+=
1
;
// Changing the SharedAppData's value for 'foo' causes the widgets that
// depend on 'foo' to be rebuilt.
SharedAppData
.
setValue
<
String
,
String
?>(
context
,
'foo'
,
'FOO
$_fooVersion
'
);
// note: no setState()
},
),
const
SizedBox
(
height:
16
),
ElevatedButton
(
child:
const
Text
(
'change bar'
),
onPressed:
()
{
_barVersion
+=
1
;
SharedAppData
.
setValue
<
String
,
String
?>(
context
,
'bar'
,
'BAR
$_barVersion
'
);
// note: no setState()
},
),
],
),
),
);
}
}
void
main
(
)
{
runApp
(
const
MaterialApp
(
home:
Home
()));
}
This diff is collapsed.
Click to expand it.
examples/api/lib/widgets/shared_app_data/shared_app_data.1.dart
0 → 100644
View file @
f4f23ecb
// 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 SharedAppData
import
'package:flutter/foundation.dart'
;
import
'package:flutter/material.dart'
;
// A single lazily constructed object that's shared with the entire
// application via `SharedObject.of(context)`. The value of the object
// can be changed with `SharedObject.reset(context)`. Resetting the value
// will cause all of the widgets that depend on it to be rebuilt.
class
SharedObject
{
SharedObject
.
_
();
static
final
Object
_sharedObjectKey
=
Object
();
@override
String
toString
()
=>
describeIdentity
(
this
);
static
void
reset
(
BuildContext
context
)
{
// Calling SharedAppData.setValue() causes dependent widgets to be rebuilt.
SharedAppData
.
setValue
<
Object
,
SharedObject
>(
context
,
_sharedObjectKey
,
SharedObject
.
_
());
}
static
SharedObject
of
(
BuildContext
context
)
{
// If a value for _sharedObjectKey has never been set then the third
// callback parameter is used to generate an initial value.
return
SharedAppData
.
getValue
<
Object
,
SharedObject
>(
context
,
_sharedObjectKey
,
()
=>
SharedObject
.
_
());
}
}
// An example of a widget which depends on the SharedObject's value,
// which might be provided - along with SharedObject - in a Dart package.
class
CustomWidget
extends
StatelessWidget
{
const
CustomWidget
({
Key
?
key
})
:
super
(
key:
key
);
@override
Widget
build
(
BuildContext
context
)
{
// Will be rebuilt if the shared object's value is changed.
return
ElevatedButton
(
child:
Text
(
'Replace
${SharedObject.of(context)}
'
),
onPressed:
()
{
SharedObject
.
reset
(
context
);
},
);
}
}
class
Home
extends
StatelessWidget
{
const
Home
({
Key
?
key
})
:
super
(
key:
key
);
@override
Widget
build
(
BuildContext
context
)
{
return
const
Scaffold
(
body:
Center
(
child:
CustomWidget
()
),
);
}
}
void
main
(
)
{
runApp
(
const
MaterialApp
(
home:
Home
()));
}
This diff is collapsed.
Click to expand it.
packages/flutter/lib/src/widgets/app.dart
View file @
f4f23ecb
...
...
@@ -24,6 +24,7 @@ import 'restoration.dart';
import
'router.dart'
;
import
'scrollable.dart'
;
import
'semantics_debugger.dart'
;
import
'shared_app_data.dart'
;
import
'shortcuts.dart'
;
import
'text.dart'
;
import
'title.dart'
;
...
...
@@ -1664,17 +1665,19 @@ class _WidgetsAppState extends State<WidgetsApp> with WidgetsBindingObserver {
return
RootRestorationScope
(
restorationId:
widget
.
restorationScopeId
,
child:
Shortcuts
(
debugLabel:
'<Default WidgetsApp Shortcuts>'
,
shortcuts:
widget
.
shortcuts
??
WidgetsApp
.
defaultShortcuts
,
// DefaultTextEditingShortcuts is nested inside Shortcuts so that it can
// fall through to the defaultShortcuts.
child:
DefaultTextEditingShortcuts
(
child:
Actions
(
actions:
widget
.
actions
??
WidgetsApp
.
defaultActions
,
child:
FocusTraversalGroup
(
policy:
ReadingOrderTraversalPolicy
(),
child:
child
,
child:
SharedAppData
(
child:
Shortcuts
(
debugLabel:
'<Default WidgetsApp Shortcuts>'
,
shortcuts:
widget
.
shortcuts
??
WidgetsApp
.
defaultShortcuts
,
// DefaultTextEditingShortcuts is nested inside Shortcuts so that it can
// fall through to the defaultShortcuts.
child:
DefaultTextEditingShortcuts
(
child:
Actions
(
actions:
widget
.
actions
??
WidgetsApp
.
defaultActions
,
child:
FocusTraversalGroup
(
policy:
ReadingOrderTraversalPolicy
(),
child:
child
,
),
),
),
),
...
...
This diff is collapsed.
Click to expand it.
packages/flutter/lib/src/widgets/shared_app_data.dart
0 → 100644
View file @
f4f23ecb
// 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/foundation.dart'
;
import
'framework.dart'
;
import
'inherited_model.dart'
;
/// The type of the [SharedAppData.getValue] `init` parameter.
///
/// This callback is used to lazily create the initial value for
/// a [SharedAppData] keyword.
typedef
SharedAppDataInitCallback
<
T
>
=
T
Function
();
/// Enables sharing key/value data with its `child` and all of the
/// child's descendants.
///
/// - `SharedAppData.getValue(context, key, initCallback)` creates a dependency
/// on the key and returns the value for the key from the shared data table.
/// If no value exists for key then the initCallback is used to create
/// the initial value.
///
/// - `SharedAppData.setValue(context, key, value)` changes the value of an entry
/// in the shared data table and forces widgets that depend on that entry
/// to be rebuilt.
///
/// A widget whose build method uses SharedAppData.getValue(context,
/// keyword, initCallback) creates a dependency on the SharedAppData. When
/// the value of keyword changes with SharedAppData.setValue(), the widget
/// will be rebuilt. The values managed by the SharedAppData are expected
/// to be immutable: intrinsic changes to values will not cause
/// dependent widgets to be rebuilt.
///
/// An instance of this widget is created automatically by [WidgetsApp].
///
/// There are many ways to share data with a widget subtree. This
/// class is based on [InheritedModel], which is an [InheritedWidget].
/// It's intended to be used by packages that need to share a modest
/// number of values among their own components.
///
/// SharedAppData is not intended to be a substitute for Provider or any of
/// the other general purpose application state systems. SharedAppData is
/// for situations where a package's custom widgets need to share one
/// or a handful of immutable data objects that can be lazily
/// initialized. It exists so that packages like that can deliver
/// custom widgets without requiring the developer to add a
/// package-specific umbrella widget to their application.
///
/// A good way to create an SharedAppData key that avoids potential
/// collisions with other packages is to use a static `Object()` value.
/// The `SharedObject` example below does this.
///
/// {@tool dartpad}
/// The following sample demonstrates using the automatically created
/// `SharedAppData`. Button presses cause changes to the values for keys
/// 'foo', and 'bar', and those changes only cause the widgets that
/// depend on those keys to be rebuilt.
///
/// ** See code in examples/api/lib/widgets/shared_app_data/shared_app_data.0.dart **
/// {@end-tool}
///
/// {@tool dartpad}
/// The following sample demonstrates how a single lazily computed
/// value could be shared within an app. A Flutter package that
/// provided custom widgets might use this approach to share a (possibly
/// private) value with instances of those widgets.
///
/// ** See code in examples/api/lib/widgets/shared_app_data/shared_app_data.1.dart **
/// {@end-tool}
class
SharedAppData
extends
StatefulWidget
{
/// Creates a widget based on [InheritedModel] that supports build
/// dependencies qualified by keywords. Descendant widgets create
/// such dependencies with [SharedAppData.getValue] and they trigger
/// rebuilds with [SharedAppData.setValue].
///
/// This widget is automatically created by the [WidgetsApp].
const
SharedAppData
({
Key
?
key
,
required
this
.
child
})
:
super
(
key:
key
);
/// The widget below this widget in the tree.
///
/// {@macro flutter.widgets.ProxyWidget.child}
final
Widget
child
;
@override
State
<
StatefulWidget
>
createState
()
=>
_SharedAppDataState
();
/// Returns the app model's value for `key` and ensures that each
/// time the value of `key` is changed with [SharedAppData.setValue], the
/// specified context will be rebuilt.
///
/// If no value for `key` exists then the `init` callback is used to
/// generate an initial value. The callback is expected to return
/// an immutable value because intrinsic changes to the value will
/// not cause dependent widgets to be rebuilt.
///
/// A widget that depends on the app model's value for `key` should use
/// this method in their `build` methods to ensure that they are rebuilt
/// if the value changes.
///
/// The type parameter `K` is the type of the keyword and `V`
/// is the type of the value.
static
V
getValue
<
K
extends
Object
,
V
>(
BuildContext
context
,
K
key
,
SharedAppDataInitCallback
<
V
>
init
)
{
final
_SharedAppModel
?
model
=
InheritedModel
.
inheritFrom
<
_SharedAppModel
>(
context
,
aspect:
key
);
assert
(
_debugHasSharedAppData
(
model
,
context
,
'getValue'
));
return
model
!.
sharedAppDataState
.
getValue
<
K
,
V
>(
key
,
init
);
}
/// Changes the app model's `value` for `key` and rebuilds any widgets
/// that have created a dependency on `key` with [SharedAppData.getValue].
///
/// If `value` is `==` to the current value of `key` then nothing
/// is rebuilt.
///
/// The `value` is expected to be immutable because intrinsic
/// changes to the value will not cause dependent widgets to be
/// rebuilt.
///
/// Unlike [SharedAppData.getValue], this method does _not_ create a dependency
/// between `context` and `key`.
///
/// The type parameter `K` is the type of the value's keyword and `V`
/// is the type of the value.
static
void
setValue
<
K
extends
Object
,
V
>(
BuildContext
context
,
K
key
,
V
value
)
{
final
_SharedAppModel
?
model
=
context
.
getElementForInheritedWidgetOfExactType
<
_SharedAppModel
>()?.
widget
as
_SharedAppModel
?;
assert
(
_debugHasSharedAppData
(
model
,
context
,
'setValue'
));
model
!.
sharedAppDataState
.
setValue
<
K
,
V
>(
key
,
value
);
}
static
bool
_debugHasSharedAppData
(
_SharedAppModel
?
model
,
BuildContext
context
,
String
methodName
)
{
assert
(()
{
if
(
model
==
null
)
{
throw
FlutterError
.
fromParts
(
<
DiagnosticsNode
>[
ErrorSummary
(
'No SharedAppData widget found.'
),
ErrorDescription
(
'SharedAppData.
$methodName
requires an SharedAppData widget ancestor.
\n
'
),
context
.
describeWidget
(
'The specific widget that could not find an SharedAppData ancestor was'
),
context
.
describeOwnershipChain
(
'The ownership chain for the affected widget is'
),
ErrorHint
(
'Typically, the SharedAppData widget is introduced by the MaterialApp '
'or WidgetsApp widget at the top of your application widget tree. It '
'provides a key/value map of data that is shared with the entire '
'application.'
,
),
],
);
}
return
true
;
}());
return
true
;
}
}
class
_SharedAppDataState
extends
State
<
SharedAppData
>
{
late
Map
<
Object
,
Object
?>
data
=
<
Object
,
Object
?>{};
@override
Widget
build
(
BuildContext
context
)
{
return
_SharedAppModel
(
sharedAppDataState:
this
,
child:
widget
.
child
);
}
V
getValue
<
K
extends
Object
,
V
>(
K
key
,
SharedAppDataInitCallback
<
V
>
init
)
{
data
[
key
]
??=
init
();
return
data
[
key
]
as
V
;
}
void
setValue
<
K
extends
Object
,
V
>(
K
key
,
V
value
)
{
if
(
data
[
key
]
!=
value
)
{
setState
(()
{
data
=
Map
<
Object
,
Object
?>.
from
(
data
);
data
[
key
]
=
value
;
});
}
}
}
class
_SharedAppModel
extends
InheritedModel
<
Object
>
{
_SharedAppModel
({
Key
?
key
,
required
this
.
sharedAppDataState
,
required
Widget
child
})
:
data
=
sharedAppDataState
.
data
,
super
(
key:
key
,
child:
child
);
final
_SharedAppDataState
sharedAppDataState
;
final
Map
<
Object
,
Object
?>
data
;
@override
bool
updateShouldNotify
(
_SharedAppModel
old
)
{
return
data
!=
old
.
data
;
}
@override
bool
updateShouldNotifyDependent
(
_SharedAppModel
old
,
Set
<
Object
>
keys
)
{
for
(
final
Object
key
in
keys
)
{
if
(
data
[
key
]
!=
old
.
data
[
key
])
{
return
true
;
}
}
return
false
;
}
}
This diff is collapsed.
Click to expand it.
packages/flutter/lib/widgets.dart
View file @
f4f23ecb
...
...
@@ -107,6 +107,7 @@ export 'src/widgets/scroll_view.dart';
export
'src/widgets/scrollable.dart'
;
export
'src/widgets/scrollbar.dart'
;
export
'src/widgets/semantics_debugger.dart'
;
export
'src/widgets/shared_app_data.dart'
;
export
'src/widgets/shortcuts.dart'
;
export
'src/widgets/single_child_scroll_view.dart'
;
export
'src/widgets/size_changed_layout_notifier.dart'
;
...
...
This diff is collapsed.
Click to expand it.
packages/flutter/test/material/debug_test.dart
View file @
f4f23ecb
...
...
@@ -200,6 +200,8 @@ void main() {
' _FocusMarker
\n
'
' Focus
\n
'
' Shortcuts
\n
'
' _SharedAppModel
\n
'
' SharedAppData
\n
'
' UnmanagedRestorationScope
\n
'
' RestorationScope
\n
'
' UnmanagedRestorationScope
\n
'
...
...
This diff is collapsed.
Click to expand it.
packages/flutter/test/widgets/shared_app_data_test.dart
0 → 100644
View file @
f4f23ecb
// 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/widgets.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
void
main
(
)
{
testWidgets
(
'SharedAppData basics'
,
(
WidgetTester
tester
)
async
{
int
columnBuildCount
=
0
;
int
child1BuildCount
=
0
;
int
child2BuildCount
=
0
;
late
void
Function
(
BuildContext
context
)
setSharedAppDataValue
;
await
tester
.
pumpWidget
(
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
SharedAppData
(
child:
Builder
(
builder:
(
BuildContext
context
)
{
columnBuildCount
+=
1
;
return
GestureDetector
(
behavior:
HitTestBehavior
.
opaque
,
onTap:
()
{
setSharedAppDataValue
.
call
(
context
);
},
child:
Column
(
children:
<
Widget
>[
Builder
(
builder:
(
BuildContext
context
)
{
child1BuildCount
+=
1
;
return
Text
(
SharedAppData
.
getValue
<
String
,
String
>(
context
,
'child1Text'
,
()
=>
'null'
));
},
),
Builder
(
builder:
(
BuildContext
context
)
{
child2BuildCount
+=
1
;
return
Text
(
SharedAppData
.
getValue
<
String
,
String
>(
context
,
'child2Text'
,
()
=>
'null'
));
}
),
],
),
);
},
),
),
),
);
expect
(
columnBuildCount
,
1
);
expect
(
child1BuildCount
,
1
);
expect
(
child2BuildCount
,
1
);
expect
(
find
.
text
(
'null'
).
evaluate
().
length
,
2
);
// SharedAppData.setValue<String, String>(context, 'child1Text', 'child1')
// causes the first Text widget to be rebuilt with its text to be
// set to 'child1'. Nothing else is rebuilt.
setSharedAppDataValue
=
(
BuildContext
context
)
{
SharedAppData
.
setValue
<
String
,
String
>(
context
,
'child1Text'
,
'child1'
);
};
await
tester
.
tap
(
find
.
byType
(
GestureDetector
));
await
tester
.
pump
();
expect
(
columnBuildCount
,
1
);
expect
(
child1BuildCount
,
2
);
expect
(
child2BuildCount
,
1
);
expect
(
find
.
text
(
'child1'
),
findsOneWidget
);
expect
(
find
.
text
(
'null'
),
findsOneWidget
);
// SharedAppData.setValue<String, String>(context, 'child2Text', 'child1')
// causes the second Text widget to be rebuilt with its text to be
// set to 'child2'. Nothing else is rebuilt.
setSharedAppDataValue
=
(
BuildContext
context
)
{
SharedAppData
.
setValue
<
String
,
String
>(
context
,
'child2Text'
,
'child2'
);
};
await
tester
.
tap
(
find
.
byType
(
GestureDetector
));
await
tester
.
pump
();
expect
(
columnBuildCount
,
1
);
expect
(
child1BuildCount
,
2
);
expect
(
child2BuildCount
,
2
);
expect
(
find
.
text
(
'child1'
),
findsOneWidget
);
expect
(
find
.
text
(
'child2'
),
findsOneWidget
);
// Resetting a key's value to the same value does not
// cause any widgets to be rebuilt.
setSharedAppDataValue
=
(
BuildContext
context
)
{
SharedAppData
.
setValue
<
String
,
String
>(
context
,
'child1Text'
,
'child1'
);
SharedAppData
.
setValue
<
String
,
String
>(
context
,
'child2Text'
,
'child2'
);
};
await
tester
.
tap
(
find
.
byType
(
GestureDetector
));
await
tester
.
pump
();
expect
(
columnBuildCount
,
1
);
expect
(
child1BuildCount
,
2
);
expect
(
child2BuildCount
,
2
);
// More of the same, resetting the values to null..
setSharedAppDataValue
=
(
BuildContext
context
)
{
SharedAppData
.
setValue
<
String
,
String
>(
context
,
'child1Text'
,
'null'
);
};
await
tester
.
tap
(
find
.
byType
(
GestureDetector
));
await
tester
.
pump
();
expect
(
columnBuildCount
,
1
);
expect
(
child1BuildCount
,
3
);
expect
(
child2BuildCount
,
2
);
expect
(
find
.
text
(
'null'
),
findsOneWidget
);
expect
(
find
.
text
(
'child2'
),
findsOneWidget
);
setSharedAppDataValue
=
(
BuildContext
context
)
{
SharedAppData
.
setValue
<
String
,
String
>(
context
,
'child2Text'
,
'null'
);
};
await
tester
.
tap
(
find
.
byType
(
GestureDetector
));
await
tester
.
pump
();
expect
(
columnBuildCount
,
1
);
expect
(
child1BuildCount
,
3
);
expect
(
child2BuildCount
,
3
);
expect
(
find
.
text
(
'null'
).
evaluate
().
length
,
2
);
});
testWidgets
(
'WidgetsApp SharedAppData '
,
(
WidgetTester
tester
)
async
{
int
parentBuildCount
=
0
;
int
childBuildCount
=
0
;
await
tester
.
pumpWidget
(
WidgetsApp
(
color:
const
Color
(
0xff00ff00
),
builder:
(
BuildContext
context
,
Widget
?
child
)
{
parentBuildCount
+=
1
;
return
GestureDetector
(
behavior:
HitTestBehavior
.
opaque
,
onTap:
()
{
SharedAppData
.
setValue
<
String
,
String
>(
context
,
'childText'
,
'child'
);
},
child:
Center
(
child:
Builder
(
builder:
(
BuildContext
context
)
{
childBuildCount
+=
1
;
return
Text
(
SharedAppData
.
getValue
<
String
,
String
>(
context
,
'childText'
,
()
=>
'null'
));
},
),
),
);
},
),
);
expect
(
find
.
text
(
'null'
),
findsOneWidget
);
expect
(
parentBuildCount
,
1
);
expect
(
childBuildCount
,
1
);
await
tester
.
tap
(
find
.
byType
(
GestureDetector
));
await
tester
.
pump
();
expect
(
parentBuildCount
,
1
);
expect
(
childBuildCount
,
2
);
expect
(
find
.
text
(
'child'
),
findsOneWidget
);
});
testWidgets
(
'WidgetsApp SharedAppData Shadowing'
,
(
WidgetTester
tester
)
async
{
int
innerTapCount
=
0
;
int
outerTapCount
=
0
;
await
tester
.
pumpWidget
(
WidgetsApp
(
color:
const
Color
(
0xff00ff00
),
builder:
(
BuildContext
context
,
Widget
?
child
)
{
return
GestureDetector
(
behavior:
HitTestBehavior
.
opaque
,
onTap:
()
{
outerTapCount
+=
1
;
SharedAppData
.
setValue
<
String
,
String
>(
context
,
'childText'
,
'child'
);
},
child:
Center
(
child:
SharedAppData
(
child:
Builder
(
builder:
(
BuildContext
context
)
{
return
GestureDetector
(
onTap:
()
{
innerTapCount
+=
1
;
SharedAppData
.
setValue
<
String
,
String
>(
context
,
'childText'
,
'child'
);
},
child:
Text
(
SharedAppData
.
getValue
<
String
,
String
>(
context
,
'childText'
,
()
=>
'null'
)),
);
},
),
),
),
);
},
),
);
expect
(
find
.
text
(
'null'
),
findsOneWidget
);
await
tester
.
tapAt
(
const
Offset
(
10
,
10
));
await
tester
.
pump
();
expect
(
outerTapCount
,
1
);
expect
(
innerTapCount
,
0
);
expect
(
find
.
text
(
'null'
),
findsOneWidget
);
await
tester
.
tap
(
find
.
text
(
'null'
));
await
tester
.
pump
();
expect
(
outerTapCount
,
1
);
expect
(
innerTapCount
,
1
);
expect
(
find
.
text
(
'child'
),
findsOneWidget
);
});
}
This diff is collapsed.
Click to expand it.
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