Android使用Circular Reveal动画让页面跳转更炫酷

Android 5.0中引入了很多炫酷的动画效果,Circular Reveal便是其中一种。使用起来很简单,但效果却是意想不到的炫酷,让你的app更有逼格。

一、效果

废话不说,下面的gif图中使用Circular Reveal动画实现跳转到搜索页的效果。gif图压缩宽高比失真了,不过效果还在。源码在最下面,可以下载体验下。

二、Circular Reveal介绍

当您显示或隐藏一组 UI 元素时,揭露动画可为用户提供视觉连续性。

ViewAnimationUtils.createCircularReveal()方法让您能够为裁剪区域添加动画以揭露或隐藏视图。

/* @param view The View will be clipped to the animating circle.
   * @param centerX The x coordinate of the center of the animating circle, relative to
   *        <code>view</code>.
   * @param centerY The y coordinate of the center of the animating circle, relative to
   *        <code>view</code>.
   * @param startRadius The starting radius of the animating circle.
   * @param endRadius The ending radius of the animating circle.
   */
  public static Animator createCircularReveal(View view,
      int centerX, int centerY, float startRadius, float endRadius) {
    return new RevealAnimator(view, centerX, centerY, startRadius, endRadius);
  }

ViewAnimationUtils.createCircularReveal()方法所执行的效果,就是将一个View裁剪成圆,然后从圆心逐渐揭露展现视图。

参数 参数说明
view 要执行动画效果的View
centerX 圆心x坐标
centerY 圆心y坐标
startRadius 开始时的圆半径
endRadius 结束时的圆半径

三、实现

从上图可以看出,需要揭露展现的View是整个视图的根布局。开始的位置就是🔍图标的x,y坐标。开始的半径为0,结束的半径是上面那条斜边的长度。知道了这些参数,那么实现就简单了。

以下代码使用Kotlin实现,不过和java区别不大,不影响看懂原理。

1.动画参数

@SuppressLint("NewApi")
  private fun actionOtherVisible(isShow: Boolean, triggerView: View, animView: View) {
    //判断API是否大于21
    if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
      if (isShow) {
        animView.visibility = View.VISIBLE
        if (mListener != null) mListener!!.onShowAnimationEnd()
      } else {
        animView.visibility = View.GONE
        if (mListener != null) mListener!!.onHideAnimationEnd()
      }
      return
    }

    /**
     * 计算 triggerView(即搜索按钮) 的中心位置
     */
    val tvLocation = IntArray(2)
    triggerView.getLocationInWindow(tvLocation)
    val tvX = tvLocation[0] + triggerView.width / 2
    val tvY = tvLocation[1] + triggerView.height / 2

    /**
     * 计算 animView(即根布局) 的中心位置
     */
    val avLocation = IntArray(2)
    animView.getLocationInWindow(avLocation)
    val avX = avLocation[0] + animView.width / 2
    val avY = avLocation[1] + animView.height / 2
    //计算宽高
    val rippleW = if (tvX < avX) animView.width - tvX else tvX - avLocation[0]
    val rippleH = if (tvY < avY) animView.height - tvY else tvY - avLocation[1]
    //勾股定理求斜边
    val maxRadius = Math.sqrt((rippleW * rippleW + rippleH * rippleH).toDouble()).toFloat()
    val startRadius: Float
    val endRadius: Float
    //根据展示或隐藏设置起始与结束的半径
    if (isShow) {
      startRadius = 0f
      endRadius = maxRadius
    } else {
      startRadius = maxRadius
      endRadius = 0f
    }

    val anim = ViewAnimationUtils.createCircularReveal(animView, tvX, tvY, startRadius, endRadius)
    animView.visibility = View.VISIBLE
    anim.duration = DURATION
    anim.interpolator = DecelerateInterpolator()
    //监听动画结束,进行回调
    anim.addListener(object : AnimatorListenerAdapter() {
      override fun onAnimationEnd(animation: Animator) {
        super.onAnimationEnd(animation)
        if (isShow) {
          animView.visibility = View.VISIBLE
          if (mListener != null) mListener!!.onShowAnimationEnd()
        } else {
          animView.visibility = View.GONE
          if (mListener != null) mListener!!.onHideAnimationEnd()
        }
      }
    })

    anim.start()
  }

