SpineRuntime-Presentation

基于 spine-libgdx 实现在 AndroidPresentation 上展示 Spine 动画


Github地址


效果

  • 可以在 Android 的 Presentation 页面上通过 GLSurfaceView 展示 Spine 动画,Spine 动画可以叠加,互不干扰
  • 使用PUSurfaceView替代PopupWindow在 Spine 动画的 GLSurfaceView 上层展示其他 View

注意

  1. Presentation 需要 android.permission.SYSTEM_ALERT_WINDOWandroid.permission.WRITE_SETTINGS 两个权限
  2. 虚拟机运行可能报错
  3. Spine动画的缩放适配可能需要手动修改SpineBaseAdapter,现有的适配需要动画的中心在(0,-1)
  4. Spine 动画需要参照 Demo 通过回调依次创建
  5. Spine 动画的回调不是主线程,操作 view 需要异步到主线程
  6. 新创建的 Spine 动画 View 的 zOrder 始终为 top

使用

调用请参考 app module 的 SpinePresentation.kt

1. 加载GDX
    companion object {
init {
GdxNativesLoader.load()
}
}
2. 创建Adapter

创建自定义 adapter 继承 SpineBaseAdapter,在onCreateImpl()回调中设置动画数据,在onCreatedImpl()中设置 skim 与 animation,也可以在创建 adapter 后设置。

    abstract class SpineBaseAdapter : ApplicationAdapter {

        var tag = "null"    // 用于onCreated异步回调的tag
var skinName = "default" // 默认皮肤名称
var animationName = "animation" // 默认动画名称
var debugMode = false // 默认关闭debug
var isClickable = true // view是否可被点击,默认为true constructor(padding: Int = 0)
constructor(paddingStart: Int, paddingTop: Int, paddingEnd: Int, paddingBottom: Int) /**
* 动画的点击回调
*/
fun setOnSpineClickListener(spineClickListener: OnSpineClickListener) /**
* 动画的创建完成回调
* 多个Spine动画对象需要依次创建,不可以同时创建多个
* 多以需要设置创建完成的异步回调,并配合tag来进行判断
*/
fun setOnCreatedListener(onSpineCreatedListener: OnSpineCreatedListener) /**
* 根据altasPath与skeletonPath初始化之后的回调
* 用于setSkin、setAnimation、setAttachment
*/
abstract fun onCreatedImpl() /**
* 点击事件回调
*/
abstract fun doClick() /**
* 设置Spine的Altas路径
* @param path 路径
* @param fileType [FileType]
*/
fun setAltasPath(path: String, fileType: FileType) /**
* 设置Spine的json文件路径
*/
fun setSkeletonPath(path: String, fileType: FileType) /**
* 设置动画
*/
fun setAnimation(trackIndex: Int, animationName: String, loop: Boolean) /**
* 实例开始创建回调
* 在这里设置Altas与SkeletonPath
*/
abstract fun onCreateImpl() /**
* 换装饰
*
* @param slotName 插槽名称
* @param attachmentName 装饰名称
* @return
*/
fun setAttachment(slotName: String, attachmentName: String): Boolean /**
* 换肤
*
* @param skinName 皮肤名称
* @return
*/
fun setSkin(skinName: String): Boolean /**
* 创建完成的回调
*/
interface OnSpineCreatedListener {
fun onCreated(tag: String)
} /**
* 创建 SurfaceView 对象
*/
@Synchronized
fun create(activity: Activity): View
}
3. 创建 view 与展示

调用 adapter 的create(activity: Activity)方法创建 view,并将 view 添加到 parentView 中。

4. 在 Spine 上层绘制纯色与图片

使用PUSurfaceView可以在 Spine 动画上层绘制纯色与图片。PUSurfaceView仅实现了简单的SurfaceView绘制功能。

    <!-- drawType 为 color 时需要配置 bgColor,image 时需要配置 imageSrc -->
<com.mai.spine.PUSurfaceView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:bgColor="#88000000"
app:imageSrc="@mipmap/ic_launcher"
app:drawType="<!-- color / image --> " />
5. 动态创建 PUSurfaceView
    class PUSurfaceView : SurfaceView{
constructor(context: Context, attrs: AttributeSet?)
constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) /**
* 根据传入的color绘制纯色
*/
fun drawColor(color: Int) /**
* 根据传入id绘制图片
*/
fun drawImage(id: Int)
}

TODO

  1. 优化 PUSurfaceView
  2. 优化 Spine 动画的缩放适配
  3. 优化 Spine 动画的动态 View 创建,不再需要提前在 container 上定义宽高

