feat: optimize editable features (#541)
This commit is contained in:
parent
9ae85ea162
commit
89b93d89a7
6 changed files with 124 additions and 20 deletions
|
|
@ -6,6 +6,7 @@ import 'dart:math';
|
|||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:example/pages/customize_theme_for_editor.dart';
|
||||
import 'package:example/pages/editor.dart';
|
||||
import 'package:example/pages/editor_list.dart';
|
||||
import 'package:example/pages/focus_example_for_editor.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
|
@ -183,6 +184,14 @@ class _HomePageState extends State<HomePage> {
|
|||
),
|
||||
);
|
||||
}),
|
||||
_buildListTile(context, 'Editor List', () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const EditorList(),
|
||||
),
|
||||
);
|
||||
}),
|
||||
|
||||
// Encoder Demo
|
||||
_buildSeparator(context, 'Export To X Demo'),
|
||||
|
|
|
|||
71
example/lib/pages/editor_list.dart
Normal file
71
example/lib/pages/editor_list.dart
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class EditorList extends StatefulWidget {
|
||||
const EditorList({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
State<EditorList> createState() => _EditorListState();
|
||||
}
|
||||
|
||||
class _EditorListState extends State<EditorList> {
|
||||
final List<Document> documents = [];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
for (var i = 0; i < 100; i++) {
|
||||
final document = Document.blank()
|
||||
..insert([
|
||||
0
|
||||
], [
|
||||
headingNode(level: 3, delta: Delta()..insert('Heading $i')),
|
||||
paragraphNode(
|
||||
delta: Delta()
|
||||
..insert('Paragraph $i: ')
|
||||
..insert(
|
||||
'formatted text',
|
||||
attributes: {'bold': true, 'italic': true, 'underline': true},
|
||||
),
|
||||
),
|
||||
]);
|
||||
documents.add(document);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.black,
|
||||
title: const Text('Editor List'),
|
||||
titleTextStyle: const TextStyle(color: Colors.white),
|
||||
iconTheme: const IconThemeData(
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: documents
|
||||
.map(
|
||||
(e) => [
|
||||
AppFlowyEditor(
|
||||
editorState: EditorState(document: e),
|
||||
shrinkWrap: true,
|
||||
editable: false,
|
||||
),
|
||||
const Divider(),
|
||||
],
|
||||
)
|
||||
.expand((element) => element)
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -48,13 +48,18 @@ class PageBlockComponent extends BlockComponentStatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final editorState = context.read<EditorState>();
|
||||
final scrollController = context.read<EditorScrollController>();
|
||||
final scrollController = context.read<EditorScrollController?>();
|
||||
final items = node.children;
|
||||
|
||||
if (scrollController.shrinkWrap) {
|
||||
if (scrollController == null ||
|
||||
scrollController.shrinkWrap ||
|
||||
!editorState.editable) {
|
||||
return Builder(
|
||||
builder: (context) {
|
||||
editorState.updateAutoScroller(Scrollable.of(context));
|
||||
final scroller = Scrollable.maybeOf(context);
|
||||
if (scroller != null) {
|
||||
editorState.updateAutoScroller(scroller);
|
||||
}
|
||||
return Column(
|
||||
children: [
|
||||
if (header != null) header!,
|
||||
|
|
|
|||
|
|
@ -123,6 +123,9 @@ class AppFlowyEditor extends StatefulWidget {
|
|||
final EditorScrollController? editorScrollController;
|
||||
|
||||
/// Set the value to false to disable editing.
|
||||
///
|
||||
/// if false, the editor will only render the block components and
|
||||
/// without the editing, selecting, scrolling features.
|
||||
final bool editable;
|
||||
|
||||
/// Set the value to true to focus the editor on the start of the document.
|
||||
|
|
@ -207,6 +210,13 @@ class _AppFlowyEditorState extends State<AppFlowyEditor> {
|
|||
Widget build(BuildContext context) {
|
||||
services ??= _buildServices(context);
|
||||
|
||||
if (!widget.editable) {
|
||||
return Provider.value(
|
||||
value: editorState,
|
||||
child: services!,
|
||||
);
|
||||
}
|
||||
|
||||
return Provider.value(
|
||||
value: editorState,
|
||||
child: FocusScope(
|
||||
|
|
@ -229,7 +239,10 @@ class _AppFlowyEditorState extends State<AppFlowyEditor> {
|
|||
footer: widget.footer,
|
||||
);
|
||||
|
||||
if (widget.editable) {
|
||||
if (!widget.editable) {
|
||||
return child;
|
||||
}
|
||||
|
||||
child = SelectionServiceWidget(
|
||||
key: editorState.service.selectionServiceKey,
|
||||
cursorColor: widget.editorStyle.cursorColor,
|
||||
|
|
@ -243,7 +256,6 @@ class _AppFlowyEditorState extends State<AppFlowyEditor> {
|
|||
child: child,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return ScrollServiceWidget(
|
||||
key: editorState.service.scrollServiceKey,
|
||||
|
|
|
|||
|
|
@ -142,9 +142,11 @@ class EditorScrollController {
|
|||
scrollController.dispose();
|
||||
}
|
||||
|
||||
if (!shrinkWrap) {
|
||||
_scrollOffsetSubscription.cancel();
|
||||
_itemPositionsListener.itemPositions.removeListener(_listenItemPositions);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> animateTo({
|
||||
required double offset,
|
||||
|
|
|
|||
|
|
@ -42,7 +42,12 @@ void main() async {
|
|||
)
|
||||
..addParagraph(initialText: text);
|
||||
|
||||
await editor.startTesting(editable: false);
|
||||
await editor.startTesting(
|
||||
editable: false,
|
||||
wrapper: (child) => SingleChildScrollView(
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(editor.documentRootLen, 3);
|
||||
|
|
|
|||
Loading…
Reference in a new issue