Android 进阶学习(二十七) 仿朋友圈查看图片动画

先看一下实现效果


GIF 2021-7-2 11-05-12.gif

想要实现上面图片中放大图片的效果,我们大致可以分为三个过程

1.收集RecyclerView中所有View的在屏幕中的位置,以及宽高

2.将Activity变为透明

3.实现图片的放大和位置调整

1.在学习RecyclerView的LayoutManger 的过程中我们知道屏幕上面的item都在他的自身的一级缓存中,那么我们只需要遍历一级缓存,并找到他的position, 得到View 的pisition 后,剩下就比较简单了,首先我们需要一个封装类来承载我们所需要收集的信息

public class ImageScanAnimBean implements Serializable {
  private int startX;//开始横坐标
  private int startY;//开始纵坐标
  private int width;//宽度
  private int height;//高度
  private int position;//位置
}

封装类有了剩下的就是收集所需要的信息,为了动画做准备

  @JvmStatic
  fun getLocation(recycler_view:RecyclerView):ArrayList<ImageScanAnimBean>? {
      val manager = recycler_view.getLayoutManager()!!
      val count = manager.childCount//getChildCount 就是获取一级缓存
      val animBeans = ArrayList<ImageScanAnimBean>()
      for (m in 0 until count) {
          val child = manager.getChildAt(m)//遍历一级缓存
          val i = manager.getPosition(child!!)//获取一级缓存在RecyclerView 中的位置
          val location_index = IntArray(2)
          child!!.getLocationOnScreen(location_index)//获取View 在屏幕中的位置,
          val bean = ImageScanAnimBean()
          bean.startX = location_index[0]
          bean.startY = location_index[1]
          bean.width = child!!.width//获取View 的宽
          bean.height = child!!.height//获取View 的高
          bean.position = i
          animBeans.add(bean)
      }
      return animBeans
  }

2.从图片中可以看到,想要实现图片缩放效果,就必须让Activity实现透明的效果,最开始我的想法是使用反射,将Activity变为透明,但是试验后发现Activity变为透明需要一个过程,这无疑影响了动画的效果,这就必须使用Theme来解决这个问题了,但是使用Theme我还在担心一个问题,由于使用了沉浸式状态栏,所以Activity使用的Theme的必须是AppCompat系列了,但是想要让Activity透明就要使用@android:style/Theme.Translucent.NoTitleBar这个Theme ,我怕使用的时候存在不兼容的情况,但是实际情况是可以的,我就放心了,解决了透明问题,我们还要考虑另外一个问题,那就是给Activity 设置一个动画,这个动画什么都不需要执行,但是他的动画时间必须是我们放大图片的动画时间,这样能让我们的动画执行起来更加放心

3.有了所有View 的坐标,同时Activity都变为了透明的效果,那么想要实现我们最终的效果就比较简单了,无非就是修改margin 和宽高的过程,

  @JvmStatic
  fun openAnim(activity: Activity, imageView: View, bean: ImageScanAnimBean,after:()->kotlin.Unit){
  /// 先把View 按照传递过来的大小调整
      var params : CoordinatorLayout.LayoutParams =CoordinatorLayout.LayoutParams(bean.width,bean.height)
      params.leftMargin=bean.startX
      params.topMargin=bean.startY
      imageView.layoutParams=params

      ///执行动画,  margin的横坐标是从 传递过来的x ->0  , 纵坐标是传递过来的y ->0 , 宽高则是由原来的宽高变为屏幕的宽高

      val animator = ValueAnimator.ofFloat(1f,0f)
      animator.duration = 400
      animator.interpolator = AccelerateInterpolator()
      var screenWidth=ScreenUtils.getScreenWidth(activity)
      var screenHeight=ScreenUtils.getScreenHeight(activity)
      animator.addUpdateListener { valueAnimator: ValueAnimator ->
          val value = valueAnimator.animatedValue as Float
          var p : CoordinatorLayout.LayoutParams = imageView.layoutParams as CoordinatorLayout.LayoutParams
          p.leftMargin= ((bean.startX)*value).toInt()
          p.topMargin=((bean.startY)*value).toInt()
          p.width=(bean.width+((screenWidth-bean.width )*(1f-value)).toInt())
          p.height=(bean.height+((screenHeight-bean.height )*(1f-value)).toInt())
          imageView.layoutParams=p
      }
      animator.addListener(object : Animator.AnimatorListener {
          override fun onAnimationStart(animation: Animator) {}
          override fun onAnimationEnd(animation: Animator) {
              after()
          }
          override fun onAnimationCancel(animation: Animator) {}
          override fun onAnimationRepeat(animation: Animator) {}
      })
      animator.start()
  }

关闭动画

 @JvmStatic
  fun closeAnim(activity: Activity, imageView: View, bean: ImageScanAnimBean){
      val animator = ValueAnimator.ofFloat(0f,1f)
      animator.duration = 400
      animator.interpolator = AccelerateInterpolator()
      var screenWidth= ScreenUtils.getScreenWidth(activity)
      var screenHeight= ScreenUtils.getScreenHeight(activity)
      animator.addUpdateListener { valueAnimator: ValueAnimator ->
          val value = valueAnimator.animatedValue as Float
          var p : CoordinatorLayout.LayoutParams = imageView.layoutParams as CoordinatorLayout.LayoutParams
          p.leftMargin= ((bean.startX)*value).toInt()
          p.topMargin=((bean.startY)*value).toInt()
          p.width=screenWidth- (((screenWidth-bean.width))*value).toInt()
          p.height=screenHeight-(((screenHeight-bean.height))*value).toInt()

          imageView.layoutParams=p
      }
      animator.start()
      animator.addListener(object : Animator.AnimatorListener {
          override fun onAnimationStart(animation: Animator) {}
          override fun onAnimationEnd(animation: Animator) {
              activity.finish()
              //发现如果先关闭activity,图片缩放可能受到影响,导致中间状态消失,所以这里结束的时候执行一个非常短的动画
              activity.overridePendingTransition(R.anim.serviceui_image_scan_in_0, R.anim.serviceui_image_scan_out_0)
          }
          override fun onAnimationCancel(animation: Animator) {}
          override fun onAnimationRepeat(animation: Animator) {}
      })
  }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,692评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,482评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,995评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,223评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,245评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,208评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,091评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,929评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,346评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,570评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,739评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,437评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,037评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,677评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,833评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,760评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,647评论 2 354