android仿美团底部导航栏的点击效果——揭露动画
来源:互联网 发布:office mac 2016 密码 编辑:程序博客网 时间:2024/06/05 05:38
又是划水的一天好开心,无聊逛了逛美团,喜欢上美团底部导航栏的点击效果。感觉在哪里见过,又想不起来,后来一波百度,发现就是安卓5.0的揭露动画createCircularReveal。
什么事揭露动画,参考http://www.itdadao.com/articles/c15a1442955p0.html。
看到没,大概就是这种动画效果,用的好的话,这种效果其实会很可爱。
于是,我快速的加入新建demo中,
// 显示if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { /** * createCircularReveal 方法参数 * view 执行动画的view * centerX 圆心横坐标 * centerY 圆心纵坐标 * startRadius 动画开始时圆的半径 * endRadius 动画结束时圆的半径 */ final Animator animator = ViewAnimationUtils.createCircularReveal(animateView, animateView.getWidth() / 2, animateView.getHeight() / 2, 0, (float) Math.hypot(animateView.getWidth(), animateView.getHeight())); // Math.hypot确定圆的半径(算长宽的斜边长,这样半径不会太短也不会很长效果比较舒服) animatorHide.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { animateView.setVisibility(View.VISIBLE); } @Override public void onAnimationEnd(Animator animation) { } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }); animatorHide.setDuration(5000); animatorHide.start();} else { animateView.setVisibility(View.VISIBLE);}animateView.setEnabled(true);
使用时直接调用:
CircleAnimateUtils.handleAnimate(iv);
这样仿美团底部导航栏的点击动画就实现了,超简单吧。
接着无聊。。。发现揭露动画效果只能实现在5.0以上的手机,5.0以下的没有这个效果。如果是我做的话,5.0以下就不管了,但是美团没有这么懒,成功实现5.0以下的揭露动画。
究竟是如何实现的,本大王不服,噼里啪啦百度一波,发现了一个可爱的第三方:
https://github.com/zhangke3016/TranslationCompat
里面的CircularRevealLayout直接拖过来用了:
public class CircularRevealLayout extends FrameLayout { private Path path; private float centerX; private float centerY; private float revealRadius; private boolean isRunning; private View childView; private float startRadius; private float endRadius; public CircularRevealLayout(Context context) { this(context, null); } public CircularRevealLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CircularRevealLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); path = new Path(); } public void setChildView(View childView) { this.childView = childView; } public void setCenterX(float centerX) { this.centerX = centerX; } public void setCenterY(float centerY) { this.centerY = centerY; } public void setStartRadius(float startRadius) { this.startRadius = startRadius; } public void setEndRadius(float endRadius) { this.endRadius = endRadius; } public void setRevealRadius(float revealRadius) { this.revealRadius = revealRadius; invalidate(); } public Animator getAnimator() { ObjectAnimator reveal = ObjectAnimator.ofFloat(this, "revealRadius", startRadius, endRadius); reveal.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animator) { animationStart(animator); } @Override public void onAnimationEnd(Animator animator) { animationEnd(animator); } @Override public void onAnimationCancel(Animator animator) { animationCancel(animator); } @Override public void onAnimationRepeat(Animator animator) { } }); return reveal; } private void animationStart(Animator animator) { isRunning = true; } private void animationEnd(Animator animator) { isRunning = false; } private void animationCancel(Animator animator) { isRunning = false; } @Override protected boolean drawChild(Canvas canvas, View child, long drawingTime) { if (isRunning && childView == child) { final int state = canvas.save(); path.reset(); path.addCircle(centerX, centerY, revealRadius, Path.Direction.CW); canvas.clipPath(path); boolean isInvalided = super.drawChild(canvas, child, drawingTime); canvas.restoreToCount(state); return isInvalided; } return super.drawChild(canvas, child, drawingTime); } public static class Builder { private View view; private float centerX; private float centerY; private float startRadius; private float endRadius; public Builder(View view) { this.view = view; } public static Builder on(View view) { return new Builder(view); } public Builder centerX(float centerX) { this.centerX = centerX; return this; } public Builder centerY(float centerY) { this.centerY = centerY; return this; } public Builder startRadius(float startRadius) { this.startRadius = startRadius; return this; } public Builder endRadius(float endRadius) { this.endRadius = endRadius; return this; } private void setParameter(CircularRevealLayout layout) { layout.setCenterX(centerX); layout.setCenterY(centerY); layout.setStartRadius(startRadius); layout.setEndRadius(endRadius); layout.setChildView(view); } public Animator create() { if (view.getParent() != null && view.getParent() instanceof CircularRevealLayout) { CircularRevealLayout layout = ((CircularRevealLayout) view.getParent()); setParameter(layout); return layout.getAnimator(); } CircularRevealLayout layout = new CircularRevealLayout(view.getContext()); if (Build.VERSION.SDK_INT >= 11) { layout.setLayerType(View.LAYER_TYPE_SOFTWARE, null); } setParameter(layout); ViewGroup.LayoutParams params = view.getLayoutParams(); ViewGroup parent = (ViewGroup) view.getParent(); int index = 0; if (parent != null) { index = parent.indexOfChild(view); parent.removeView(view); } layout.addView(view, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)); if (parent != null) { parent.addView(layout, index, params); } return layout.getAnimator(); } }}
牛逼吧,反正我暂时还不会写,只会copy.
public class CircleAnimateUtils { public static void handleAnimate(final View animateView) { Animator animator = CircularRevealLayout.Builder.on(animateView) .centerX(animateView.getWidth() / 2) .centerY(animateView.getHeight() / 2) .startRadius(0) .endRadius((float) Math.hypot(animateView.getWidth(), animateView.getHeight())) .create(); mAnimator.setDuration(5000); mAnimator.setInterpolator(new AccelerateDecelerateInterpolator()); mAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); } @Override public void onAnimationStart(Animator animation) { animateView.setVisibility(View.VISIBLE); super.onAnimationStart(animation); } }); mAnimator.start(); } }
使用的时候直接调用 CircleAnimateUtils.handleAnimate(iv);
源码:https://github.com/jjjSilence/jjjPlus/tree/%E5%B0%81%E8%A3%85
仿美团底部导航栏点击——揭露动画
阅读全文
0 0
- android仿美团底部导航栏的点击效果——揭露动画
- Android点击水纹效果和QQ拖拽效果的底部导航栏
- JFTabBar android强大的底部导航栏框架 (微信底部导航栏效果)
- android底部导航栏中间凸起效果的制作
- android效果TapBarMenu绘制底部导航栏的使用方式
- 实现android studio底部导航栏四个标签的效果
- Android WebView 滚动方向判断同时底部导航栏隐藏或显示(动画效果)
- viewpager的setCurrentItem 底部导航栏点击按钮实现直接跳转,去掉滑动效果
- Android——BottomNavigationBar底部导航栏的快速实现
- ANDROID底部导航栏的实现(一)— BottomNavigationBar
- android BottomNavigationBar——底部导航栏
- Android底部导航栏—RadioButton+Fragment
- Android底部导航栏—FragmentTabHost+Fragment
- 揭露动画—ViewAnimationUtils.createCircularReveal
- Android 使用Circular Reveal为你的应用添加揭露动画效果
- Android 底部导航条切换高亮的效果实现
- Android 创建CircularReveal揭露动画的实现
- android仿微信底部导航栏图标渐变效果
- C语言
- LintCode C++代码 余弦相似度;
- SMS短信的PDU编码解码,附java解码源码
- python自定义一个非常简易的模块
- SSH和SSM框架的区别
- android仿美团底部导航栏的点击效果——揭露动画
- CSS选择器
- 持有对象
- 【Unity】安装配置Python使用protobuf转换Excel表格数据并在unit中使用
- maven POM.xml 标签详解
- 第六场选拔 Problem G: 素数对 水
- Java数据类型和MySql数据类型对应表
- UsbCamera V4L2自动适配分辨率720和480p
- 高仿2017手机QQ