mirror of
https://github.com/flutter/flutter
synced 2024-08-24 18:36:03 +00:00
Add more documentation for TextEditingController default constructor (#143452)
## Description This PR adds more documentation for `TextEditingController(String text)` constructor and it adds one example. https://github.com/flutter/flutter/pull/96245 was a first improvement to the documentation. https://github.com/flutter/flutter/issues/79495 tried to hide the cursor when an invalid selection is set but it was reverted. https://github.com/flutter/flutter/pull/123777 mitigated the issue of having a default invalid selection: it takes care of setting a proper selection when a text field is focused and its controller selection is not initialized. I will try changing the initial selection in another PR, but It will probably break several existing tests. ## Related Issue Fixes https://github.com/flutter/flutter/issues/95978 ## Tests Adds 1 test for the new example.
This commit is contained in:
parent
c61dc2a586
commit
5c88fbf0b9
|
@ -0,0 +1,61 @@
|
|||
// 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';
|
||||
|
||||
/// Flutter code sample for [TextEditingController].
|
||||
|
||||
void main() {
|
||||
runApp(const TextEditingControllerExampleApp());
|
||||
}
|
||||
|
||||
class TextEditingControllerExampleApp extends StatelessWidget {
|
||||
const TextEditingControllerExampleApp({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const MaterialApp(
|
||||
home: TextEditingControllerExample(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class TextEditingControllerExample extends StatefulWidget {
|
||||
const TextEditingControllerExample({super.key});
|
||||
|
||||
@override
|
||||
State<TextEditingControllerExample> createState() => _TextEditingControllerExampleState();
|
||||
}
|
||||
|
||||
class _TextEditingControllerExampleState extends State<TextEditingControllerExample> {
|
||||
// Create a controller whose initial selection is empty (collapsed) and positioned
|
||||
// before the text (offset is 0).
|
||||
final TextEditingController _controller = TextEditingController.fromValue(
|
||||
const TextEditingValue(
|
||||
text: 'Flutter',
|
||||
selection: TextSelection.collapsed(offset: 0),
|
||||
),
|
||||
);
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Container(
|
||||
alignment: Alignment.center,
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: TextField(
|
||||
controller: _controller,
|
||||
autofocus: true,
|
||||
decoration: const InputDecoration(filled: true),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
// 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/editable_text/text_editing_controller.1.dart' as example;
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Initial selection is collasped at offset 0', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
const example.TextEditingControllerExampleApp(),
|
||||
);
|
||||
|
||||
final EditableText editableText = tester.widget(find.byType(EditableText));
|
||||
final TextEditingController controller = editableText.controller;
|
||||
|
||||
expect(controller.text, 'Flutter');
|
||||
expect(controller.selection, const TextSelection.collapsed(offset: 0));
|
||||
});
|
||||
}
|
|
@ -178,6 +178,7 @@ class _RenderCompositionCallback extends RenderProxyBox {
|
|||
///
|
||||
/// Remember to [dispose] of the [TextEditingController] when it is no longer
|
||||
/// needed. This will ensure we discard any resources used by the object.
|
||||
///
|
||||
/// {@tool dartpad}
|
||||
/// This example creates a [TextField] with a [TextEditingController] whose
|
||||
/// change listener forces the entered text to be lower case and keeps the
|
||||
|
@ -198,6 +199,24 @@ class TextEditingController extends ValueNotifier<TextEditingValue> {
|
|||
///
|
||||
/// This constructor treats a null [text] argument as if it were the empty
|
||||
/// string.
|
||||
///
|
||||
/// The initial selection is `TextSelection.collapsed(offset: -1)`.
|
||||
/// This indicates that there is no selection at all ([TextSelection.isValid]
|
||||
/// is false in this case). When a text field is built with a controller whose
|
||||
/// selection is not valid, the text field will update the selection when it
|
||||
/// is focused (the selection will be an empty selection positioned at the
|
||||
/// end of the text).
|
||||
//
|
||||
/// Consider using [TextEditingController.fromValue] to initialize both the
|
||||
/// text and the selection.
|
||||
///
|
||||
/// {@tool dartpad}
|
||||
/// This example creates a [TextField] with a [TextEditingController] whose
|
||||
/// initial selection is empty (collapsed) and positioned at the beginning
|
||||
/// of the text (offset is 0).
|
||||
///
|
||||
/// ** See code in examples/api/lib/widgets/editable_text/text_editing_controller.1.dart **
|
||||
/// {@end-tool}
|
||||
TextEditingController({ String? text })
|
||||
: super(text == null ? TextEditingValue.empty : TextEditingValue(text: text));
|
||||
|
||||
|
|
Loading…
Reference in a new issue