【问题标题】:Flutter - 'enableInteractiveSelection' not working for EditableTextFlutter - 'enableInteractiveSelection' 不适用于 EditableText
【发布时间】:2018-12-31 22:39:31
【问题描述】:

我正在尝试使用 Flutter 的“EditableText”类。 我对此有 3 个问题。

  1. “enableInteractiveSelection”设置为“true”,但我没有看到“剪切、复制、粘贴”。

  2. 'onSelectionChanged' 似乎不起作用。即使更改选择,我也看不到控制台中的任何内容。

  3. 谁能解释一下如何使用“selectionControls”?

以下是我的“可编辑文本”代码

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Editable Text'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  TextEditingController _mainContentController;
  TextSelectionControls _mainContentSelectionController;
  FocusNode _textFieldFocusNode;

  @override
  void initState() {
    _textFieldFocusNode = FocusNode();
    _mainContentController = TextEditingController();
    super.initState();
  }

  @override
  void dispose() {
    _mainContentController.dispose();
    _textFieldFocusNode.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Column(
        children: <Widget>[
          Text('Editable Text Below'),
          Container(
            padding: EdgeInsets.all(10),
            child: EditableText(
              focusNode: _textFieldFocusNode,
              controller: _mainContentController,
              selectionColor: Colors.blue,
              style: TextStyle(color: Colors.black, fontSize: 17),
              cursorColor: Colors.blue,
              textInputAction: TextInputAction.newline,
              maxLines: null,
              onChanged: (text) {
                print(text);
              },
              enableInteractiveSelection: true,
              onSelectionChanged:
                  (TextSelection textSelection, SelectionChangedCause cause) {
                print('working?');
                print(textSelection.start);
                print(cause);
              },
              selectionControls: _mainContentSelectionController,
            ),
          )
        ],
      ),
    );
  }
}

【问题讨论】:

    标签: android ios dart flutter


    【解决方案1】:

    您可以只使用 TextField,它为 Android 和 iOS 的交互式控制器提供了自定义实现。

    这是 Android 的实现:

        class _MaterialTextSelectionControls extends TextSelectionControls {
          @override
          Size handleSize = const Size(_kHandleSize, _kHandleSize);
    
          /// Builder for material-style copy/paste text selection toolbar.
          @override
          Widget buildToolbar(BuildContext context, Rect globalEditableRegion, Offset position, TextSelectionDelegate delegate) {
            assert(debugCheckHasMediaQuery(context));
            assert(debugCheckHasMaterialLocalizations(context));
            return ConstrainedBox(
              constraints: BoxConstraints.tight(globalEditableRegion.size),
              child: CustomSingleChildLayout(
                delegate: _TextSelectionToolbarLayout(
                  MediaQuery.of(context).size,
                  globalEditableRegion,
                  position,
                ),
                child: _TextSelectionToolbar(
                  handleCut: canCut(delegate) ? () => handleCut(delegate) : null,
                  handleCopy: canCopy(delegate) ? () => handleCopy(delegate) : null,
                  handlePaste: canPaste(delegate) ? () => handlePaste(delegate) : null,
                  handleSelectAll: canSelectAll(delegate) ? () => handleSelectAll(delegate) : null,
                ),
              )
            );
          }
    
          /// Builder for material-style text selection handles.
          @override
          Widget buildHandle(BuildContext context, TextSelectionHandleType type, double textHeight) {
            final Widget handle = Padding(
              padding: const EdgeInsets.only(right: 26.0, bottom: 26.0),
              child: SizedBox(
                width: _kHandleSize,
                height: _kHandleSize,
                child: CustomPaint(
                  painter: _TextSelectionHandlePainter(
                    color: Theme.of(context).textSelectionHandleColor
                  ),
                ),
              ),
            );
    
            // [handle] is a circle, with a rectangle in the top left quadrant of that
            // circle (an onion pointing to 10:30). We rotate [handle] to point
            // straight up or up-right depending on the handle type.
            switch (type) {
              case TextSelectionHandleType.left: // points up-right
                return Transform(
                  transform: Matrix4.rotationZ(math.pi / 2.0),
                  child: handle
                );
              case TextSelectionHandleType.right: // points up-left
                return handle;
              case TextSelectionHandleType.collapsed: // points up
                return Transform(
                  transform: Matrix4.rotationZ(math.pi / 4.0),
                  child: handle
                );
            }
            assert(type != null);
            return null;
          }
        }
    

    您可以从text_selection.dart查看源代码,cupertino也是如此。

    在您的示例中,您使用的是空变量 _mainContentSelectionController,因此您在长按输入时看不到任何内容。

    尝试从 TextSelectionControls 创建一个新类并从 _MaterialTextSelectionControls 复制逻辑。

    示例:

          selectionControls: MySelectionControls(),
    

    ...

      class MySelectionControls extends TextSelectionControls {
        @override
        Widget buildHandle(BuildContext context, TextSelectionHandleType type, double textLineHeight) {
          // TODO: implement buildHandle
          return null;
        }
    
        @override
        Widget buildToolbar(BuildContext context, Rect globalEditableRegion, Offset position, TextSelectionDelegate delegate) {
          // TODO: implement buildToolbar
          return null;
        }
    
        @override
        // TODO: implement handleSize
        Size get handleSize => null;
    
      }
    

    【讨论】:

    • 非常感谢您的回答!
    猜你喜欢
    • 2020-01-07
    • 2020-08-13
    • 2022-07-19
    • 1970-01-01
    • 1970-01-01
    • 2021-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多