欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2023-11-28 23:40:58
android 5.0中引入了很多炫酷的动画效果,circular reveal便是其中一种。使用起来很简单,但效果却是意想不到的炫酷,让你的app更有逼格。 一、效...

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

一、效果

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

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

二、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 结束时的圆半径

三、实现

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

从上图可以看出,需要揭露展现的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动画

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