Skip to content

Commit

Permalink
add AdjustBuilder
Browse files Browse the repository at this point in the history
  • Loading branch information
xdd666t committed Oct 6, 2024
1 parent bccd733 commit d1cc768
Show file tree
Hide file tree
Showing 10 changed files with 128 additions and 37 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* Break change
* Delete CompatibleSmartDialog
* Delete SmartConfigCustom/SmartConfigAttach/SmartConfigLoading backDismiss
* Add AdjustBuilder

* # [4.9.7+x]
* optimize bindWidget, when bindWidget is not null, bindPage will be automatically set to false.
Expand Down
3 changes: 3 additions & 0 deletions lib/flutter_smart_dialog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ export 'src/config/smart_config_loading.dart';
export 'src/config/smart_config_notify.dart';
export 'src/config/smart_config_toast.dart';
export 'src/data/animation_param.dart' show AnimationParam;

/// model
export 'src/data/attach_model.dart';
export 'src/data/notify_style.dart';

/// dialog
Expand Down
2 changes: 2 additions & 0 deletions lib/src/custom/custom_dialog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ class CustomDialog extends BaseDialog {
required Widget widget,
required TargetBuilder? targetBuilder,
required ReplaceBuilder? replaceBuilder,
required AdjustBuilder? adjustBuilder,
required Alignment alignment,
required bool usePenetrate,
required bool useAnimation,
Expand Down Expand Up @@ -149,6 +150,7 @@ class CustomDialog extends BaseDialog {
widget: widget,
targetBuilder: targetBuilder,
replaceBuilder: replaceBuilder,
adjustBuilder: adjustBuilder,
alignment: alignment,
usePenetrate: usePenetrate,
useAnimation: useAnimation,
Expand Down
2 changes: 2 additions & 0 deletions lib/src/custom/main_dialog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ class MainDialog {
required Widget widget,
required TargetBuilder? targetBuilder,
required ReplaceBuilder? replaceBuilder,
required AdjustBuilder? adjustBuilder,
required Alignment alignment,
required bool usePenetrate,
required bool useAnimation,
Expand All @@ -111,6 +112,7 @@ class MainDialog {
targetContext: targetContext,
targetBuilder: targetBuilder,
replaceBuilder: replaceBuilder,
adjustBuilder: adjustBuilder,
controller: _controller = AttachDialogController(),
alignment: alignment,
usePenetrate: usePenetrate,
Expand Down
28 changes: 28 additions & 0 deletions lib/src/data/attach_model.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import 'package:flutter/cupertino.dart';

class AttachParam {
const AttachParam({
required this.targetOffset,
required this.targetSize,
required this.selfWidget,
required this.selfOffset,
required this.selfSize,
});

final Offset targetOffset;
final Size targetSize;

final Widget selfWidget;
final Offset selfOffset;
final Size selfSize;
}

class AttachAdjustParam {
const AttachAdjustParam({
this.builder,
this.alignment,
});

final WidgetBuilder? builder;
final Alignment? alignment;
}
2 changes: 2 additions & 0 deletions lib/src/helper/dialog_proxy.dart
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ class DialogProxy {
required Widget widget,
required TargetBuilder? targetBuilder,
required ReplaceBuilder? replaceBuilder,
required AdjustBuilder? adjustBuilder,
required Alignment alignment,
required bool usePenetrate,
required bool useAnimation,
Expand Down Expand Up @@ -236,6 +237,7 @@ class DialogProxy {
widget: widget,
targetBuilder: targetBuilder,
replaceBuilder: replaceBuilder,
adjustBuilder: adjustBuilder,
alignment: alignment,
usePenetrate: usePenetrate,
useAnimation: useAnimation,
Expand Down
20 changes: 13 additions & 7 deletions lib/src/smart_dialog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -232,10 +232,12 @@ class SmartDialog {
///
/// [builder]:the custom dialog
///
/// [replaceBuilder]:The widget returned in [replaceBuilder] will replace the widget returned in [builder];
/// [replaceBuilder] will callback the offset and size of the target widget and the offset and size of the dialog itself.
/// [replaceBuilder]:deprecated, please use adjustBuilder
///
/// [adjustBuilder]:The widget returned in [adjustBuilder] will replace the widget returned in [builder];
/// [adjustBuilder] will callback the offset and size of the target widget and the offset and size of the dialog itself.
/// You can customize a suitable replacement widget according to these parameters.
/// It is strongly recommended that the width and height of the custom widget returned by [replaceBuilder] should be consistent with that in [builder],
/// It is strongly recommended that the width and height of the custom widget returned by [adjustBuilder] should be consistent with that in [builder],
/// and the positioning information in showAttach is calculated based on the widget in [builder].
///
/// [controller]:this controller can be used to refresh the layout of the custom dialog
Expand Down Expand Up @@ -326,9 +328,11 @@ class SmartDialog {
///
/// [builder]:自定义 dialog
///
/// [replaceBuilder][replaceBuilder]中返回widget会替换掉[builder]中返回的widget;
/// [replaceBuilder]将回调目标widget的坐标,大小和dialog自身的坐标,大小,你可以根据这些参数,重新自定义一个合适的替换widget,
/// 强烈建议[replaceBuilder]返回的自定义的widget宽高和[builder]中的保持一致, showAttach中定位信息都是根据[builder]中widget计算得来的
/// [replaceBuilder]:已废弃, 请使用adjustBuilder
///
/// [adjustBuilder][adjustBuilder]中返回widget会替换掉[builder]中返回的widget;
/// [adjustBuilder]将回调目标widget的坐标,大小和dialog自身的坐标,大小,你可以根据这些参数,重新自定义一个合适的替换widget,
/// 强烈建议[adjustBuilder]返回的自定义的widget宽高和[builder]中的保持一致, showAttach中定位信息都是根据[builder]中widget计算得来的
///
/// [controller]:可使用该控制器来刷新自定义的dialog的布局
///
Expand Down Expand Up @@ -401,7 +405,8 @@ class SmartDialog {
static Future<T?> showAttach<T>({
required BuildContext? targetContext,
required WidgetBuilder builder,
ReplaceBuilder? replaceBuilder,
@Deprecated("Please use adjustBuilder") ReplaceBuilder? replaceBuilder,
AdjustBuilder? adjustBuilder,
SmartDialogController? controller,
TargetBuilder? targetBuilder,
Alignment? alignment,
Expand Down Expand Up @@ -452,6 +457,7 @@ class SmartDialog {
),
targetBuilder: targetBuilder,
replaceBuilder: replaceBuilder,
adjustBuilder: adjustBuilder,
alignment: alignment ?? config.attach.alignment,
clickMaskDismiss: clickMaskDismiss ?? config.attach.clickMaskDismiss,
animationType: animationType ?? config.attach.animationType,
Expand Down
55 changes: 46 additions & 9 deletions lib/src/widget/attach_dialog_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ typedef ReplaceBuilder = Widget Function(
Size selfSize,
);

typedef AdjustBuilder = AttachAdjustParam Function(AttachParam attachParam);

typedef ScalePointBuilder = Offset Function(Size selfSize);

class AttachDialogWidget extends StatefulWidget {
Expand All @@ -39,6 +41,7 @@ class AttachDialogWidget extends StatefulWidget {
required this.targetContext,
required this.targetBuilder,
required this.replaceBuilder,
required this.adjustBuilder,
required this.controller,
required this.animationTime,
required this.useAnimation,
Expand All @@ -64,6 +67,8 @@ class AttachDialogWidget extends StatefulWidget {

final ReplaceBuilder? replaceBuilder;

final AdjustBuilder? adjustBuilder;

/// 是否使用动画
final bool useAnimation;

Expand Down Expand Up @@ -186,8 +191,8 @@ class _AttachDialogWidgetState extends State<AttachDialogWidget>
beforeBuilder: beforeBuilder,
alignment: widget.alignment,
originChild: _child,
builder: (Widget child) {
return _buildBodyAnimation(child);
builder: (Widget child, AttachAdjustParam? adjustParam) {
return _buildBodyAnimation(child, adjustParam);
},
belowBuilder: (targetOffset, targetSize) {
return [
Expand Down Expand Up @@ -219,12 +224,14 @@ class _AttachDialogWidgetState extends State<AttachDialogWidget>
);
}

Widget beforeBuilder(
AttachAdjustParam beforeBuilder(
Offset targetOffset,
Size targetSize,
Offset selfOffset,
Size selfSize,
) {
AttachAdjustParam? adjustParam;

//替换控件builder
if (widget.replaceBuilder != null) {
Widget replaceChildBuilder() {
Expand All @@ -247,6 +254,32 @@ class _AttachDialogWidgetState extends State<AttachDialogWidget>
}
}

// 处理调整组件
if (widget.adjustBuilder != null) {
adjustParam = widget.adjustBuilder!(
AttachParam(
targetOffset: targetOffset,
targetSize: targetSize,
selfWidget: widget.child,
selfOffset: selfOffset,
selfSize: selfSize,
),
);

final WidgetBuilder? adjustWidgetBuilder = adjustParam.builder;
if (adjustWidgetBuilder != null) {
// 必须要写在DialogScope的builder之外,保证在scalePointBuilder之前触发adjustBuilder
adjustWidgetBuilder(context);
//保证controller能刷新replaceBuilder
if (widget.child is DialogScope) {
_child = DialogScope(
controller: (widget.child as DialogScope).controller,
builder: (context) => adjustWidgetBuilder(context),
);
}
}
}

//缩放动画的缩放点
if (widget.scalePointBuilder != null) {
var halfWidth = selfSize.width / 2;
Expand All @@ -259,16 +292,20 @@ class _AttachDialogWidgetState extends State<AttachDialogWidget>
_scaleAlignment = Alignment(rateX, rateY);
}

return _child;
return AttachAdjustParam(
alignment: adjustParam?.alignment ?? widget.alignment,
builder: (context) => _child,
);
}

Widget _buildBodyAnimation(Widget child) {
Widget _buildBodyAnimation(Widget child, AttachAdjustParam? adjustParam) {
var alignment = adjustParam?.alignment ?? widget.alignment;
if (widget.animationBuilder != null) {
return widget.animationBuilder!.call(
_bodyController,
child,
_animationParam = AnimationParam(
alignment: widget.alignment,
alignment: alignment,
animationTime: widget.animationTime,
),
);
Expand All @@ -282,7 +319,7 @@ class _AttachDialogWidgetState extends State<AttachDialogWidget>
child: child,
);
Widget size = SizeAnimation(
alignment: widget.alignment,
alignment: alignment,
controller: _bodyController,
child: child,
);
Expand All @@ -294,13 +331,13 @@ class _AttachDialogWidgetState extends State<AttachDialogWidget>
} else if (type == SmartAnimationType.scale) {
animation = scale;
} else if (type == SmartAnimationType.centerFade_otherSlide) {
if (widget.alignment == Alignment.center) {
if (alignment == Alignment.center) {
animation = fade;
} else {
animation = size;
}
} else if (type == SmartAnimationType.centerScale_otherSlide) {
if (widget.alignment == Alignment.center) {
if (alignment == Alignment.center) {
animation = scale;
} else {
animation = size;
Expand Down
50 changes: 30 additions & 20 deletions lib/src/widget/helper/attach_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ import 'package:flutter_smart_dialog/src/kit/view_utils.dart';

import '../attach_dialog_widget.dart';

typedef AttachBuilder = Widget Function(Widget child);
typedef AttachBuilder = Widget Function(
Widget child,
AttachAdjustParam? adjustParam,
);

typedef BeforeBuilder = Widget Function(
typedef BeforeBuilder = AttachAdjustParam Function(
Offset targetOffset,
Size targetSize,
Offset selfOffset,
Expand Down Expand Up @@ -37,7 +40,7 @@ class AttachWidget extends StatefulWidget {
/// 自定义坐标点
final TargetBuilder? targetBuilder;

final BeforeBuilder? beforeBuilder;
final BeforeBuilder beforeBuilder;

final Alignment alignment;

Expand All @@ -63,10 +66,13 @@ class _AttachWidgetState extends State<AttachWidget> {
BuildContext? _childContext;
late Widget _originChild;

late Alignment _alignment;
AttachAdjustParam? _adjustParam;

@override
void initState() {
_alignment = widget.alignment;
_resetState();

super.initState();
}

Expand Down Expand Up @@ -99,7 +105,7 @@ class _AttachWidgetState extends State<AttachWidget> {
right: _targetRect?.right,
top: _targetRect?.top,
bottom: _targetRect?.bottom,
child: widget.builder(child),
child: widget.builder(child, _adjustParam),
),

//above
Expand Down Expand Up @@ -137,7 +143,7 @@ class _AttachWidgetState extends State<AttachWidget> {
final screen = MediaQuery.of(context).size;

//动画方向及其位置
final alignment = widget.alignment;
final alignment = _alignment;

if (alignment == Alignment.topLeft) {
_targetRect = _adjustReactInfo(
Expand Down Expand Up @@ -199,20 +205,24 @@ class _AttachWidgetState extends State<AttachWidget> {
);
}

if (widget.beforeBuilder != null) {
_originChild = widget.beforeBuilder!.call(
targetOffset,
targetSize,
Offset(
_targetRect?.left != null
? _targetRect!.left!
: screen.width - ((_targetRect?.right ?? 0) + selfSize.width),
_targetRect?.top != null
? _targetRect!.top!
: screen.height - ((_targetRect?.bottom ?? 0) + selfSize.height),
),
selfSize,
);
AttachAdjustParam adjustParam = _adjustParam = widget.beforeBuilder.call(
targetOffset,
targetSize,
Offset(
_targetRect?.left != null
? _targetRect!.left!
: screen.width - ((_targetRect?.right ?? 0) + selfSize.width),
_targetRect?.top != null
? _targetRect!.top!
: screen.height - ((_targetRect?.bottom ?? 0) + selfSize.height),
),
selfSize,
);
_originChild = adjustParam.builder?.call(context) ?? _originChild;
if (_alignment != adjustParam.alignment) {
_alignment = adjustParam.alignment ?? Alignment.center;
_handleLocation();
return;
}

//第一帧后恢复透明度,同时重置位置信息
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ description:
An elegant Flutter Dialog solution,
Easily implement Toast, Loading and custom Dialog,
Make the use of the dialog easier!
version: 4.9.8+2
version: 4.9.8+3
homepage: https://github.com/fluttercandies/flutter_smart_dialog
# flutter pub publish --server=https://pub.dartlang.org
# flutter build web --release --base-href="/flutter_smart_dialog/web/"
Expand Down

0 comments on commit d1cc768

Please sign in to comment.