专栏首页恩蓝脚本Android ShimmerLayout实现微光效果解析

Android ShimmerLayout实现微光效果解析

前阵子在github上看到一个很不错的动画效果,叫做ShimmerLayout,是一个用于实现内部视图微光效果的布局。

如何实现

通过使用PorterDuff,我们可以制造出微光效果。PorterDuff是canvas绘制图像处理中的一种渲染模式,当我们需要绘制出区域覆盖的图形效果的时候,我们可以使用这种方式来绘制。

这里我们采用的是PorterDuff.MODE.SRC_IN,意思是在绘制的时候,显示上下图层相交的部分,且这部分显示上层图层。

1) 首先我们需要绘制出最上层的微光,这里通过LinearGradient线性渐变渲染器来绘制微光渐变效果,为了使得渐变自然,我们看到,代码里在前后两端都加入了透明色。

private Bitmap getSourceMaskBitmap() {
  if (sourceMaskBitmap != null) {
   return sourceMaskBitmap;
  }

  int width = maskRect.width();
  int height = getHeight();

  /* 通过LinearGradient在遮罩Bitmap上绘制渐变效果 */
  final int edgeColor = reduceColorAlphaValueToZero(shimmerColor);
  LinearGradient gradient = new LinearGradient(
    -maskRect.left, 0,
    width + maskRect.left, 0,
    /* 透明色 - 微光颜色 - 微光颜色 - 透明色 */
    new int[]{edgeColor, shimmerColor, shimmerColor, edgeColor},
    new float[]{0.25F, 0.47F, 0.53F, 0.75F},
    Shader.TileMode.CLAMP);

  Paint paint = new Paint();
  paint.setShader(gradient);

  sourceMaskBitmap = createBitmap(width, height);
  /* 对微光效果的bitmap做一些旋转效果 */
  Canvas canvas = new Canvas(sourceMaskBitmap);
  canvas.rotate(shimmerAngle, width / 2, height / 2);
  canvas.drawRect(-maskRect.left, maskRect.top, width + maskRect.left, maskRect.bottom, paint);

  return sourceMaskBitmap;
 }

2)、然后,我们需要把微光效果的图层和视图本身的界面混合,使用PorterDuff.MODE.SRC_IN混合效果。首先如何绘制视图本身的界面,这里很简单,直接调用父类的绘制方法super.dispatchDraw(Canvas),紧接着再绘制微光效果的图层。

/* 获取微光效果Bitmap */
localMaskBitmap = getSourceMaskBitmap();
canvas.save();
/* 先绘制GroupView本身的界面 */
super.dispatchDraw(canvas);
/* 再绘制微光效果Bitmap */
canvas.drawBitmap(localMaskBitmap, 0, 0, maskPaint);
canvas.restore();

3) 最后我们发现,微光效果是从左向右移动过去的,如何实现?

通过不断位移localMaskBitmap的位置,这里通过控制偏移值maskOffsetX,实现了微光慢慢位移的效果。

/* 获取微光效果Bitmap */
localMaskBitmap = getSourceMaskBitmap();
canvas.save();
/* canvas 裁剪显示 */
canvas.clipRect(maskOffsetX, 0,
        maskOffsetX + localMaskBitmap.getWidth(),
        getHeight());
/* 先绘制GroupView本身的界面 */
super.dispatchDraw(canvas);
/* 再绘制微光效果Bitmap */
canvas.drawBitmap(localMaskBitmap, maskOffsetX, 0, maskPaint);
canvas.restore();

这个动画原理本身很简单,不过在内存方面,因为创建了多个bitmap,如果当前界面不包含大图,对内存的消耗还是很低的,适用于为比较轻量级的界面添加效果。

更多细节,看看作者的原文介绍以及GitHub

ShimmerLayout Github : https://github.com/team-supercharge/ShimmerLayout

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Python集成开发工具Pycharm的安装和使用详解

    Python语言当前越来越流行,使用的人越来越多,集成开发工具pycharm是当前使用比较多的一个开发工具,掌握pycharm的安装和基本的使用非常重要。

    砸漏
  • 基于Android studio3.6的JNI教程之ncnn之语义分割ENet

    https://github.com/watersink/enet-as-linux

    砸漏
  • cdr怎么画简笔画的打印机图形? cdr打印机矢量图的画法

    cdr中想要绘制打印机,该怎么绘制打印机简笔画效果呢?我们需要用基本形状、选择、形状工具,调色板等进行操作,下面我们就来看看详细的教程。

    砸漏
  • 计算n的阶乘的俩种方法

    递归函数的优点是算法设计容易, 但诋毁函数的优点是在牺牲了存储空间的基础上得到的。

    栋先生
  • Unity3D使用Cinemachine配合Timeline实现运镜效果

    Unity3D中的插件Cinemachine高级虚拟摄像系统,配合Timeline时间轴一起使用,可以实现像电影级别的分镜等效果,这篇我们就继续用上个模拟收费通...

    Vaccae
  • 【业界】帮化学家偷个懒,利用量子计算来模拟化学反应

    AiTechYun 编辑:xiaoshan.xiang 第一个已知的经典“计算机”是Antikythera mechanism,这是一种模拟机器,用于模拟天体在...

    AiTechYun
  • 使用VisualVM、JMC远程监控JVM 原

    VisualVM is a visual tool integrating commandline JDK tools and lightweight prof...

    wuweixiang
  • ICLR 2020满分论文解读 | 一种镜像生成式机器翻译模型:MGNMT

    论文链接:https://static.aminer.cn/misc/pdf/minrror.pdf

    AI科技评论
  • C++初始化列表

    一、什么是初始化列表 与其他函数不同,构造函数除了有名字,参数列表和函数体之外,还可以有初始化列表,初始化列表以冒号开头,后跟一系列以逗号分隔的初始化字段 二、...

    用户1215536
  • 浅谈Android单元测试的作用以及简单示例

    对于单元测试这个知识点,其实很多开发者是不太接触的,包括笔者,在实习之前也并未实用过单元测试,或者说并没感受到单元测试的好处。

    砸漏

扫码关注云+社区

领取腾讯云代金券