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. hdu 1696 Oulipo(KMP算法)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1686 题意 查询字符串 $p$ 在字符串 $s$ 中出现了多少次,可重叠. 题解 KMP模板题. Ti ...

  2. HDU2065 "红色病毒"问题 【组合数学 二项式定理】

    HDU2065 "红色病毒"问题 Description: 医学界发现的新病毒因其蔓延速度和Internet上传播的"红色病毒"不相上下,被称为"红色 ...

  3. 2019中国大学生程序设计竞赛(CCPC) - 网络选拔赛(8/11)

    $$2019中国大学生程序设计竞赛(CCPC)\ -\ 网络选拔赛$$ \(A.\hat{} \& \hat{}\) 签到,只把AB都有的位给异或掉 //#pragma comment(lin ...

  4. P2764 最小路径覆盖问题 (最小点覆盖=顶点数-最大匹配)

    题意:最小路径覆盖 题解:对于一个有向图,最小点覆盖 = 顶点数 - 最大匹配 这里的最大匹配指的是将原图中每一个点拆成入点.出点, 每条边连接起点的出点和终点的入点 源点S连接每个点的出点,汇点T连 ...

  5. Codeforces Round #692 (Div. 2, based on Technocup 2021 Elimination Round 3) C. Peaceful Rooks (思维,dsu找环)

    题意:一个棋盘上有一些"车",现在要让这些"车"跑到左倾斜的对角线上,每次可以移动一个棋子,但是棋盘的任意时刻都不能出现一个"车"能吃另一个 ...

  6. hdu4770 Lights Against Dudely

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission ...

  7. KEIL5 使用STM32 官方例程

    1. 安装keil5,破解 网上很多安装包/教程,跳过 2.下载官方固件库 https://www.st.com/content/st_com/en.html 在这里找微处理器,STM32 stand ...

  8. sscanf的最基础用法(非原创)

    1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 5 int main(){ 6 ch ...

  9. C++ part8

    1.volatile关键字 在C++中,对volatile修饰的对象的访问,有编译器优化上的副作用: 不允许被编译器优化,提供特殊地址的稳定访问(只从内存中读取). 有序性,编译器进行优化时,不能把对 ...

  10. TypeScript 1.7 & TypeScript 1.8

    TypeScript 1.7 & TypeScript 1.8 1 1 https://zh.wikipedia.org/wiki/TypeScript TypeScript是一种由微软开发的 ...