SpineRuntime-Presentation - 基于 spine-libgdx 实现在 AndroidPresentation 上展示 Spine 动画
SpineRuntime-Presentation
基于 spine-libgdx 实现在 AndroidPresentation 上展示 Spine 动画
Github地址
效果
- 可以在 Android 的 Presentation 页面上通过 GLSurfaceView 展示 Spine 动画,Spine 动画可以叠加,互不干扰
- 使用
PUSurfaceView替代PopupWindow在 Spine 动画的 GLSurfaceView 上层展示其他 View
注意
- Presentation 需要
android.permission.SYSTEM_ALERT_WINDOW、android.permission.WRITE_SETTINGS两个权限 - 虚拟机运行可能报错
- Spine动画的缩放适配可能需要手动修改
SpineBaseAdapter,现有的适配需要动画的中心在(0,-1) - Spine 动画需要参照 Demo 通过回调依次创建
- Spine 动画的回调不是主线程,操作 view 需要异步到主线程
- 新创建的 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
- 优化 PUSurfaceView
- 优化 Spine 动画的缩放适配
- 优化 Spine 动画的动态 View 创建,不再需要提前在 container 上定义宽高
SpineRuntime-Presentation - 基于 spine-libgdx 实现在 AndroidPresentation 上展示 Spine 动画的更多相关文章
- 基于 Flink 的实时数仓生产实践
数据仓库的建设是“数据智能”必不可少的一环,也是大规模数据应用中必然面临的挑战.在智能商业中,数据的结果代表了用户反馈.获取数据的及时性尤为重要.快速获取数据反馈能够帮助公司更快地做出决策,更好地进行 ...
- 基于 Kafka 的实时数仓在搜索的实践应用
一.概述 Apache Kafka 发展至今,已经是一个很成熟的消息队列组件了,也是大数据生态圈中不可或缺的一员.Apache Kafka 社区非常的活跃,通过社区成员不断的贡献代码和迭代项目,使得 ...
- 利用Mahout实现在Hadoop上运行K-Means算法
利用Mahout实现在Hadoop上运行K-Means算法 一.介绍Mahout Mahout是Apache下的开源机器学习软件包,目前实现的机器学习算法主要包含有协同过滤/推荐引擎,聚类和分类三个部 ...
- 基于原生JS封装数组原型上的sort方法
基于原生JS封装数组原型上的sort方法 最近学习了数组的原型上内置方法的封装,加强了用原生JS封装方法的能力,也进一步理解数组方法封装的过程,实现的功能.虽然没有深入底层,了解源码.以下解法都是基于 ...
- 基于Caffe的DeepID2实现(上)
小喵的唠叨话:小喵最近在做人脸识别的工作,打算将汤晓鸥前辈的DeepID,DeepID2等算法进行实验和复现.DeepID的方法最简单,而DeepID2的实现却略微复杂,并且互联网上也没有比较好的资源 ...
- Resumable.js – 基于 HTML5 File API 的文件上传
Resumable.js 是一个 JavaScript 库,通过 HTML5 文件 API 提供,稳定和可恢复的批量上传功能.在上传大文件的时候通过每个文件分割成小块,每块在上传失败的时候,上传会不断 ...
- 基于h5的图片无刷新上传(uploadifive)
基于h5的图片无刷新上传(uploadifive) uploadifive简介 了解uploadify之前,首先了解来一下什么是uploadify,uploadfy官网,uploadify和uploa ...
- 注意padding-top 百分比定义基于父元素宽度的百分比上内边距!!是基于宽度
定义和用法 padding-top 属性设置元素的上内边距(空间). 说明 该属性设置元素上内边距的宽度.行内非替换元素上设置的上内边距不会影响行高计算,因此,如果一个元素既有内边距又有背景,从视觉上 ...
- 基于 Django的Ajax实现 文件上传
---------------------------------------------------------------遇到困难的时候,勇敢一点,找同学朋友帮忙,找导师求助. Ajax Ajax ...
随机推荐
- P4074 [WC2013]糖果公园 树上莫队带修改
题目链接 Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来糖果公园游玩. 糖果公园的结构十分奇特,它由 nn 个游览点构 ...
- c语言实现n!算法
最近一面学习数据结构,一面在做些c语言的题目.这个题目前些天碰到,和同学讨论了下.于是就用c语言实现n!(n=10000) 1 #include<stdio.h> 2 #define MA ...
- AcWing 241.楼兰图腾 (树状数组,逆序对)
题意:在二维坐标轴上给你一些点,求出所有由三个点构成的v和∧图案的个数. 题解:因为给出的点是按横坐标的顺序给出的,所以我们可以先遍历然后求出某个点左边比它高和低的点的个数(这个过程简直和用树状数组求 ...
- Codeforces Round #547 (Div. 3) F1/2. Same Sum Blocks (Easy/Hard) (贪心,模拟)
题意:有一长度为\(n\)的数组,求最多的区间和相同的不相交的区间的个数. 题解:我们可以先求一个前缀和,然后第一层循环遍历区间的右端点,第二层循环枚举左端点,用前缀和来\(O(1)\)求出区间和,\ ...
- Codeforces Round #650 (Div. 3) C. Social Distance (前缀和)
题意:有一排座位,要求每人之间隔\(k\)个座位坐,\(1\)代表已做,\(0\)代表空座,问最多能坐几人. 题解:我们分别从前和从后跑个前缀和,将已经有人坐的周围的位置标记,然后遍历求每一段连续的\ ...
- 从网络I/O模型到Netty,先深入了解下I/O多路复用
微信搜索[阿丸笔记],关注Java/MySQL/中间件各系列原创实战笔记,干货满满. 本文是Netty系列第3篇 上一篇文章我们了解了Unix标准的5种网络I/O模型,知道了它们的核心区别与各自的优缺 ...
- Kubernets二进制安装(7)之部署主控节点服务--apiserver二进制安装
kube-apiserver集群规划 主机名 角色 IP地址 mfyxw30.mfxyw.com kube-apiserver主 192.168.80.30 mfyxw40.mfyxw.com kub ...
- Redis 的缓存淘汰机制(Eviction)
本文从源码层面分析了 redis 的缓存淘汰机制,并在文章末尾描述使用 Java 实现的思路,以供参考. 相关配置 为了适配用作缓存的场景,redis 支持缓存淘汰(eviction)并提供相应的了配 ...
- sqlmap 详解
sqlmap 使用总结 0x01 需要了解 当给 sqlmap 这么一个 url 的时候,它会:1.判断可注入的参数 2.判断可以用那种 SQL 注入技术来注入 3.识别出哪种数据库 4.根据用户 ...
- 【原】无脑操作:Centos 7.6 + MariaDB + Rsyslog + LogAnalyzer环境搭建
背景: 网络安全法第三章第二十一条明确规定"采取监测.记录网络运行状态.网络安全事件的技术措施,并按照规定留存相关的网络日志不少于六个月". 为了满足合规性的要求,应当建设相应的日 ...
