边框焦点设置高亮颜色
效果:
代码:
import 'package:flutter/material.dart';
class TextFieldDemo extends StatelessWidget {
const TextFieldDemo({super.key});
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('TextField Focus and Border Highlight Example'),
),
body: FocusAndBorderHighlight(),
),
);
}
}
class FocusAndBorderHighlight extends StatefulWidget {
const FocusAndBorderHighlight({super.key});
createState() => _FocusAndBorderHighlightState();
}
class _FocusAndBorderHighlightState extends State<FocusAndBorderHighlight> {
late FocusNode _focusNode;
void initState() {
super.initState();
_focusNode = FocusNode();
}
void dispose() {
_focusNode.dispose();
super.dispose();
}
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: TextField(
focusNode: _focusNode,
decoration: InputDecoration(
labelText: 'Enter text',
border: OutlineInputBorder(),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blue, width: 2.0),
),
),
onTap: () {
// 请求焦点
FocusScope.of(context).requestFocus(_focusNode);
},
),
);
}
}
简单的上效果:
简单的实现了一下:
代码如下:
import 'package:flutter/material.dart';
class MyTextEditingController extends StatefulWidget {
const MyTextEditingController({super.key});
createState() => _MyTextEditingControllerState();
}
class _MyTextEditingControllerState extends State<MyTextEditingController> {
final TextEditingController _controller = TextEditingController();
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
controller: _controller,
decoration: InputDecoration(hintText: '请输入'),
),
TextButton(
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('您输入的是:'),
content: Text(_controller.text),
actions: <Widget>[
TextButton(
style: TextButton.styleFrom(
textStyle: Theme.of(context).textTheme.labelLarge,
),
child: const Text('取消'),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
style: TextButton.styleFrom(
textStyle: Theme.of(context).textTheme.labelLarge,
),
child: const Text('确定'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
},
child: Text('完成'),
)
],
);
}
}
还是在布局构建那一章里《【Flutter&Dart】构建布局(1/100)》调用
导入可以用快捷键实现:macOS 里是 command+.;其他系统平台没有用过就不知道了
遇到一点点小坑
教程上对话框的示例代码是:
new RaisedButton(
onPressed: () {
showDialog(
context: context,
child: new AlertDialog(
title: new Text('What you typed'),
content: new Text(_controller.text),
),
);
},
child: new Text('DONE'),
),
但是RaisedButton这个没有了,用TextButton代替,不过也可以用其他的,本来也是简单实现;
主要是showDialog这个有点坑,大概率是教程比较早了,child 这个参数没有了;如下:
Future<T?> showDialog<T>({
required BuildContext context,
required WidgetBuilder builder,
bool barrierDismissible = true,
Color? barrierColor,
String? barrierLabel,
bool useSafeArea = true,
bool useRootNavigator = true,
RouteSettings? routeSettings,
Offset? anchorPoint,
TraversalEdgeBehavior? traversalEdgeBehavior,
}) {}
required WidgetBuilder builder;对于练习来说,完全不理解,于是硬头皮读一下注释:
/// Displays a Material dialog above the current contents of the app, with
/// Material entrance and exit animations, modal barrier color, and modal
/// barrier behavior (dialog is dismissible with a tap on the barrier).
///
/// This function takes a `builder` which typically builds a [Dialog] widget.
/// Content below the dialog is dimmed with a [ModalBarrier]. The widget
/// returned by the `builder` does not share a context with the location that
/// [showDialog] is originally called from. Use a [StatefulBuilder] or a
/// custom [StatefulWidget] if the dialog needs to update dynamically.
///
/// The `context` argument is used to look up the [Navigator] and [Theme] for
/// the dialog. It is only used when the method is called. Its corresponding
/// widget can be safely removed from the tree before the dialog is closed.
///
/// The `barrierDismissible` argument is used to indicate whether tapping on the
/// barrier will dismiss the dialog. It is `true` by default and can not be `null`.
///
/// The `barrierColor` argument is used to specify the color of the modal
/// barrier that darkens everything below the dialog. If `null` the `barrierColor`
/// field from `DialogThemeData` is used. If that is `null` the default color
/// `Colors.black54` is used.
///
/// The `useSafeArea` argument is used to indicate if the dialog should only
/// display in 'safe' areas of the screen not used by the operating system
/// (see [SafeArea] for more details). It is `true` by default, which means
/// the dialog will not overlap operating system areas. If it is set to `false`
/// the dialog will only be constrained by the screen size. It can not be `null`.
///
/// The `useRootNavigator` argument is used to determine whether to push the
/// dialog to the [Navigator] furthest from or nearest to the given `context`.
/// By default, `useRootNavigator` is `true` and the dialog route created by
/// this method is pushed to the root navigator. It can not be `null`.
///
/// The `routeSettings` argument is passed to [showGeneralDialog],
/// see [RouteSettings] for details.
///
/// If not null, the `traversalEdgeBehavior` argument specifies the transfer of
/// focus beyond the first and the last items of the dialog route. By default,
/// [TraversalEdgeBehavior.closedLoop] is used, because it's typical for dialogs
/// to allow users to cycle through dialog widgets without leaving the dialog.
///
/// {@macro flutter.widgets.RawDialogRoute}
///
/// If the application has multiple [Navigator] objects, it may be necessary to
/// call `Navigator.of(context, rootNavigator: true).pop(result)` to close the
/// dialog rather than just `Navigator.pop(context, result)`.
///
/// Returns a [Future] that resolves to the value (if any) that was passed to
/// [Navigator.pop] when the dialog was closed.
///
/// {@tool dartpad}
/// This sample demonstrates how to use [showDialog] to display a dialog box.
///
/// ** See code in examples/api/lib/material/dialog/show_dialog.0.dart **
/// {@end-tool}
///
/// {@tool dartpad}
/// This sample shows the creation of [showDialog], as described in:
/// https://m3.material.io/components/dialogs/overview
///
/// ** See code in examples/api/lib/material/dialog/show_dialog.1.dart **
/// {@end-tool}
///
/// ### State Restoration in Dialogs
///
/// Using this method will not enable state restoration for the dialog. In order
/// to enable state restoration for a dialog, use [Navigator.restorablePush]
/// or [Navigator.restorablePushNamed] with [DialogRoute].
///
/// For more information about state restoration, see [RestorationManager].
///
/// {@tool dartpad}
/// This sample demonstrates how to create a restorable Material dialog. This is
/// accomplished by enabling state restoration by specifying
/// [MaterialApp.restorationScopeId] and using [Navigator.restorablePush] to
/// push [DialogRoute] when the button is tapped.
///
/// {@macro flutter.widgets.RestorationManager}
///
/// ** See code in examples/api/lib/material/dialog/show_dialog.2.dart **
/// {@end-tool}
///
/// See also:
///
/// * [AlertDialog], for dialogs that have a row of buttons below a body.
/// * [SimpleDialog], which handles the scrolling of the contents and does
/// not show buttons below its body.
/// * [Dialog], on which [SimpleDialog] and [AlertDialog] are based.
/// * [showCupertinoDialog], which displays an iOS-style dialog.
/// * [showGeneralDialog], which allows for customization of the dialog popup.
/// * [DisplayFeatureSubScreen], which documents the specifics of how
/// [DisplayFeature]s can split the screen into sub-screens.
/// * <https://material.io/design/components/dialogs.html>
/// * <https://m3.material.io/components/dialogs>
好吧如果你真的也硬头皮看完了,敬佩你是个狠人,我看到examples/api/lib/material/dialog/show_dialog.0.dart这里就直接进去看示例代码了,代码如下:
// 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 [showDialog].
void main() => runApp(const ShowDialogExampleApp());
class ShowDialogExampleApp extends StatelessWidget {
const ShowDialogExampleApp({super.key});
Widget build(BuildContext context) {
return const MaterialApp(
home: DialogExample(),
);
}
}
class DialogExample extends StatelessWidget {
const DialogExample({super.key});
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('showDialog Sample')),
body: Center(
child: OutlinedButton(
onPressed: () => _dialogBuilder(context),
child: const Text('Open Dialog'),
),
),
);
}
Future<void> _dialogBuilder(BuildContext context) {
return showDialog<void>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Basic dialog title'),
content: const Text(
'A dialog is a type of modal window that\n'
'appears in front of app content to\n'
'provide critical information, or prompt\n'
'for a decision to be made.',
),
actions: <Widget>[
TextButton(
style: TextButton.styleFrom(
textStyle: Theme.of(context).textTheme.labelLarge,
),
child: const Text('Disable'),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
style: TextButton.styleFrom(
textStyle: Theme.of(context).textTheme.labelLarge,
),
child: const Text('Enable'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
好吧!代码好像多了一点点,截取其中需要的就行了
return showDialog<void>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Basic dialog title'),
content: const Text(
'A dialog is a type of modal window that\n'
'appears in front of app content to\n'
'provide critical information, or prompt\n'
'for a decision to be made.',
),
actions: <Widget>[
TextButton(
style: TextButton.styleFrom(
textStyle: Theme.of(context).textTheme.labelLarge,
),
child: const Text('Disable'),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
style: TextButton.styleFrom(
textStyle: Theme.of(context).textTheme.labelLarge,
),
child: const Text('Enable'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
然后你懂得,敲敲黑板!抄作业就可以了,黑板在哪?嗯,如果大家的风格一致,那上面的代码块应该是黑底带白字的蛤!
罗里吧嗦的,只是想说,flutter 的各种官方Widget都在注释里有示例代码,如果教程不太友好,那可以去注释里碰碰运气;
如果您运气好,那您用发财的金手指点个赞,感谢感谢!
如果刚好运气不好,注释里没有,那您更应该点个赞告诉我一下蛤!说不定我后面会有博客更新加持这个一下,涨涨您的运气!!!
========================END