上述代码中注释清楚解析了动画参数的获取和执行过程。

2.动画调用

fun show(triggerView: View, showView: View) {
    actionOtherVisible(true, triggerView, showView)
  }

fun hide(triggerView: View, hideView: View) {
    actionOtherVisible(false, triggerView, hideView)
  }

actionOtherVisible()方法根据传入true/false来确定是执行展示或隐藏动画。

3.动画调用时机

在SearchFragment中,监听第一帧的绘制,开启动画。其中mRootView就是根布局View。

override fun onPreDraw(): Boolean {
    iv_search_search.viewTreeObserver.removeOnPreDrawListener(this);
    mCircularRevealAnim.show(iv_search_search, mRootView);
    return true;
  }

动画结束调用时机:①在点击搜索,跳转到搜索结果界面。②物理回退键回退。③点击回退按钮

再以上三个地方都可以调用hide()方法,实现隐藏动画。

4.监听回调

在上面配置动画参数的过程中,对动画结束进行了监听回调。调用了AnimListener接口的onHideAnimationEnd()和onShowAnimationEnd()方法,来实现回调。所有在SearchFragment中实现该接口,来监听回调。

override fun onHideAnimationEnd() {
  et_search_keyword.setText("");
  dismiss();
}

override fun onShowAnimationEnd() {
  if (isVisible) {
    KeyBoardUtils.openKeyboard(activity, et_search_keyword);
  }
}

监听到隐藏动画结束的时候,调用dismiss()方法关闭该DialogFragment。监听展现动画结束的时候,开启输入法框。

就是这么简单,通过以上方式就可以实现如此炫酷的效果。

