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
884129d1
Unverified
Commit
884129d1
authored
Apr 14, 2021
by
Shi-Hao Hong
Committed by
GitHub
Apr 14, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Autocomplete and RawAutocomplete initialValue parameter (#80257)
parent
a4411b55
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
163 additions
and
4 deletions
+163
-4
autocomplete.dart
packages/flutter/lib/src/material/autocomplete.dart
+5
-0
autocomplete.dart
packages/flutter/lib/src/widgets/autocomplete.dart
+16
-1
autocomplete_test.dart
packages/flutter/test/material/autocomplete_test.dart
+47
-0
autocomplete_test.dart
packages/flutter/test/widgets/autocomplete_test.dart
+95
-3
No files found.
packages/flutter/lib/src/material/autocomplete.dart
View file @
884129d1
...
...
@@ -167,6 +167,7 @@ class Autocomplete<T extends Object> extends StatelessWidget {
this
.
fieldViewBuilder
=
_defaultFieldViewBuilder
,
this
.
onSelected
,
this
.
optionsViewBuilder
,
this
.
initialValue
,
})
:
assert
(
displayStringForOption
!=
null
),
assert
(
optionsBuilder
!=
null
),
super
(
key:
key
);
...
...
@@ -192,6 +193,9 @@ class Autocomplete<T extends Object> extends StatelessWidget {
/// default.
final
AutocompleteOptionsViewBuilder
<
T
>?
optionsViewBuilder
;
/// {@macro flutter.widgets.RawAutocomplete.initialValue}
final
TextEditingValue
?
initialValue
;
static
Widget
_defaultFieldViewBuilder
(
BuildContext
context
,
TextEditingController
textEditingController
,
FocusNode
focusNode
,
VoidCallback
onFieldSubmitted
)
{
return
_AutocompleteField
(
focusNode:
focusNode
,
...
...
@@ -205,6 +209,7 @@ class Autocomplete<T extends Object> extends StatelessWidget {
return
RawAutocomplete
<
T
>(
displayStringForOption:
displayStringForOption
,
fieldViewBuilder:
fieldViewBuilder
,
initialValue:
initialValue
,
optionsBuilder:
optionsBuilder
,
optionsViewBuilder:
optionsViewBuilder
??
(
BuildContext
context
,
AutocompleteOnSelected
<
T
>
onSelected
,
Iterable
<
T
>
options
)
{
return
_AutocompleteOptions
<
T
>(
...
...
packages/flutter/lib/src/widgets/autocomplete.dart
View file @
884129d1
...
...
@@ -493,6 +493,7 @@ class RawAutocomplete<T extends Object> extends StatefulWidget {
this
.
focusNode
,
this
.
onSelected
,
this
.
textEditingController
,
this
.
initialValue
,
})
:
assert
(
displayStringForOption
!=
null
),
assert
(
fieldViewBuilder
!=
null
...
...
@@ -502,6 +503,10 @@ class RawAutocomplete<T extends Object> extends StatefulWidget {
assert
(
optionsBuilder
!=
null
),
assert
(
optionsViewBuilder
!=
null
),
assert
((
focusNode
==
null
)
==
(
textEditingController
==
null
)),
assert
(
!(
textEditingController
!=
null
&&
initialValue
!=
null
),
'textEditingController and initialValue cannot be simultaneously defined.'
),
super
(
key:
key
);
/// {@template flutter.widgets.RawAutocomplete.fieldViewBuilder}
...
...
@@ -661,6 +666,16 @@ class RawAutocomplete<T extends Object> extends StatefulWidget {
/// If this parameter is not null, then [focusNode] must also be not null.
final
TextEditingController
?
textEditingController
;
/// {@template flutter.widgets.RawAutocomplete.initialValue}
/// The initial value to use for the text field.
/// {@endtemplate}
///
/// Setting the initial value does not notify [textEditingController]'s
/// listeners, and thus will not cause the options UI to appear.
///
/// This parameter is ignored if [textEditingController] is defined.
final
TextEditingValue
?
initialValue
;
/// Calls [AutocompleteFieldViewBuilder]'s onFieldSubmitted callback for the
/// RawAutocomplete widget indicated by the given [GlobalKey].
///
...
...
@@ -811,7 +826,7 @@ class _RawAutocompleteState<T extends Object> extends State<RawAutocomplete<T>>
@override
void
initState
()
{
super
.
initState
();
_textEditingController
=
widget
.
textEditingController
??
TextEditingController
(
);
_textEditingController
=
widget
.
textEditingController
??
TextEditingController
.
fromValue
(
widget
.
initialValue
);
_textEditingController
.
addListener
(
_onChangedField
);
_focusNode
=
widget
.
focusNode
??
FocusNode
();
_focusNode
.
addListener
(
_onChangedFocus
);
...
...
packages/flutter/test/material/autocomplete_test.dart
View file @
884129d1
...
...
@@ -253,4 +253,51 @@ void main() {
await
tester
.
pump
();
expect
(
find
.
byKey
(
optionsKey
),
findsOneWidget
);
});
testWidgets
(
'initialValue sets initial text field value'
,
(
WidgetTester
tester
)
async
{
late
String
lastSelection
;
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Scaffold
(
body:
Autocomplete
<
String
>(
initialValue:
const
TextEditingValue
(
text:
'lem'
),
onSelected:
(
String
selection
)
{
lastSelection
=
selection
;
},
optionsBuilder:
(
TextEditingValue
textEditingValue
)
{
return
kOptions
.
where
((
String
option
)
{
return
option
.
contains
(
textEditingValue
.
text
.
toLowerCase
());
});
},
),
),
),
);
// The field is always rendered, but the options are not unless needed.
expect
(
find
.
byType
(
TextFormField
),
findsOneWidget
);
expect
(
find
.
byType
(
ListView
),
findsNothing
);
expect
(
tester
.
widget
<
TextFormField
>(
find
.
byType
(
TextFormField
)).
controller
!.
text
,
'lem'
,
);
// Focus the empty field. All the options are displayed.
await
tester
.
tap
(
find
.
byType
(
TextFormField
));
await
tester
.
pump
();
expect
(
find
.
byType
(
ListView
),
findsOneWidget
);
final
ListView
list
=
find
.
byType
(
ListView
).
evaluate
().
first
.
widget
as
ListView
;
// Displays just one option ('lemur').
expect
(
list
.
semanticChildCount
,
1
);
// Select a option. The options hide and the field updates to show the
// selection.
await
tester
.
tap
(
find
.
byType
(
InkWell
).
first
);
await
tester
.
pump
();
expect
(
find
.
byType
(
TextFormField
),
findsOneWidget
);
expect
(
find
.
byType
(
ListView
),
findsNothing
);
final
TextFormField
field
=
find
.
byType
(
TextFormField
).
evaluate
().
first
.
widget
as
TextFormField
;
expect
(
field
.
controller
!.
text
,
'lemur'
);
expect
(
lastSelection
,
'lemur'
);
});
}
packages/flutter/test/widgets/autocomplete_test.dart
View file @
884129d1
...
...
@@ -102,7 +102,7 @@ void main() {
expect
(
lastOptions
.
elementAt
(
0
),
'chameleon'
);
expect
(
lastOptions
.
elementAt
(
1
),
'elephant'
);
// Select a option. The options hide and the field updates to show the
// Select a
n
option. The options hide and the field updates to show the
// selection.
final
String
selection
=
lastOptions
.
elementAt
(
1
);
lastOnSelected
(
selection
);
...
...
@@ -184,7 +184,7 @@ void main() {
expect
(
lastOptions
.
elementAt
(
0
),
kOptionsUsers
[
0
]);
expect
(
lastOptions
.
elementAt
(
1
),
kOptionsUsers
[
1
]);
// Select a option. The options hide and onSelected is called.
// Select a
n
option. The options hide and onSelected is called.
final
User
selection
=
lastOptions
.
elementAt
(
1
);
lastOnSelected
(
selection
);
await
tester
.
pump
();
...
...
@@ -266,7 +266,7 @@ void main() {
expect
(
lastOptions
.
elementAt
(
0
),
kOptionsUsers
[
0
]);
expect
(
lastOptions
.
elementAt
(
1
),
kOptionsUsers
[
1
]);
// Select a option. The options hide and onSelected is called. The field
// Select a
n
option. The options hide and onSelected is called. The field
// has its text set to the selection's display string.
final
User
selection
=
lastOptions
.
elementAt
(
1
);
lastOnSelected
(
selection
);
...
...
@@ -553,4 +553,96 @@ void main() {
expect
(
find
.
byKey
(
optionsKey
),
findsNothing
);
expect
(
textEditingController
.
text
,
lastOptions
.
elementAt
(
0
));
});
testWidgets
(
'initialValue sets initial text field value'
,
(
WidgetTester
tester
)
async
{
final
GlobalKey
fieldKey
=
GlobalKey
();
final
GlobalKey
optionsKey
=
GlobalKey
();
late
Iterable
<
String
>
lastOptions
;
late
AutocompleteOnSelected
<
String
>
lastOnSelected
;
late
FocusNode
focusNode
;
late
TextEditingController
textEditingController
;
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Scaffold
(
body:
RawAutocomplete
<
String
>(
// Should initialize text field with 'lem'.
initialValue:
const
TextEditingValue
(
text:
'lem'
),
optionsBuilder:
(
TextEditingValue
textEditingValue
)
{
return
kOptions
.
where
((
String
option
)
{
return
option
.
contains
(
textEditingValue
.
text
.
toLowerCase
());
});
},
fieldViewBuilder:
(
BuildContext
context
,
TextEditingController
fieldTextEditingController
,
FocusNode
fieldFocusNode
,
VoidCallback
onFieldSubmitted
)
{
focusNode
=
fieldFocusNode
;
textEditingController
=
fieldTextEditingController
;
return
TextField
(
key:
fieldKey
,
focusNode:
focusNode
,
controller:
textEditingController
,
);
},
optionsViewBuilder:
(
BuildContext
context
,
AutocompleteOnSelected
<
String
>
onSelected
,
Iterable
<
String
>
options
)
{
lastOptions
=
options
;
lastOnSelected
=
onSelected
;
return
Container
(
key:
optionsKey
);
},
),
),
),
);
// The field is always rendered, but the options are not unless needed.
expect
(
find
.
byKey
(
fieldKey
),
findsOneWidget
);
expect
(
find
.
byKey
(
optionsKey
),
findsNothing
);
// The text editing controller value starts off with initialized value.
expect
(
textEditingController
.
text
,
'lem'
);
// Focus the empty field. All the options are displayed.
focusNode
.
requestFocus
();
await
tester
.
pump
();
expect
(
find
.
byKey
(
optionsKey
),
findsOneWidget
);
expect
(
lastOptions
.
elementAt
(
0
),
'lemur'
);
// Select an option. The options hide and the field updates to show the
// selection.
final
String
selection
=
lastOptions
.
elementAt
(
0
);
lastOnSelected
(
selection
);
await
tester
.
pump
();
expect
(
find
.
byKey
(
fieldKey
),
findsOneWidget
);
expect
(
find
.
byKey
(
optionsKey
),
findsNothing
);
expect
(
textEditingController
.
text
,
selection
);
});
testWidgets
(
'initialValue cannot be defined if TextEditingController is defined'
,
(
WidgetTester
tester
)
async
{
final
FocusNode
focusNode
=
FocusNode
();
final
TextEditingController
textEditingController
=
TextEditingController
();
expect
(
()
{
RawAutocomplete
<
String
>(
focusNode:
focusNode
,
// Both [initialValue] and [textEditingController] cannot be
// simultaneously defined.
initialValue:
const
TextEditingValue
(
text:
'lemur'
),
textEditingController:
textEditingController
,
optionsBuilder:
(
TextEditingValue
textEditingValue
)
{
return
kOptions
.
where
((
String
option
)
{
return
option
.
contains
(
textEditingValue
.
text
.
toLowerCase
());
});
},
optionsViewBuilder:
(
BuildContext
context
,
AutocompleteOnSelected
<
String
>
onSelected
,
Iterable
<
String
>
options
)
{
return
Container
();
},
fieldViewBuilder:
(
BuildContext
context
,
TextEditingController
fieldTextEditingController
,
FocusNode
fieldFocusNode
,
VoidCallback
onFieldSubmitted
)
{
return
TextField
(
focusNode:
focusNode
,
controller:
textEditingController
,
);
},
);
},
throwsAssertionError
,
);
});
}
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