chore: optimize cell focus

This commit is contained in:
appflowy 2022-04-27 14:24:50 +08:00
parent d0b4abb0c8
commit f972cdd3fb
6 changed files with 85 additions and 13 deletions

View File

@ -44,7 +44,16 @@ class BlankCell extends StatelessWidget {
abstract class GridCellWidget extends HoverWidget {
@override
final ValueNotifier<bool> onFocus = ValueNotifier<bool>(false);
final GridCellRequestFocusNotifier requestFocus = GridCellRequestFocusNotifier();
GridCellWidget({Key? key}) : super(key: key);
}
class GridCellRequestFocusNotifier extends ChangeNotifier {
void notify() {
notifyListeners();
}
}
abstract class GridCellStyle {}

View File

@ -1,3 +1,4 @@
import 'package:app_flowy/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart';
import 'package:flowy_infra/theme.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
@ -31,17 +32,20 @@ class CellContainer extends StatelessWidget {
final GridCellWidget child;
final Widget? expander;
final double width;
final RegionStateNotifier rowStateNotifier;
const CellContainer({
Key? key,
required this.child,
required this.width,
required this.rowStateNotifier,
this.expander,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
return ChangeNotifierProxyProvider<RegionStateNotifier, CellStateNotifier>(
create: (_) => CellStateNotifier(),
update: (_, row, cell) => cell!..onEnter = row.onEnter,
child: Selector<CellStateNotifier, bool>(
selector: (context, notifier) => notifier.isFocus,
builder: (context, isFocus, _) {
@ -54,11 +58,15 @@ class CellContainer extends StatelessWidget {
container = _CellEnterRegion(child: container, expander: expander!);
}
return Container(
constraints: BoxConstraints(maxWidth: width),
decoration: _makeBoxDecoration(context, isFocus),
padding: GridSize.cellContentInsets,
child: container,
return GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () => child.requestFocus.notify(),
child: Container(
constraints: BoxConstraints(maxWidth: width),
decoration: _makeBoxDecoration(context, isFocus),
padding: GridSize.cellContentInsets,
child: container,
),
);
},
),

View File

@ -24,6 +24,7 @@ class _CheckboxCellState extends State<CheckboxCell> {
void initState() {
final cellContext = widget.cellContextBuilder.build();
_cellBloc = getIt<CheckboxCellBloc>(param1: cellContext)..add(const CheckboxCellEvent.initial());
_listenCellRequestFocus();
super.initState();
}
@ -48,9 +49,21 @@ class _CheckboxCellState extends State<CheckboxCell> {
);
}
@override
void didUpdateWidget(covariant CheckboxCell oldWidget) {
_listenCellRequestFocus();
super.didUpdateWidget(oldWidget);
}
@override
Future<void> dispose() async {
_cellBloc.close();
super.dispose();
}
void _listenCellRequestFocus() {
widget.requestFocus.addListener(() {
_cellBloc.add(const CheckboxCellEvent.select());
});
}
}

View File

@ -23,6 +23,7 @@ class _NumberCellState extends State<NumberCell> {
late NumberCellBloc _cellBloc;
late TextEditingController _controller;
late FocusNode _focusNode;
VoidCallback? _focusListener;
Timer? _delayOperation;
@override
@ -40,6 +41,7 @@ class _NumberCellState extends State<NumberCell> {
@override
Widget build(BuildContext context) {
_listenCellRequestFocus(context);
return BlocProvider.value(
value: _cellBloc,
child: BlocConsumer<NumberCellBloc, NumberCellState>(
@ -68,6 +70,9 @@ class _NumberCellState extends State<NumberCell> {
@override
Future<void> dispose() async {
if (_focusListener != null) {
widget.requestFocus.removeListener(_focusListener!);
}
_delayOperation?.cancel();
_cellBloc.close();
_focusNode.dispose();
@ -89,4 +94,19 @@ class _NumberCellState extends State<NumberCell> {
});
}
}
void _listenCellRequestFocus(BuildContext context) {
if (_focusListener != null) {
widget.requestFocus.removeListener(_focusListener!);
}
focusListener() {
if (_focusNode.hasFocus == false && _focusNode.canRequestFocus) {
FocusScope.of(context).requestFocus(_focusNode);
}
}
_focusListener = focusListener;
widget.requestFocus.addListener(focusListener);
}
}

View File

@ -36,7 +36,7 @@ class _GridTextCellState extends State<GridTextCell> {
late TextCellBloc _cellBloc;
late TextEditingController _controller;
late FocusNode _focusNode;
VoidCallback? _focusListener;
Timer? _delayOperation;
@override
@ -50,11 +50,14 @@ class _GridTextCellState extends State<GridTextCell> {
widget.onFocus.value = _focusNode.hasFocus;
focusChanged();
});
super.initState();
}
@override
Widget build(BuildContext context) {
_listenCellRequestFocus(context);
return BlocProvider.value(
value: _cellBloc,
child: BlocConsumer<TextCellBloc, TextCellState>(
@ -84,8 +87,26 @@ class _GridTextCellState extends State<GridTextCell> {
);
}
void _listenCellRequestFocus(BuildContext context) {
if (_focusListener != null) {
widget.requestFocus.removeListener(_focusListener!);
}
focusListener() {
if (_focusNode.hasFocus == false && _focusNode.canRequestFocus) {
FocusScope.of(context).requestFocus(_focusNode);
}
}
_focusListener = focusListener;
widget.requestFocus.addListener(focusListener);
}
@override
Future<void> dispose() async {
if (_focusListener != null) {
widget.requestFocus.removeListener(_focusListener!);
}
_delayOperation?.cancel();
_cellBloc.close();
_focusNode.dispose();

View File

@ -88,7 +88,7 @@ class _RowLeading extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Consumer<_RegionStateNotifier>(
return Consumer<RegionStateNotifier>(
builder: (context, state, _) {
return SizedBox(width: GridSize.leadingHeaderPadding, child: state.onEnter ? _activeWidget() : null);
},
@ -164,13 +164,13 @@ class _RowCells extends StatelessWidget {
return Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: _makeCells(state.cellDataMap),
children: _makeCells(context, state.cellDataMap),
);
},
);
}
List<Widget> _makeCells(GridCellMap gridCellMap) {
List<Widget> _makeCells(BuildContext context, GridCellMap gridCellMap) {
return gridCellMap.values.map(
(gridCell) {
Widget? expander;
@ -181,6 +181,7 @@ class _RowCells extends StatelessWidget {
return CellContainer(
width: gridCell.field.width.toDouble(),
child: buildGridCellWidget(gridCell, cellCache),
rowStateNotifier: Provider.of<RegionStateNotifier>(context, listen: false),
expander: expander,
);
},
@ -188,7 +189,7 @@ class _RowCells extends StatelessWidget {
}
}
class _RegionStateNotifier extends ChangeNotifier {
class RegionStateNotifier extends ChangeNotifier {
bool _onEnter = false;
set onEnter(bool value) {
@ -226,11 +227,11 @@ class _RowEnterRegion extends StatefulWidget {
}
class _RowEnterRegionState extends State<_RowEnterRegion> {
late _RegionStateNotifier _rowStateNotifier;
late RegionStateNotifier _rowStateNotifier;
@override
void initState() {
_rowStateNotifier = _RegionStateNotifier();
_rowStateNotifier = RegionStateNotifier();
super.initState();
}