Flutter-'enableInteractiveSelection'不适用于EditableText

时间:2018-12-31 22:39:32

标签: android ios dart flutter

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

  1. 'enableInteractiveSelection'设置为'true',但看不到'剪切,复制,粘贴'。

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

  3. 有人可以向我解释如何使用“ selectionControls”吗?

下面是我的“ EditableText”代码

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

1 个答案:

答案 0 :(得分: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;

  }