Flutter development practice - customize long press TextField input box to cut, copy, select all menu AdaptiveTextSelectionToolba style UI effects

Flutter development practice-customize long-press TextField input box to cut, copy, and select all menu style UI effects

During the development process, I need to press and hold the TextField input box cut and copy to set it to Chinese "copy and paste". I first checked the source code in TextField and saw ToolbarOptions and AdaptiveTextSelectionToolbar. At this time, we can cut, copy, and select all The icon button is now displayed on the menu style UI effect.

Insert image description here

1. Code contextMenuBuilder in TextField source code

Here in the source code of TextField, I saw ToolbarOptions and AdaptiveTextSelectionToolbar. You can inherit AdaptiveTextSelectionToolbar to change the cut, copy, and select all menu style effects.

Just set the customized AdaptiveTextSelectionToolbar to contextMenuBuilder.

TextField source code section

  /// {@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,
    );
  }

2. Customize AdaptiveTextSelectionToolbar

Inherit AdaptiveTextSelectionToolbar to implement custom toolbar style CustomTextSelectionToolbar

After customization, you need to implement the button list

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,
  ));
}

Customize the button SelectionToolBarButton and set the button style of 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,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

The complete code of CustomTextSelectionToolbar is as follows

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,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

3. Use CustomTextSelectionToolbar in TextField

Set contextMenuBuilder in TextField input box

static Widget _textFieldContextMenuBuilder(BuildContext context, EditableTextState editableTextState) {
    
    
    return CustomTextSelectionToolbar.editableText(
      editableTextState: editableTextState,
    );
  }

Finally, set contextMenuBuilder in the TextField input box

TextField(
        contextMenuBuilder: _textFieldContextMenuBuilder,
        minLines: 1,
        maxLines: null,
        keyboardType: TextInputType.multiline,
        textAlignVertical: TextAlignVertical.center,
        autofocus: widget.autofocus,
        focusNode: editFocusNode,
        controller: widget.textEditingController,
        textInputAction: TextInputAction.send,
)

At this point, you can customize the UI effect of long-pressing the TextField input box to cut, copy, and select all menu styles.
Insert image description here
Insert image description here
Use the system global cut, copy, and select all settings to Chinese. You can view: https://blog.csdn.net/gloryFlow/article /details/132966717

4. Summary

Flutter development practice-customize the UI effects of long-pressing the TextField input box to cut, copy, and select all menu styles. Customize AdaptiveTextSelectionToolbar and set contextMenuBuilder in the TextField input box to implement the function.
There is a lot of content and the description may not be accurate, so please forgive me.

URL of this article: https://blog.csdn.net/gloryFlow/article/details/132970840

Study and record, keep improving every day.

Guess you like

Origin blog.csdn.net/gloryFlow/article/details/132970840