mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: repalce sliver header with single scroll view
This commit is contained in:
parent
d71e0de8c3
commit
6dbb708991
@ -1,3 +1,4 @@
|
||||
import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
@ -7,13 +8,14 @@ import 'grid_service.dart';
|
||||
part 'grid_header_bloc.freezed.dart';
|
||||
|
||||
class GridHeaderBloc extends Bloc<GridHeaderEvent, GridHeaderState> {
|
||||
// final FieldService _fieldService;
|
||||
final FieldService _fieldService;
|
||||
final GridFieldCache fieldCache;
|
||||
|
||||
GridHeaderBloc({
|
||||
required String gridId,
|
||||
required this.fieldCache,
|
||||
}) : super(GridHeaderState.initial(fieldCache.clonedFields)) {
|
||||
}) : _fieldService = FieldService(gridId: gridId),
|
||||
super(GridHeaderState.initial(fieldCache.clonedFields)) {
|
||||
on<GridHeaderEvent>(
|
||||
(event, emit) async {
|
||||
await event.map(
|
||||
@ -23,6 +25,7 @@ class GridHeaderBloc extends Bloc<GridHeaderEvent, GridHeaderState> {
|
||||
didReceiveFieldUpdate: (_DidReceiveFieldUpdate value) {
|
||||
emit(state.copyWith(fields: value.fields));
|
||||
},
|
||||
moveField: (_MoveField value) {},
|
||||
);
|
||||
},
|
||||
);
|
||||
@ -46,6 +49,7 @@ class GridHeaderBloc extends Bloc<GridHeaderEvent, GridHeaderState> {
|
||||
class GridHeaderEvent with _$GridHeaderEvent {
|
||||
const factory GridHeaderEvent.initial() = _InitialHeader;
|
||||
const factory GridHeaderEvent.didReceiveFieldUpdate(List<Field> fields) = _DidReceiveFieldUpdate;
|
||||
const factory GridHeaderEvent.moveField(int fromIndex, int toIndex) = _MoveField;
|
||||
}
|
||||
|
||||
@freezed
|
||||
|
@ -1,21 +1,28 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:linked_scroll_controller/linked_scroll_controller.dart';
|
||||
|
||||
class GridScrollController {
|
||||
final ScrollController _verticalController = ScrollController();
|
||||
final ScrollController _horizontalController = ScrollController();
|
||||
final LinkedScrollControllerGroup _scrollGroupContorller;
|
||||
final ScrollController verticalController;
|
||||
final ScrollController horizontalController;
|
||||
|
||||
ScrollController get verticalController => _verticalController;
|
||||
ScrollController get horizontalController => _horizontalController;
|
||||
final List<ScrollController> _linkHorizontalControllers = [];
|
||||
|
||||
GridScrollController();
|
||||
GridScrollController({required LinkedScrollControllerGroup scrollGroupContorller})
|
||||
: _scrollGroupContorller = scrollGroupContorller,
|
||||
verticalController = ScrollController(),
|
||||
horizontalController = scrollGroupContorller.addAndGet();
|
||||
|
||||
// final SelectionChangeCallback? onSelectionChanged;
|
||||
|
||||
// final ShouldApplySelection? shouldApplySelection;
|
||||
|
||||
// final ScrollCallback? onScroll;
|
||||
ScrollController linkHorizontalController() {
|
||||
final controller = _scrollGroupContorller.addAndGet();
|
||||
_linkHorizontalControllers.add(controller);
|
||||
return controller;
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
for (final controller in _linkHorizontalControllers) {
|
||||
controller.dispose();
|
||||
}
|
||||
verticalController.dispose();
|
||||
horizontalController.dispose();
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Field;
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:linked_scroll_controller/linked_scroll_controller.dart';
|
||||
import 'controller/grid_scroll.dart';
|
||||
import 'layout/layout.dart';
|
||||
import 'layout/sizes.dart';
|
||||
@ -73,17 +74,23 @@ class FlowyGrid extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _FlowyGridState extends State<FlowyGrid> {
|
||||
final _scrollController = GridScrollController();
|
||||
final _scrollController = GridScrollController(scrollGroupContorller: LinkedScrollControllerGroup());
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_scrollController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<GridBloc, GridState>(
|
||||
buildWhen: (previous, current) => previous.fields.length != current.fields.length,
|
||||
builder: (context, state) {
|
||||
final contentWidth = GridLayout.headerWidth(state.fields);
|
||||
final child = _wrapScrollView(
|
||||
state.fields,
|
||||
contentWidth,
|
||||
[
|
||||
_GridHeader(gridId: state.gridId, fields: state.fields),
|
||||
const _GridRows(),
|
||||
const _GridFooter(),
|
||||
],
|
||||
@ -91,6 +98,7 @@ class _FlowyGridState extends State<FlowyGrid> {
|
||||
|
||||
return Column(children: [
|
||||
const _GridToolbarAdaptor(),
|
||||
_gridHeader(context, state.gridId, contentWidth),
|
||||
Flexible(child: child),
|
||||
]);
|
||||
},
|
||||
@ -98,7 +106,7 @@ class _FlowyGridState extends State<FlowyGrid> {
|
||||
}
|
||||
|
||||
Widget _wrapScrollView(
|
||||
List<Field> fields,
|
||||
double contentWidth,
|
||||
List<Widget> slivers,
|
||||
) {
|
||||
final verticalScrollView = ScrollConfiguration(
|
||||
@ -111,7 +119,7 @@ class _FlowyGridState extends State<FlowyGrid> {
|
||||
);
|
||||
|
||||
final sizedVerticalScrollView = SizedBox(
|
||||
width: GridLayout.headerWidth(fields),
|
||||
width: contentWidth,
|
||||
child: verticalScrollView,
|
||||
);
|
||||
|
||||
@ -128,6 +136,19 @@ class _FlowyGridState extends State<FlowyGrid> {
|
||||
child: horizontalScrollView,
|
||||
);
|
||||
}
|
||||
|
||||
Widget _gridHeader(BuildContext context, String gridId, double contentWidth) {
|
||||
final fieldCache = context.read<GridBloc>().fieldCache;
|
||||
|
||||
return SizedBox(
|
||||
width: contentWidth,
|
||||
child: GridHeaderSliverAdaptor(
|
||||
gridId: gridId,
|
||||
fieldCache: fieldCache,
|
||||
anchorScrollController: _scrollController.linkHorizontalController(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _GridToolbarAdaptor extends StatelessWidget {
|
||||
@ -149,18 +170,6 @@ class _GridToolbarAdaptor extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class _GridHeader extends StatelessWidget {
|
||||
final String gridId;
|
||||
final List<Field> fields;
|
||||
const _GridHeader({Key? key, required this.gridId, required this.fields}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final fieldCache = context.read<GridBloc>().fieldCache;
|
||||
return GridHeaderSliverAdaptor(gridId: gridId, fieldCache: fieldCache);
|
||||
}
|
||||
}
|
||||
|
||||
class _GridRows extends StatefulWidget {
|
||||
const _GridRows({Key? key}) : super(key: key);
|
||||
|
||||
|
@ -13,25 +13,41 @@ import 'package:reorderables/reorderables.dart';
|
||||
import 'field_editor.dart';
|
||||
import 'field_cell.dart';
|
||||
|
||||
class GridHeaderSliverAdaptor extends StatelessWidget {
|
||||
class GridHeaderSliverAdaptor extends StatefulWidget {
|
||||
final String gridId;
|
||||
final GridFieldCache fieldCache;
|
||||
final ScrollController anchorScrollController;
|
||||
const GridHeaderSliverAdaptor({
|
||||
required this.gridId,
|
||||
required this.fieldCache,
|
||||
required this.anchorScrollController,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
const GridHeaderSliverAdaptor({required this.gridId, required this.fieldCache, Key? key}) : super(key: key);
|
||||
@override
|
||||
State<GridHeaderSliverAdaptor> createState() => _GridHeaderSliverAdaptorState();
|
||||
}
|
||||
|
||||
class _GridHeaderSliverAdaptorState extends State<GridHeaderSliverAdaptor> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) =>
|
||||
getIt<GridHeaderBloc>(param1: gridId, param2: fieldCache)..add(const GridHeaderEvent.initial()),
|
||||
getIt<GridHeaderBloc>(param1: widget.gridId, param2: widget.fieldCache)..add(const GridHeaderEvent.initial()),
|
||||
child: BlocBuilder<GridHeaderBloc, GridHeaderState>(
|
||||
buildWhen: (previous, current) => previous.fields.length != current.fields.length,
|
||||
builder: (context, state) {
|
||||
return SliverPersistentHeader(
|
||||
delegate: SliverHeaderDelegateImplementation(gridId: gridId, fields: state.fields),
|
||||
floating: true,
|
||||
pinned: true,
|
||||
return SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
controller: widget.anchorScrollController,
|
||||
child: SizedBox(height: GridSize.headerHeight, child: _GridHeader(gridId: widget.gridId)),
|
||||
);
|
||||
|
||||
// return SliverPersistentHeader(
|
||||
// delegate: SliverHeaderDelegateImplementation(gridId: gridId, fields: state.fields),
|
||||
// floating: true,
|
||||
// pinned: true,
|
||||
// );
|
||||
},
|
||||
),
|
||||
);
|
||||
@ -46,7 +62,7 @@ class SliverHeaderDelegateImplementation extends SliverPersistentHeaderDelegate
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
|
||||
return _GridHeader(gridId: gridId, fields: fields);
|
||||
return _GridHeader(gridId: gridId);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -66,13 +82,7 @@ class SliverHeaderDelegateImplementation extends SliverPersistentHeaderDelegate
|
||||
|
||||
class _GridHeader extends StatefulWidget {
|
||||
final String gridId;
|
||||
final List<Field> fields;
|
||||
|
||||
const _GridHeader({
|
||||
Key? key,
|
||||
required this.gridId,
|
||||
required this.fields,
|
||||
}) : super(key: key);
|
||||
const _GridHeader({Key? key, required this.gridId}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<_GridHeader> createState() => _GridHeaderState();
|
||||
@ -93,15 +103,17 @@ class _GridHeaderState extends State<_GridHeader> {
|
||||
|
||||
return Container(
|
||||
color: theme.surface,
|
||||
child: ReorderableRow(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
scrollController: ScrollController(),
|
||||
header: const _CellLeading(),
|
||||
footer: _CellTrailing(gridId: widget.gridId),
|
||||
onReorder: (int oldIndex, int newIndex) {
|
||||
Log.info("from $oldIndex to $newIndex");
|
||||
},
|
||||
children: cells,
|
||||
child: RepaintBoundary(
|
||||
child: ReorderableRow(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
scrollController: ScrollController(),
|
||||
header: const _CellLeading(),
|
||||
footer: _CellTrailing(gridId: widget.gridId),
|
||||
onReorder: (int oldIndex, int newIndex) {
|
||||
Log.info("from $oldIndex to $newIndex");
|
||||
},
|
||||
children: cells,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
@ -653,6 +653,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.4.0"
|
||||
linked_scroll_controller:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: linked_scroll_controller
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
lint:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -75,6 +75,7 @@ dependencies:
|
||||
fluttertoast: ^8.0.8
|
||||
table_calendar: ^3.0.5
|
||||
reorderables:
|
||||
linked_scroll_controller: ^0.2.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_lints: ^1.0.0
|
||||
|
Loading…
Reference in New Issue
Block a user