flutter开发实战-自定义长按TextField输入框剪切、复制、选择全部菜单样式UI效果
在开发过程中,需要长按TextField输入框cut、copy设置为中文“复制、粘贴”,我首先查看了TextField中的源码,看到了ToolbarOptions、AdaptiveTextSelectionToolbar,这时候我们可以在剪切、复制、选择全部菜单样式UI效果上显示icon的按钮了。
一、TextField源码中的代码contextMenuBuilder
我这里在中TextField中的源码,看到了ToolbarOptions、AdaptiveTextSelectionToolbar,可以继承AdaptiveTextSelectionToolbar来实现更改剪切、复制、选择全部菜单样式效果
将自定义的AdaptiveTextSelectionToolbar,设置到contextMenuBuilder即可。
TextField源码一段
/// {@macro flutter.widgets.EditableText.contextMenuBuilder}////// If not provided, will build a default menu based on the platform.////// See also:////// * [AdaptiveTextSelectionToolbar], which is built by default.final EditableTextContextMenuBuilder? contextMenuBuilder;static Widget _defaultContextMenuBuilder(BuildContext context, EditableTextState editableTextState) {return AdaptiveTextSelectionToolbar.editableText(editableTextState: editableTextState,);}
二、自定义AdaptiveTextSelectionToolbar
继承AdaptiveTextSelectionToolbar实现自定义的toolbar样式CustomTextSelectionToolbar
自定义后需要实现按钮列表
List<Widget> resultChildren = <Widget>[];
for (int i = 0; i < buttonItems!.length; i++) {final ContextMenuButtonItem buttonItem = buttonItems![i];resultChildren.add(SelectionToolBarButton(width: 100,height: 50,icon: (i == 0)?Icon(Icons.cut,color: Colors.white,size: 14,):Icon(Icons.copy,color: Colors.white,size: 16,),title: getButtonLabelString(context, buttonItem),onPressed: buttonItem.onPressed,));
}
自定义按钮SelectionToolBarButton,设置icon+title的按钮样式
class SelectionToolBarButton extends StatelessWidget {const SelectionToolBarButton({super.key,required this.width,required this.height,required this.icon,required this.title,required this.onPressed,});final double width;final double height;final Icon icon;final String title;final VoidCallback onPressed;Widget build(BuildContext context) {return GestureDetector(onTap: () {onPressed();},child: Container(color: Colors.black87,width: width,height: height,alignment: Alignment.center,child: Row(mainAxisAlignment: MainAxisAlignment.center,crossAxisAlignment: CrossAxisAlignment.center,children: [icon,SizedBox(width: 5,),Text(title,style: TextStyle(fontSize: 15,color: Colors.white,),),],),),);}
}
CustomTextSelectionToolbar完整代码如下
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';class CustomTextSelectionToolbar extends AdaptiveTextSelectionToolbar {const CustomTextSelectionToolbar({super.key, required super.children, required super.anchors});CustomTextSelectionToolbar.editableText({super.key,required EditableTextState editableTextState,}) : super.editableText(editableTextState: editableTextState);Widget build(BuildContext context) {// If there aren't any buttons to build, build an empty toolbar.if ((children != null && children!.isEmpty) ||(buttonItems != null && buttonItems!.isEmpty)) {return const SizedBox.shrink();}List<Widget> resultChildren = <Widget>[];for (int i = 0; i < buttonItems!.length; i++) {final ContextMenuButtonItem buttonItem = buttonItems![i];resultChildren.add(SelectionToolBarButton(width: 100,height: 50,icon: (i == 0)?Icon(Icons.cut,color: Colors.white,size: 14,):Icon(Icons.copy,color: Colors.white,size: 16,),title: getButtonLabelString(context, buttonItem),onPressed: buttonItem.onPressed,));}switch (Theme.of(context).platform) {case TargetPlatform.iOS:return CupertinoTextSelectionToolbar(anchorAbove: anchors.primaryAnchor,anchorBelow: anchors.secondaryAnchor == null? anchors.primaryAnchor: anchors.secondaryAnchor!,children: resultChildren,);case TargetPlatform.android:return TextSelectionToolbar(anchorAbove: anchors.primaryAnchor,anchorBelow: anchors.secondaryAnchor == null? anchors.primaryAnchor: anchors.secondaryAnchor!,children: resultChildren,);case TargetPlatform.fuchsia:case TargetPlatform.linux:case TargetPlatform.windows:return DesktopTextSelectionToolbar(anchor: anchors.primaryAnchor,children: resultChildren,);case TargetPlatform.macOS:return CupertinoDesktopTextSelectionToolbar(anchor: anchors.primaryAnchor,children: resultChildren,);}}/// Returns the default button label String for the button of the given/// [ContextMenuButtonType] on any platform.static String getButtonLabelString(BuildContext context, ContextMenuButtonItem buttonItem) {if (buttonItem.label != null) {return buttonItem.label!;}switch (Theme.of(context).platform) {case TargetPlatform.iOS:case TargetPlatform.macOS:case TargetPlatform.android:case TargetPlatform.fuchsia:case TargetPlatform.linux:case TargetPlatform.windows:assert(debugCheckHasMaterialLocalizations(context));switch (buttonItem.type) {case ContextMenuButtonType.cut:return "剪切";case ContextMenuButtonType.copy:return "复制";case ContextMenuButtonType.paste:return "粘贴";case ContextMenuButtonType.selectAll:return "选择全部";case ContextMenuButtonType.custom:return '';}}}
}class SelectionToolBarButton extends StatelessWidget {const SelectionToolBarButton({super.key,required this.width,required this.height,required this.icon,required this.title,required this.onPressed,});final double width;final double height;final Icon icon;final String title;final VoidCallback onPressed;Widget build(BuildContext context) {return GestureDetector(onTap: () {onPressed();},child: Container(color: Colors.black87,width: width,height: height,alignment: Alignment.center,child: Row(mainAxisAlignment: MainAxisAlignment.center,crossAxisAlignment: CrossAxisAlignment.center,children: [icon,SizedBox(width: 5,),Text(title,style: TextStyle(fontSize: 15,color: Colors.white,),),],),),);}
}
三、TextField中使用CustomTextSelectionToolbar
在TextField输入框中设置contextMenuBuilder
static Widget _textFieldContextMenuBuilder(BuildContext context, EditableTextState editableTextState) {return CustomTextSelectionToolbar.editableText(editableTextState: editableTextState,);}
最后在TextField输入框中设置contextMenuBuilder
TextField(contextMenuBuilder: _textFieldContextMenuBuilder,minLines: 1,maxLines: null,keyboardType: TextInputType.multiline,textAlignVertical: TextAlignVertical.center,autofocus: widget.autofocus,focusNode: editFocusNode,controller: widget.textEditingController,textInputAction: TextInputAction.send,
)
至此可以自定义长按TextField输入框剪切、复制、选择全部菜单样式UI效果
使用系统全局剪切、复制、选择全部设置为中文,可以查看:https://blog.csdn.net/gloryFlow/article/details/132966717
四、小结
flutter开发实战-自定义长按TextField输入框剪切、复制、选择全部菜单样式UI效果。自定义AdaptiveTextSelectionToolbar,在TextField输入框中设置contextMenuBuilder,实现功能。
内容较多,描述可能不准确,请见谅。
本文地址:https://blog.csdn.net/gloryFlow/article/details/132970840
学习记录,每天不停进步。