Github地址:搜索页Circular Reveal动画

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android使用Intent实现页面跳转

    什么是Intent Intent可以理解为信使(意图) 由Intent来协助完成Android各个组件之间的通讯 Intent实现页面之间的跳转 1>startActivity(intent) 2>startActivityForResult(intent,requestCode) onActivityResult(int requestCode,int resultCode,Intent data) setResult(resultCode,data) 第二种启动方式可以返回结果 代码 Fi

  • Android 实现页面跳转

    android使用Intent来实现页面跳转,Intent通过startActivity(Intent intent)或startActivityForResult(Intent intent,int resquestCode)方法来启动Activity,在新建Intent对象时来指定从A页面跳到B页面, 比如: Intent i = new Intent(A.this,B.class);这就表示从A页面跳到B页面, Intent对象通过调用putExtra方法来传递页面跳转时所需要传递的信息

  • Android编程中Intent实现页面跳转功能详解

    本文实例讲述了Android编程中Intent实现页面跳转功能.分享给大家供大家参考,具体如下: 安卓四大组件:Activity.Service.Broadcast Receiver.Content Provider Intent实现页面之间跳转 1.无返回值 startActivity(intent) 2.有返回值 startActivityForResult(intent,requestCode); onActivityResult(int requestCode,int resultCod

  • Android Activity中使用Intent实现页面跳转与参数传递的方法

    本文实例讲述了Android Activity中使用Intent实现页面跳转与参数传递的方法.分享给大家供大家参考,具体如下: 新建一个FirstAvtivity.java package com.zhuguangwei; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.O

  • Android使用Circular Reveal动画让页面跳转更炫酷

    Android 5.0中引入了很多炫酷的动画效果,Circular Reveal便是其中一种.使用起来很简单,但效果却是意想不到的炫酷,让你的app更有逼格. 一.效果 废话不说,下面的gif图中使用Circular Reveal动画实现跳转到搜索页的效果.gif图压缩宽高比失真了,不过效果还在.源码在最下面,可以下载体验下. 二.Circular Reveal介绍 当您显示或隐藏一组 UI 元素时,揭露动画可为用户提供视觉连续性. ViewAnimationUtils.createCircul

  • Android使用Intent隐式实现页面跳转

    在上一篇文章中我介绍了使用Intent显式来实现页面向下跳转,接下来这篇文章主要介绍的是使用Intent隐式来实现向上跳转,什么意思呢,就是当我们从第一个页面跳转到第二个页面的时候我们可以从第二个页面跳转回去. 通过查阅文档你会发现Activity中还有一个startActivityForResult()方法也是用于启动活动的,但是这个方法期望在活动销毁的时候能返回一个结果给上一个活动,毫无疑问这就是我们所要达到的效果. startActivityForResult()方法接收2个参数,第一个参

  • Android实现单页显示3个Item的ViewPager炫酷切换效果

    单页显示3个Item的ViewPager炫酷切换效果,适用于Banner等. 效果图 Rotate Y Rotate Down Rotate Up Alpha ScaleIn ScaleIn + Alpha + Rotate Down 使用 ###(1)引入 compile `com.zhy:magic-viewpager:1.0.1` ###(2)示例 布局文件 <FrameLayout android:layout_width="match_parent" android:l

  • Android Intent实现页面跳转的方法示例

    应朋友们反馈的Android基础薄弱的问题,决定出一套Android基础教程,帮助大家复习,巩固Android基础,今天要讲的是Android中的Intent实现Android间的页面跳转. 增加Acrivity页面时,首先需要在MainActivity中对页面注册,比如 新建被跳转的页面OtherActivity,其对应的xml文件如下 activity_other <?xml version="1.0" encoding="utf-8"?> <

  • Android使用Intent显示实现页面跳转

    在学习安卓的最初过程中我们学的都是最基本的一个活动,只有一个活动的应用也太简单了吧,没错我们的最求应该更高点,不管你创建多少个活动,接下里我们介绍的这种方法能解决我们在创建活动之间的跳转. 使用显示Intent 刚入门学习Android的小伙伴们已经能很娴熟的使用Android studio 创建一个项目了,接下来我把我自己创建的目录先展示下 首先创建一个名叫TestIntent的project然后在main--java下面创建了2个类分别是FirstActivity和MainActivity,

  • 原生JS+CSS实现炫酷重力模拟弹跳系统的登录页面

    今天小编把之前保存的js特效视频看了一遍,跟着视频敲了敲嘻嘻,用原生js实现一个炫酷的登录页面.怎么个炫酷法呢,看看下面的图片大家就知道啦. 效果图: 不过在看代码之前呢,大家先和小颖看看css中的opacity.transition.box-shadow这三个属性. 1.opacity CSS3 opacity 属性 实例 设置一个div元素的透明度级别: div { opacity:0.5; } 在此页底部有更多的例子. 浏览器支持 Internet ExplorerFirefoxOpera

  • JS实现页面炫酷的时钟特效示例

    目录 一.前言 二.想法设计/实现过程 三.基本样式 四.时间函数控制器 五,时,分,秒占位 六.时间动态填充 一.前言 今天看到某网站的时间特别的丑陋,所以就诞生了写一个看时间的炫酷的时钟前端页面. 特点就是炫酷,特效好,个人以心情愉快的感觉. 对于时间的变化,我打算使用翻页的特效来完成,色系的话采用黑色以主题,给人一种神秘的感觉. 而且要获取到本地的时间的数据来实时更新它的变化. 二.想法设计/实现过程 秉持着尽可能的美观炫酷,与用户的交互性好的原则,我初步的想法是,采用黑色系来增加可观性,

  • Vue仿微信app页面跳转动画效果

    10:14:11独立开发者在开发移动端产品时,为了更高效,通常会使用Web技术来开发移动端项目,可以同时适配Android.iOS.H5,稍加改动还可适配微信小程序. 在使用Vue.js开发移动端页面的时候,默认的组件转场效果过于生硬,根本就没有动画效果.于是我用Vue提供的组件过渡功能,写了个仿微信app页面跳转的动画,以提高用户体验. 废话不多说,直接上图 在600元骁龙632安卓测试机效果流畅. 代码量很少,已上传至GitHub https://github.com/YellowDoing

  • Android软件启动动画及动画结束后跳转的实现方法

    本文实例讲述了Android软件启动动画及动画结束后跳转的实现方法.分享给大家供大家参考,具体如下: 自己写了个小程序,软件启动时,先显示几张图片,每3秒显示一张,图片显示完跳转到首页 1. 图片轮播使用Gallery,用法很简单 GalleryAdapter adapter = new GalleryAdapter(this, mIds); mGallery.setAdapter(adapter); GalleryAdapter是自定义适配器 public class GalleryAdapt

随机推荐