SpineRuntime-Presentation - 基于 spine-libgdx 实现在 AndroidPresentation 上展示 Spine 动画的更多相关文章

  1. 基于 Flink 的实时数仓生产实践

    数据仓库的建设是“数据智能”必不可少的一环,也是大规模数据应用中必然面临的挑战.在智能商业中,数据的结果代表了用户反馈.获取数据的及时性尤为重要.快速获取数据反馈能够帮助公司更快地做出决策,更好地进行 ...

  2. 基于 Kafka 的实时数仓在搜索的实践应用

    一.概述 Apache Kafka 发展至今,已经是一个很成熟的消息队列组件了,也是大数据生态圈中不可或缺的一员.Apache Kafka 社区非常的活跃,通过社区成员不断的贡献代码和迭代项目,使得 ...

  3. 利用Mahout实现在Hadoop上运行K-Means算法

    利用Mahout实现在Hadoop上运行K-Means算法 一.介绍Mahout Mahout是Apache下的开源机器学习软件包,目前实现的机器学习算法主要包含有协同过滤/推荐引擎,聚类和分类三个部 ...

  4. 基于原生JS封装数组原型上的sort方法

    基于原生JS封装数组原型上的sort方法 最近学习了数组的原型上内置方法的封装,加强了用原生JS封装方法的能力,也进一步理解数组方法封装的过程,实现的功能.虽然没有深入底层,了解源码.以下解法都是基于 ...

  5. 基于Caffe的DeepID2实现(上)

    小喵的唠叨话:小喵最近在做人脸识别的工作,打算将汤晓鸥前辈的DeepID,DeepID2等算法进行实验和复现.DeepID的方法最简单,而DeepID2的实现却略微复杂,并且互联网上也没有比较好的资源 ...

  6. Resumable.js – 基于 HTML5 File API 的文件上传

    Resumable.js 是一个 JavaScript 库,通过 HTML5 文件 API 提供,稳定和可恢复的批量上传功能.在上传大文件的时候通过每个文件分割成小块,每块在上传失败的时候,上传会不断 ...

  7. 基于h5的图片无刷新上传(uploadifive)

    基于h5的图片无刷新上传(uploadifive) uploadifive简介 了解uploadify之前,首先了解来一下什么是uploadify,uploadfy官网,uploadify和uploa ...

  8. 注意padding-top 百分比定义基于父元素宽度的百分比上内边距!!是基于宽度

    定义和用法 padding-top 属性设置元素的上内边距(空间). 说明 该属性设置元素上内边距的宽度.行内非替换元素上设置的上内边距不会影响行高计算,因此,如果一个元素既有内边距又有背景,从视觉上 ...

  9. 基于 Django的Ajax实现 文件上传

    ---------------------------------------------------------------遇到困难的时候,勇敢一点,找同学朋友帮忙,找导师求助. Ajax Ajax ...

随机推荐

  1. AtCoder Beginner Contest 178

    比赛链接:https://atcoder.jp/contests/abc178/tasks A - not 题意 给出一个整数 $0 \le x \le 1$,如果 $x$ 是 $0$ 就输出 $1$ ...

  2. CodeCraft-20 (Div. 2) C. Primitive Primes (数学)

    题意:给你两个一元多项式\(f(x)\)和\(g(x)\),保证它们每一项的系数互质,让\(f(x)\)和\(g(x)\)相乘得到\(h(x)\),问\(h(x)\)是否有某一项系数不被\(p\)整除 ...

  3. HDU 6155 Subsequence Count(矩阵 + DP + 线段树)题解

    题意:01串,操作1:把l r区间的0变1,1变0:操作2:求出l r区间的子序列种数 思路:设DP[i][j]为到i为止以j结尾的种数,假设j为0,那么dp[i][0] = dp[i - 1][1] ...

  4. Monorepo All In One

    Monorepo All In One monorepos 只是一种思想,或设计模式,架构风格 https://trunkbaseddevelopment.com/monorepos/ Lerna h ...

  5. git merge bug

    git merge bug 本地分支 dev commit 后, 直接 pull 远程 dev 分支, 导致远程 dev 分支 merge 到本地 dev 分支了, 取消本次 merge 操作? Re ...

  6. HTML5 Animation Creator | Hype 官方文档

    HTML5 Animation Creator | Hype 官方文档 HTML5 Animation Build 7个 专业术语 场景,元素,属性,关键帧,动画,时间线,操作 Hype 官方文档 h ...

  7. CSS & new class name

    CSS & new class name { test: /\.((s*)css|sass)$/, // test: /\.(css|scss|sass)$/, use: ExtractTex ...

  8. Github history viewer

    Github history viewer https://github.githistory.xyz/ https://github.com/pomber/git-history https://c ...

  9. 来必力 & Disqus

    来必力 & Disqus 正在载入来必力 https://livere.com 个人博客-双评论系统(来必力与Disqus) https://tianbozhang.coding.me/com ...

  10. Typescript & React & Vue

    Typescript & React & Vue Typescript & React https://facebook.github.io/create-react-app/ ...