Flutter-Quill 编辑器无法在可滚动表单内工作

nic*_*ord 5 flutter flutter-dependencies flutter-layout

我想将我的QuillEditor内容放在我的表单中,而不是放在我的应用程序的专用页面上。

我尝试过使用 a ColumninsideSingleChildScrollView和一个ListView小部件,但结果是相同的:

  • 由于没有文本,编辑器很小,我希望它能够“扩展”(我知道它不能在卷轴内如此,但你明白了);
  • 文本的溢出不会使页面相应地滚动,因此用户看不到他们正在输入的内容。

这是一些代码:

return Scaffold(
  appBar: AppBar(
    title: Text("Reply form"),
    actions: [
      IconButton(
        onPressed: () {},
        icon: Icon(Icons.send),
        tooltip: "Send",
      )
    ],
  ),
  body: SafeArea(
    child: Form(
      child: ListView(
        children: [
          Text("From: test@my.org"),
          SizedBox(height: 8),
          chipInputField(
            label: "To",
            onChanged: (List<Object?> o) {},
            initialValue: ["first@email.it"],
          ),
          chipInputField(
            label: "Cc",
            onChanged: (List<Object?> o) {},
            initialValue: ["second@email.it"],
          ),
          chipInputField(
            label: "Bcc",
            onChanged: (List<Object?> o) {},
            initialValue: ["third@email.it"],
          ),
          QuillEditor(
            controller: quillController,
            scrollable: true,
            scrollController: ScrollController(),
            focusNode: FocusNode(),
            padding: EdgeInsets.all(5),
            autoFocus: true,
            readOnly: false,
            expands: false,
            placeholder: "compose_email",
          ),
          QuillToolbar.basic(
            controller: quillController,
            showUnderLineButton: false,
            showStrikeThrough: false,
            showColorButton: false,
            showBackgroundColorButton: false,
            showListCheck: false,
            showIndent: false,
          ),
        ],
      ),
    ),
  ),
);
Run Code Online (Sandbox Code Playgroud)

第一个问题:撰写电子邮件部分在应用程序页面内未展开

撰写电子邮件部分未在应用程序页面内展开

第二个问题:只要我写一些文本,小部件就不会滚动

键盘位于文本上方并且小部件未滚动

编辑:我正在使用 Flutter 2.2.3 和 flutter_quill: 1.3.3

Nay*_*dwi 2

因此,在多次尝试解决这个答案之后,我意识到以下内容并提出了一个可能对您有帮助的解决方案。

textField列表视图中的amaxlines: null会自动滚动列表视图,没有任何问题,但由于某种原因,flutter_quill 有一些问题

现在我的解决方法如下(完整的代码将在底部):

  1. 首先我们在具有这种形式的小部件的状态类中定义几个变量
final quill.QuillController quillController = quill.QuillController.basic();
final FocusNode editorFocusNode = FocusNode();
bool isToolBarVisible = true;
Run Code Online (Sandbox Code Playgroud)

