flutter开发实战-自定义长按TextField输入框剪切、复制、选择全部菜单AdaptiveTextSelectionToolba样式UI效果

2023-09-18 11:43:10

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

学习记录,每天不停进步。

更多推荐

角度回归——角度编码方式

文章目录1.为什么研究角度的编码方式?1.1角度本身具有周期性1.2深度学习的损失函数因为角度本身的周期性,在周期性的点上可能产生很大的Loss,造成训练不稳定1.3那么如何处理边界问题呢:(以θ的边界问题为例)1.3顺时针(CW)1.4逆时针(CCW)2角度回归的方式2.1长边定义法,强制W<H,range范围[-9

如何更好的选择服务器硬盘?

一.选择服务器硬盘时,可以考虑以下几个因素:1.容量需求:首先确定您的服务器对存储容量的需求。评估您预计需要存储的数据量、应用程序和文件的大小,以及未来的扩展需求。确保选择的硬盘能够满足服务器的存储需求,并有足够的空间用于备份和增长。2.性能要求:考虑您的服务器对性能的需求。如果服务器需要处理大量的读写操作、高速数据传

解决@vueup/vue-quill图片上传、视频上传问题

Editor.vue<template><el-upload:action="uploadUrl":before-upload="handleBeforeUpload":on-success="handleUploadSuccess"name="files":on-error="handleUploadError":s

第一章 计算机网络基础

目录1.1网络体系结构1.1.1OSI/RM七层参考模型1.1.2OSI/RM和TCP/IP模型的比较1.1.3五层协议的体系结构1.1.4计算机1向计算机2发送数据过程1.1.5TCP/IP体系结构的具体实现1.2网络设备概述1.2.1互联设备与OSI的对应关系1.2.2集线器(HUB)1.2.3网桥(Bridge)

酷开系统——酷开科技挖掘下沉市场的重要利器

纵观整个互联网的发展历程,我们经历从搜索时代到电子商务时代,再从社交网络时代到近几年兴起的兴趣网络时代。而在当下的兴趣网络时代,面对多元化、同质化的产品,价值文化成为品牌和消费者建立连接的关键。目前,互联网也已进入价值网络时代。而具有强曝光的互联网智能大屏天然是塑造品牌形象、助力品牌与消费者进行文化价值共创的重要载体。

做了五年功能测试麻木了,现在想进阶自动化测试该从哪里开始?

什么是自动化测试?做测试好几年了,真正学习和实践自动化测试一年,自我感觉这一个年中收获许多。一直想动笔写一篇文章分享自动化测试实践中的一些经验。终于决定花点时间来做这件事儿。首先理清自动化测试的概念,广义上来讲,自动化包括一切通过工具(程序)的方式来代替或辅助手工测试的行为都可以看做自动化,包括性能测试工具(loadr

云端IDE的技术选型1

背景考虑到以下几点,准备给低代码平台开发一套云端的IDE:桌面端IDE:vscode或idea,都有需要开发人员安装ide,以及配置环境很多时候,配置开发环境是个非常曲折过程,经常出现版本不匹配,即使有文档,也经常出现文档没有及时更新等问题同时,配置环境又是一个完全不产出任何价值的过程希望有一套云端的开发环境,即开即用

windows下mysql的高可用方案

PS:理论上linux下也可以使用这种方案环境准备:首先准备两台电脑,全部安装MySQL,然后分别查看一下ip地址,我的两个ip分别是:192.168.25.134(简称134)192.168.25.135(简称135)配置:my.ini一、配置两个MySQL的my.ini如下:必須卸载mysqld后面134my.in

ROS相机内参标定详细步骤指南

作者:HermanYe@Galbot@Auromix版本:V1.0测试环境:Ubuntu20.04、ROS1Noetic更新日期:2023/09/14注1:本文内容中的硬件由@Galbot提供支持。注2:@Auromix是一个机器人爱好者开源组织。注3:由于笔者水平有限,以下内容可能存在错误。注4:本文中直接引用各包官

python中的字符串也是可迭代对象吗?

python中的字符串也是可迭代对象吗?━━━━━━━━━━━━━━━━━━━━━━是的,Python中的字符串是可迭代对象。这意味着你可以像处理列表或元组那样处理字符串。例如,你可以使用for循环遍历字符串中的每个字符,或者使用in运算符检查一个字符串是否包含另一个字符串。这些都是Python中可迭代对象的特性。━━

Matlab论文插图绘制模板第114期—带图形标记的图

之前的文章中,分享了Matlab带线标记的图:带阴影标记的图:带箭头标记的图:进一步,分享一下带图形标记的图,先来看一下成品效果:特别提示:本期内容『数据+代码』已上传资源群中,加群的朋友请自行下载。有需要的朋友可以关注同名公号【阿昆的科研日常】,后台回复关键词【绘图桶】查看加入方式。模板中最关键的部分内容:1.数据准

热文推荐