fix: reduce rebuild while editing text field

This commit is contained in:
appflowy 2022-09-06 20:43:49 +08:00
parent 3ae28186e8
commit 86e2091ccf
5 changed files with 64 additions and 33 deletions

View File

@ -99,7 +99,6 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
));
},
endEditRow: (rowId) {
assert(state.editingRow.isSome());
state.editingRow.fold(() => null, (editingRow) {
assert(editingRow.row.id == rowId);
emit(state.copyWith(editingRow: none()));

View File

@ -77,7 +77,7 @@ class BoardCardBloc extends Bloc<BoardCardEvent, BoardCardState> {
}
}
UnmodifiableListView<BoardCellEquatable> _makeCells(
List<BoardCellEquatable> _makeCells(
String groupFieldId, GridCellMap originalCellMap) {
List<BoardCellEquatable> cells = [];
for (final entry in originalCellMap.entries) {
@ -86,14 +86,14 @@ UnmodifiableListView<BoardCellEquatable> _makeCells(
cells.add(BoardCellEquatable(entry.value));
}
}
return UnmodifiableListView(cells);
return cells;
}
@freezed
class BoardCardEvent with _$BoardCardEvent {
const factory BoardCardEvent.initial() = _InitialRow;
const factory BoardCardEvent.didReceiveCells(
UnmodifiableListView<BoardCellEquatable> cells,
List<BoardCellEquatable> cells,
RowsChangedReason reason,
) = _DidReceiveCells;
}
@ -102,12 +102,11 @@ class BoardCardEvent with _$BoardCardEvent {
class BoardCardState with _$BoardCardState {
const factory BoardCardState({
required RowPB rowPB,
required UnmodifiableListView<BoardCellEquatable> cells,
required List<BoardCellEquatable> cells,
RowsChangedReason? changeReason,
}) = _BoardCardState;
factory BoardCardState.initial(
RowPB rowPB, UnmodifiableListView<BoardCellEquatable> cells) =>
factory BoardCardState.initial(RowPB rowPB, List<BoardCellEquatable> cells) =>
BoardCardState(
rowPB: rowPB,
cells: cells,
@ -120,10 +119,12 @@ class BoardCellEquatable extends Equatable {
const BoardCellEquatable(this.identifier);
@override
List<Object?> get props => [
identifier.fieldContext.id,
identifier.fieldContext.fieldType,
identifier.fieldContext.visibility,
identifier.fieldContext.width,
];
List<Object?> get props {
return [
identifier.fieldContext.id,
identifier.fieldContext.fieldType,
identifier.fieldContext.visibility,
identifier.fieldContext.width,
];
}
}

View File

@ -63,6 +63,7 @@ class BoardContent extends StatefulWidget {
class _BoardContentState extends State<BoardContent> {
late AppFlowyBoardScrollController scrollManager;
final Map<String, ValueKey> cardKeysCache = {};
final config = AppFlowyBoardConfig(
groupBackgroundColor: HexColor.fromHex('#F7F8FC'),
@ -239,8 +240,15 @@ class _BoardContentState extends State<BoardContent> {
},
);
ValueKey? key = cardKeysCache[columnItem.id];
if (key == null) {
final newKey = ValueKey(columnItem.id);
cardKeysCache[columnItem.id] = newKey;
key = newKey;
}
return AppFlowyGroupCard(
key: ValueKey(columnItem.id),
key: key,
margin: config.cardPadding,
decoration: _makeBoxDecoration(context),
child: BoardCard(

View File

@ -56,7 +56,11 @@ class _BoardTextCellState extends State<BoardTextCell> {
}
}
});
_bindEditableNotifier();
super.initState();
}
void _bindEditableNotifier() {
widget.editableNotifier?.becomeFirstResponder.addListener(() {
if (!mounted) return;
WidgetsBinding.instance.addPostFrameCallback((_) {
@ -69,8 +73,12 @@ class _BoardTextCellState extends State<BoardTextCell> {
if (!mounted) return;
_cellBloc.add(const BoardTextCellEvent.enableEdit(false));
});
}
super.initState();
@override
void didUpdateWidget(covariant BoardTextCell oldWidget) {
_bindEditableNotifier();
super.didUpdateWidget(oldWidget);
}
@override
@ -84,6 +92,15 @@ class _BoardTextCellState extends State<BoardTextCell> {
}
},
child: BlocBuilder<BoardTextCellBloc, BoardTextCellState>(
buildWhen: (previous, current) {
if (previous.content != current.content &&
_controller.text == current.content &&
current.enableEdit) {
return false;
}
return previous != current;
},
builder: (context, state) {
if (state.content.isEmpty &&
state.enableEdit == false &&
@ -127,24 +144,26 @@ class _BoardTextCellState extends State<BoardTextCell> {
}
Widget _buildTextField() {
return TextField(
controller: _controller,
focusNode: focusNode,
onChanged: (value) => focusChanged(),
onEditingComplete: () => focusNode.unfocus(),
maxLines: 1,
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
fontFamily: 'Mulish',
),
decoration: InputDecoration(
// Magic number 4 makes the textField take up the same space as FlowyText
contentPadding: EdgeInsets.symmetric(
vertical: BoardSizes.cardCellVPadding + 4,
return IntrinsicHeight(
child: TextField(
controller: _controller,
focusNode: focusNode,
onChanged: (value) => focusChanged(),
onEditingComplete: () => focusNode.unfocus(),
maxLines: null,
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
fontFamily: 'Mulish',
),
decoration: InputDecoration(
// Magic number 4 makes the textField take up the same space as FlowyText
contentPadding: EdgeInsets.symmetric(
vertical: BoardSizes.cardCellVPadding + 4,
),
border: InputBorder.none,
isDense: true,
),
border: InputBorder.none,
isDense: true,
),
);
}

View File

@ -5,6 +5,7 @@ import 'package:app_flowy/plugins/grid/presentation/widgets/row/row_action_sheet
import 'package:flowy_infra/image.dart';
import 'package:flowy_infra/theme.dart';
import 'package:flowy_infra_ui/flowy_infra_ui_web.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'board_cell.dart';
@ -56,7 +57,10 @@ class _BoardCardState extends State<BoardCard> {
value: _cardBloc,
child: BlocBuilder<BoardCardBloc, BoardCardState>(
buildWhen: (previous, current) {
return previous.cells != current.cells;
if (previous.cells.length != current.cells.length) {
return true;
}
return !listEquals(previous.cells, current.cells);
},
builder: (context, state) {
return BoardCardContainer(