您已经定义了控制器,但对于其他 2 个属性,您将需要它们根据焦点节点显示/隐藏工具栏。

  1. 我们不使用简单的ListView,而是使用customScrollView,这使我们可以创建更复杂的列表视图,它使用slivers(sliver是一个可滚动的小部件,您可以了解更多信息
Form(
          child: CustomScrollView(
            slivers: [
              SliverAppBar(
                pinned: true,
                toolbarHeight: isToolBarVisible ? 50 : 0,
                title:
                    Visibility(visible: isToolBarVisible, child: getToolBar()),
              ),
              SliverToBoxAdapter(
                child: Column(
                  children: getTextFields(),
                ),
              ),
              SliverFillRemaining(
                hasScrollBody: true,
                child: getEditor(),
              ),
            ],
          ),
Run Code Online (Sandbox Code Playgroud)

使用 sliver 应用栏,我们可以固定 quill 工具栏,使用 sliver to box 适配器,我们可以添加普通文本字段,然后使用 sliverFillRemaining 来展开 quill 编辑器。

以下是子功能:

 Widget getToolBar() {
    return SingleChildScrollView(
      scrollDirection: Axis.horizontal,
      child: quill.QuillToolbar.basic(
        controller: quillController,
        showUnderLineButton: false,
        showStrikeThrough: false,
        showColorButton: false,
        showBackgroundColorButton: false,
        showListCheck: false,
        showIndent: false,
      ),
    );
  }

  List<Widget> getTextFields() {
    return [
      Text("From: test@my.org"),
      SizedBox(height: 8),
      TextField(
        decoration: InputDecoration(labelText: "To"),
      ),
      TextField(
        decoration: InputDecoration(labelText: "Cc"),
      ),
      TextField(
        decoration: InputDecoration(labelText: "Bcc"),
      ),
    ];
  }

  Widget getEditor() {
    return QuillEditor(
      controller: quillController,
      scrollable: true,
      scrollController: ScrollController(),
      focusNode: editorFocusNode,
      padding: EdgeInsets.all(5),
      autoFocus: true,
      readOnly: false,
      expands: false,
      placeholder: "compose_email",
    );
  }
Run Code Online (Sandbox Code Playgroud)

将普通的文本字段替换为您的芯片输入字段

最后这是完整的代码:

import 'package:flutter/material.dart';
import 'package:flutter_quill/flutter_quill.dart' as quill;
import 'package:flutter_quill/widgets/editor.dart';

class FlutterQuillForm extends StatefulWidget {
  @override
  _FlutterQuillFormState createState() => _FlutterQuillFormState();
}

class _FlutterQuillFormState extends State<FlutterQuillForm> {
  final quill.QuillController quillController = quill.QuillController.basic();
  final FocusNode editorFocusNode = FocusNode();
  bool isToolBarVisible = true;
  @override
  void initState() {
    editorFocusNode.addListener(() {
      setState(() {
        isToolBarVisible = editorFocusNode.hasFocus;
      });
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Reply form"),
        actions: [
          IconButton(
            onPressed: () {},
            icon: Icon(Icons.send),
            tooltip: "Send",
          )
        ],
      ),
      body: SafeArea(
        child: Form(
          child: CustomScrollView(
            slivers: [
              SliverAppBar(
                pinned: true,
                toolbarHeight: isToolBarVisible ? 50 : 0,
                title:
                    Visibility(visible: isToolBarVisible, child: getToolBar()),
              ),
              SliverToBoxAdapter(
                child: Column(
                  children: getTextFields(),
                ),
              ),
              SliverFillRemaining(
                hasScrollBody: true,
                child: getEditor(),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget getToolBar() {
    return SingleChildScrollView(
      scrollDirection: Axis.horizontal,
      child: quill.QuillToolbar.basic(
        controller: quillController,
        showUnderLineButton: false,
        showStrikeThrough: false,
        showColorButton: false,
        showBackgroundColorButton: false,
        showListCheck: false,
        showIndent: false,
      ),
    );
  }

  List<Widget> getTextFields() {
    return [
      Text("From: test@my.org"),
      SizedBox(height: 8),
      TextField(
        decoration: InputDecoration(labelText: "To"),
      ),
      TextField(
        decoration: InputDecoration(labelText: "Cc"),
      ),
      TextField(
        decoration: InputDecoration(labelText: "Bcc"),
      ),
    ];
  }

  Widget getEditor() {
    return QuillEditor(
      controller: quillController,
      scrollable: true,
      scrollController: ScrollController(),
      focusNode: editorFocusNode,
      padding: EdgeInsets.all(5),
      autoFocus: true,
      readOnly: false,
      expands: false,
      placeholder: "compose_email",
    );
  }

  @override
  void dispose() {
    super.dispose();
    quillController.dispose();
  }
}

Run Code Online (Sandbox Code Playgroud)

在焦点节点监听器中,我们可以将工具栏的状态设置为可见或不可见,并且不要忘记配置控制器和焦点节点。

截图:

工具栏隐藏 工具栏显示 自动滚屏