Files
henryjin 911cedcc29 feat(voltron): fix voltron events binding (#2828)
* feat(voltron): fix voltron events binding

* feat(voltron): fix toDeepVoltronMap func

* feat(voltron): update voltron version

* feat(voltron): fix voltron workerManager destroy
2023-01-03 16:33:26 +08:00

347 lines
13 KiB
Dart

//
// Tencent is pleased to support the open source community by making
// Hippy available.
//
// Copyright (C) 2022 THL A29 Limited, a Tencent company.
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import 'package:flutter/widgets.dart';
// ignore: import_of_legacy_library_into_null_safe
import 'package:pull_to_refresh/pull_to_refresh.dart';
import '../common.dart';
import '../controller.dart';
import '../gesture.dart';
import '../render.dart';
import '../style.dart';
import '../util.dart';
import '../viewmodel.dart';
import '../widget.dart';
typedef RefreshWrapperDelegate = RefreshConfiguration Function({
required BuildContext context,
required Widget child,
RenderViewModel? footerModel,
});
class ListViewController extends BaseGroupController<ListViewModel> {
static const String kClassName = "ListView";
/// func
static const kFuncScrollToIndex = "scrollToIndex";
static const kFuncScrollToContentOffset = "scrollToContentOffset";
/// 3.0 bind events
static const String kEventOnScroll = "scroll";
static const String kEventOnMomentumScrollBegin = "momentumscrollbegin";
static const String kEventOnMomentumScrollEnd = "momentumscrollend";
static const String kEventOnScrollBeginDrag = "scrollbegindrag";
static const String kEventOnScrollEndDrag = "scrollenddrag";
static const String kEventOnEndReached = "endreached";
static const String kEventOnAppear = "appear";
static const String kEventOnDisAppear = "disappear";
static const String kEventOnWillAppear = "willappear";
static const String kEventOnWillDisAppear = "willdisappear";
@override
Widget createWidget(BuildContext context, ListViewModel viewModel) {
return ListViewWidget(viewModel);
}
@override
ListViewModel createRenderViewModel(RenderNode node, RenderContext context) {
return ListViewModel(node.id, node.rootId, node.name, context);
}
@override
String get name => kClassName;
@override
Map<String, ControllerMethodProp> get groupExtraMethodProp => {
NodeProps.kRowShouldSticky: ControllerMethodProp(setRowShouldSticky, false),
NodeProps.kHorizontal: ControllerMethodProp(setHorizontal, false),
NodeProps.kScrollEnable: ControllerMethodProp(setScrollEnable, true),
NodeProps.kScrollEventThrottle: ControllerMethodProp(setScrollEventThrottle, 30),
NodeProps.kShowScrollIndicator: ControllerMethodProp(setShowScrollIndicator, false),
NodeProps.kPreloadItemSize: ControllerMethodProp(setPreloadItemSize, 0.0),
NodeProps.kInitContentOffset: ControllerMethodProp(setInitContentOffset, 0.0),
NodeProps.kPreloadItemNumber: ControllerMethodProp(setPreloadItemNumber, 0),
NodeProps.kBounces: ControllerMethodProp(setBounces, true),
NodeProps.kOverScrollEnabled: ControllerMethodProp(setOverScrollEnabled, true),
NodeProps.kPaddingTop: ControllerMethodProp(setPaddingTop, 0.0),
NodeProps.kPaddingRight: ControllerMethodProp(setPaddingRight, 0.0),
NodeProps.kPaddingBottom: ControllerMethodProp(setPaddingBottom, 0.0),
NodeProps.kPaddingLeft: ControllerMethodProp(setPaddingLeft, 0.0),
// 2.0 bind events
NodeProps.kOnScrollEnable: ControllerMethodProp(setScrollEventEnable, false),
NodeProps.kOnScrollBeginDrag: ControllerMethodProp(setScrollBeginDragEventEnable, false),
NodeProps.kOnScrollEndDrag: ControllerMethodProp(setScrollEndDragEventEnable, false),
NodeProps.kOnMomentumScrollBegin:
ControllerMethodProp(setMomentumScrollBeginEventEnable, false),
NodeProps.kOnMomentumScrollEnd:
ControllerMethodProp(setMomentumScrollEndEventEnable, false),
NodeProps.kOnEndReached: ControllerMethodProp(setOnEndReached, true),
NodeProps.kOnAppear: ControllerMethodProp(setOnAppear, true),
NodeProps.kOnDisAppear: ControllerMethodProp(setOnDisAppear, true),
NodeProps.kOnWillAppear: ControllerMethodProp(setOnWillAppear, true),
NodeProps.kOnWillDisAppear: ControllerMethodProp(setOnWillDisAppear, true),
};
@ControllerProps(NodeProps.kRowShouldSticky)
void setRowShouldSticky(ListViewModel renderViewModel, bool enable) {
renderViewModel.hasStickyItem = enable;
}
@ControllerProps(NodeProps.kHorizontal)
void setHorizontal(ListViewModel renderViewModel, bool enable) {
renderViewModel.horizontal = enable;
}
@ControllerProps(NodeProps.kShowScrollIndicator)
void setShowScrollIndicator(ListViewModel renderViewModel, bool enable) {
renderViewModel.showScrollIndicator = enable;
}
@ControllerProps(NodeProps.kScrollEnable)
void setScrollEnable(ListViewModel renderViewModel, bool flag) {
renderViewModel.scrollGestureDispatcher.scrollEnable = flag;
}
@ControllerProps(NodeProps.kScrollEventThrottle)
void setScrollEventThrottle(ListViewModel renderViewModel, int scrollEventThrottle) {
renderViewModel.scrollGestureDispatcher.scrollEventThrottle = scrollEventThrottle;
}
@ControllerProps(NodeProps.kPreloadItemSize)
void setPreloadItemSize(ListViewModel renderViewModel, double preloadItemSize) {
renderViewModel.preloadSize = preloadItemSize;
}
@ControllerProps(NodeProps.kInitContentOffset)
void setInitContentOffset(ListViewModel renderViewModel, double offset) {
renderViewModel.initOffset = offset;
}
@ControllerProps(NodeProps.kPreloadItemNumber)
void setPreloadItemNumber(ListViewModel renderViewModel, int number) {
var gestureDispatcher = renderViewModel.gestureDispatcher;
if (gestureDispatcher is NativeScrollGestureDispatcher) {
gestureDispatcher.preloadItemNumber = number;
}
}
@ControllerProps(NodeProps.kBounces)
void setBounces(ListViewModel renderViewModel, bool enable) {
renderViewModel.bounces = enable;
}
@ControllerProps(NodeProps.kOverScrollEnabled)
void setOverScrollEnabled(ListViewModel renderViewModel, bool enable) {
renderViewModel.bounces = enable;
}
@ControllerProps(NodeProps.kOnAppear)
void setOnAppear(ListViewModel renderViewModel, bool enable) {
var gestureDispatcher = renderViewModel.gestureDispatcher;
if (gestureDispatcher is NativeScrollGestureDispatcher) {
gestureDispatcher.appearEventEnable = enable;
}
}
@ControllerProps(NodeProps.kOnDisAppear)
void setOnDisAppear(ListViewModel renderViewModel, bool enable) {
var gestureDispatcher = renderViewModel.gestureDispatcher;
if (gestureDispatcher is NativeScrollGestureDispatcher) {
gestureDispatcher.disAppearEventEnable = enable;
}
}
@ControllerProps(NodeProps.kOnWillAppear)
void setOnWillAppear(ListViewModel renderViewModel, bool enable) {
var gestureDispatcher = renderViewModel.gestureDispatcher;
if (gestureDispatcher is NativeScrollGestureDispatcher) {
gestureDispatcher.willAppearEventEnable = enable;
}
}
@ControllerProps(NodeProps.kOnWillDisAppear)
void setOnWillDisAppear(ListViewModel renderViewModel, bool enable) {
var gestureDispatcher = renderViewModel.gestureDispatcher;
if (gestureDispatcher is NativeScrollGestureDispatcher) {
gestureDispatcher.willDisAppearEventEnable = enable;
}
}
@ControllerProps(NodeProps.kPaddingTop)
void setPaddingTop(ListViewModel renderViewModel, Object? paddingTop) {
if (paddingTop is int) {
renderViewModel.paddingTop = paddingTop.toDouble();
} else if (paddingTop is double) {
renderViewModel.paddingTop = paddingTop;
} else {
renderViewModel.paddingTop = 0.0;
}
}
@ControllerProps(NodeProps.kPaddingRight)
void setPaddingRight(ListViewModel renderViewModel, Object? paddingRight) {
if (paddingRight is int) {
renderViewModel.paddingRight = paddingRight.toDouble();
} else if (paddingRight is double) {
renderViewModel.paddingRight = paddingRight;
} else {
renderViewModel.paddingRight = 0.0;
}
}
@ControllerProps(NodeProps.kPaddingBottom)
void setPaddingBottom(ListViewModel renderViewModel, Object? paddingBottom) {
if (paddingBottom is int) {
renderViewModel.paddingBottom = paddingBottom.toDouble();
} else if (paddingBottom is double) {
renderViewModel.paddingBottom = paddingBottom;
} else {
renderViewModel.paddingBottom = 0.0;
}
}
@ControllerProps(NodeProps.kPaddingLeft)
void setPaddingLeft(ListViewModel renderViewModel, Object? paddingLeft) {
if (paddingLeft is int) {
renderViewModel.paddingLeft = paddingLeft.toDouble();
} else if (paddingLeft is double) {
renderViewModel.paddingLeft = paddingLeft;
} else {
renderViewModel.paddingLeft = 0.0;
}
}
/// 2.0 bind events
@ControllerProps(NodeProps.kOnScrollBeginDrag)
void setScrollBeginDragEventEnable(ListViewModel renderViewModel, bool flag) {
renderViewModel.scrollGestureDispatcher.scrollBeginDragEventEnable = flag;
}
@ControllerProps(NodeProps.kOnScrollEndDrag)
void setScrollEndDragEventEnable(ListViewModel renderViewModel, bool flag) {
renderViewModel.scrollGestureDispatcher.scrollEndDragEventEnable = flag;
}
@ControllerProps(NodeProps.kOnMomentumScrollBegin)
void setMomentumScrollBeginEventEnable(
ListViewModel renderViewModel,
bool flag,
) {
renderViewModel.scrollGestureDispatcher.momentumScrollBeginEventEnable = flag;
}
@ControllerProps(NodeProps.kOnMomentumScrollEnd)
void setMomentumScrollEndEventEnable(ListViewModel renderViewModel, bool flag) {
renderViewModel.scrollGestureDispatcher.momentumScrollEndEventEnable = flag;
}
@ControllerProps(NodeProps.kOnScrollEnable)
void setScrollEventEnable(ListViewModel renderViewModel, bool flag) {
renderViewModel.scrollGestureDispatcher.scrollEventEnable = flag;
}
@ControllerProps(NodeProps.kOnEndReached)
void setOnEndReached(ListViewModel renderViewModel, bool flag) {
renderViewModel.scrollGestureDispatcher.endReachedEventEnable = true;
}
@override
void updateEvents(
ListViewModel renderViewModel,
Set<EventHolder> holders,
) {
super.updateEvents(renderViewModel, holders);
if (holders.isNotEmpty) {
for (var holder in holders) {
switch (holder.eventName) {
case kEventOnScroll:
setScrollEventEnable(renderViewModel, holder.isAdd);
break;
case kEventOnScrollBeginDrag:
setScrollBeginDragEventEnable(renderViewModel, holder.isAdd);
break;
case kEventOnScrollEndDrag:
setScrollEndDragEventEnable(renderViewModel, holder.isAdd);
break;
case kEventOnMomentumScrollBegin:
setMomentumScrollBeginEventEnable(renderViewModel, holder.isAdd);
break;
case kEventOnMomentumScrollEnd:
setMomentumScrollEndEventEnable(renderViewModel, holder.isAdd);
break;
case kEventOnEndReached:
setOnEndReached(renderViewModel, holder.isAdd);
break;
case kEventOnAppear:
setOnAppear(renderViewModel, holder.isAdd);
break;
case kEventOnDisAppear:
setOnDisAppear(renderViewModel, holder.isAdd);
break;
case kEventOnWillAppear:
setOnWillAppear(renderViewModel, holder.isAdd);
break;
case kEventOnWillDisAppear:
setOnWillDisAppear(renderViewModel, holder.isAdd);
break;
}
}
}
}
@override
void dispatchFunction(
ListViewModel viewModel,
String functionName,
VoltronArray array, {
Promise? promise,
}) {
super.dispatchFunction(viewModel, functionName, array, promise: promise);
if (functionName == kFuncScrollToIndex) {
// list滑动到某个item
var yIndex = array.get<int>(1) ?? -1;
var animated = array.get<bool>(2) ?? false;
var duration = array.get<int>(3) ?? 0; //1.2.7 增加滚动时间 ms,animated==true时生效
if (duration <= 100) {
// 保证duration最小为100ms
duration = 100;
}
LogUtils.d("list_scroll", "scroll to index:$yIndex");
viewModel.scrollToIndex(yIndex, duration, animated);
} else if (functionName == kFuncScrollToContentOffset) {
// list滑动到某个距离
var yOffset = array.get<double>(1) ?? array.get<int>(1)?.toDouble() ?? 0.0;
var animated = array.get<bool>(2) ?? false;
var duration = array.get<int>(3) ?? 0; //1.2.7 增加滚动时间 ms,animated==true时生效
if (duration <= 100) {
// 保证duration最小为100ms
duration = 100;
}
LogUtils.d("list_scroll", "scroll to offset:$yOffset");
viewModel.scrollToOffset(yOffset, duration, animated);
}
}
}