Skip to content

Commit

Permalink
优化了CupertinoPopover的动画
Browse files Browse the repository at this point in the history
  • Loading branch information
Im-Kevin committed Oct 27, 2018
1 parent 91f7e51 commit 419141d
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 57 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## [0.0.1] - TODO: Add release date.

* TODO: Describe initial release.

## [0.0.9] - TODO: 修改了CupertionPopover动画

* TODO: 修改了修改了CupertionPopover动画,添加了CupertinoPopoverMenuItem控件
2 changes: 0 additions & 2 deletions cool_ui.iml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
<excludeFolder url="file://$MODULE_DIR$/example/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/example/.pub" />
<excludeFolder url="file://$MODULE_DIR$/example/build" />
<excludeFolder url="file://$MODULE_DIR$/example/build/app/intermediates/flutter/debug/flutter_assets/packages" />
<excludeFolder url="file://$MODULE_DIR$/example/build/app/intermediates/merged_assets/debug/mergeDebugAssets/out/flutter_assets/packages" />
</content>
<orderEntry type="jdk" jdkName="Android API 25 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
Expand Down
3 changes: 2 additions & 1 deletion example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ dependencies:
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.2
cool_ui: ^0.0.7
cool_ui:
path: ../

dev_dependencies:
flutter_test:
Expand Down
85 changes: 31 additions & 54 deletions lib/popover/cupertino_popover.dart
Original file line number Diff line number Diff line change
Expand Up @@ -99,22 +99,20 @@ class CupertinoPopoverState extends State<CupertinoPopover> with TickerProvider
static const double _arrowWidth = 26.0;
static const double _arrowHeight = 13.0;

double left;
double top;
Rect _arrowRect;
Rect _bodyRect;
Rect _currentArrowRect;
Rect _currentBodyRect;
double _currentRadius;
Animation<double> doubleAnimation;
AnimationController animation;

/// 是否箭头向上
bool get isArrowUp{
return ScreenUtil.screenHeight > widget.attachRect.bottom + widget.height + _arrowWidth;
}
bool isArrowUp;

@override
void initState() {
// TODO: implement initState
isArrowUp = ScreenUtil.screenHeight > widget.attachRect.bottom + widget.height + _arrowWidth;
super.initState();
calcRect();
animation = new AnimationController(
Expand All @@ -123,34 +121,39 @@ class CupertinoPopoverState extends State<CupertinoPopover> with TickerProvider
);
// Tween({T begin, T end }):创建tween(补间)
doubleAnimation = new Tween<double>(begin: 0.0, end: 1.0).animate(animation)..addListener((){
setState(calcAnimationRect);
setState((){});
});
animation.forward(from: 0.0);
}

@override
Widget build(BuildContext context) {
var left = _bodyRect.left;
var top = isArrowUp?_arrowRect.top:_bodyRect.top;

var bodyMiddleX = _bodyRect.left + _bodyRect.width / 2; // 计算Body的X轴中间点
var arrowMiddleX = _arrowRect.left + _arrowRect.width /2; //计算箭头的X轴中间点
var leftOffset = (arrowMiddleX - bodyMiddleX) * (1 - doubleAnimation.value); //计算X轴缩小的偏移值
return Stack(
children: <Widget>[
Positioned(
left:left,
left:left + leftOffset,
top:top,
child: ClipPath(
clipper:ArrowCliper(
arrowRect: _currentArrowRect,
bodyRect: _currentBodyRect,
isArrowUp: isArrowUp,
radius: _currentRadius
),
child: Container(
padding: EdgeInsets.only(top:isArrowUp?_arrowHeight:0.0),
color: Colors.white,
width: widget.width,
height: _bodyRect.height + _arrowHeight,
child: Material(child: widget.child)
),
child:ScaleTransition(
alignment: isArrowUp?Alignment.topCenter:Alignment.bottomCenter,
scale: doubleAnimation,
child: ClipPath(
clipper:ArrowCliper(
arrowRect:_arrowRect,
bodyRect: _bodyRect,
isArrowUp: isArrowUp,
radius: widget.radius
),
child: Container(
padding: EdgeInsets.only(top:isArrowUp?_arrowHeight:0.0),
color: Colors.white,
width: widget.width,
height: _bodyRect.height + _arrowHeight,
child: Material(child: widget.child)
),),
),
)
]
Expand Down Expand Up @@ -179,37 +182,11 @@ class CupertinoPopoverState extends State<CupertinoPopover> with TickerProvider
arrowTop = widget.attachRect.top - _arrowHeight;
bodyTop = widget.attachRect.top - widget.height - _arrowHeight;
}
_arrowRect = Rect.fromLTWH(arrowLeft, arrowTop, _arrowWidth, _arrowHeight);
_bodyRect = Rect.fromLTWH(bodyLeft, bodyTop, widget.width, widget.height);
}

calcAnimationRect(){
var top = isArrowUp?_arrowRect.top:_bodyRect.top;

var middleX = (_arrowRect.left - _bodyRect.left) + _arrowRect.width /2;
var arrowLeft = middleX + ((_arrowRect.left - _bodyRect.left) - middleX) * doubleAnimation.value;
var arrowTop = _arrowRect.top - top;
var bodyLeft = middleX + (0 - middleX) * doubleAnimation.value;
_currentRadius = widget.radius * doubleAnimation.value;
var bodyTop = _bodyRect.top - top;

if(isArrowUp){
bodyTop = arrowTop + _arrowRect.height * doubleAnimation.value ;
}else{
arrowTop += _arrowRect.height *(1 - doubleAnimation.value) ;
bodyTop = arrowTop - _bodyRect.height * doubleAnimation.value ;
}

_currentArrowRect = Rect.fromLTWH(
arrowLeft,
arrowTop,
_arrowRect.width * doubleAnimation.value,
_arrowRect.height * doubleAnimation.value);
_currentBodyRect = Rect.fromLTWH(
bodyLeft,
bodyTop,
_bodyRect.width * doubleAnimation.value,
_bodyRect.height * doubleAnimation.value);
left = bodyLeft;
top = isArrowUp?arrowTop:bodyTop;
_arrowRect = Rect.fromLTWH(arrowLeft - left, arrowTop - top, _arrowWidth, _arrowHeight);
_bodyRect = Rect.fromLTWH(0.0, bodyTop - top, widget.width, widget.height);
}
}

Expand Down
5 changes: 5 additions & 0 deletions lib/popover/cupertino_popover_menu_item.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import 'package:flutter/material.dart';

class CupertinoPopoverMenuItem extends StatelessWidget{
final Widget leading;
final Widget child;

const CupertinoPopoverMenuItem({this.leading,this.child});



@override
Expand Down

0 comments on commit 419141d

Please sign in to comment.