当前位置: 首页 > news >正文

专业网站定制价格便宜班级网站制作模板

专业网站定制价格便宜,班级网站制作模板,微信知彼网络网站建设,上海市网最近一段时间#xff0c;在做一个需求#xff0c;需要实现一个聊天气泡的动画效果#xff0c;如下图所示#xff1a; GitHub源码demo #xff0c;建议下载demo#xff0c;运行查看。 动态聊天气泡动画 静态聊天气泡 经过一段时间调研#xff0c;实现方案如下: 实现方…最近一段时间在做一个需求需要实现一个聊天气泡的动画效果如下图所示 GitHub源码demo 建议下载demo运行查看。 动态聊天气泡动画 静态聊天气泡 经过一段时间调研实现方案如下: 实现方案 从服务端下载zip文件文件中包含配置文件和多张png图片配置文件定义了图片的横向拉伸拉伸区域、纵向拉伸区域、padding信息等。从本地加载配置文件加载多张png图片为bitmap。将bitmap存储在内存里。LruCache避免多次解析。根据配置文件将png图片转换为.9图NinePatchDrawable。使用多张NinePatchDrawable创建一个帧动画对象AnimationDrawable将AnimationDrawable设置为控件的背景并让AnimationDrawable播放动画执行一定的次数后停止动画。 其中的难点在于第3步将png图片转换为.9图 NinePatchDrawable。 NinePatchDrawable 的构造函数。 /*** Create drawable from raw nine-patch data, setting initial target density* based on the display metrics of the resources.*/ public NinePatchDrawable(Resources res,Bitmap bitmap,byte[]chunk,Rect padding,String srcName){this(new NinePatchState(new NinePatch(bitmap,chunk,srcName),padding),res); }其中最关键的点在于构建byte[] chunk参数。通过查看这个类NinePatchChunk.java并参阅了许多博客通过反向分析NinePatchChunk类的deserialize方法得到了如何构建byte[] chunk的方法。 // See frameworks/base/include/utils/ResourceTypes.h for the format of // NinePatch chunk. class NinePatchChunk {public static final int NO_COLOR 0x00000001;public static final int TRANSPARENT_COLOR 0x00000000;public Rect mPaddings new Rect();public int mDivX[];public int mDivY[];public int mColor[];private static void readIntArray(int[] data, ByteBuffer buffer) {for (int i 0, n data.length; i n; i) {data[i] buffer.getInt();}}private static void checkDivCount(int length) {if (length 0 || (length 0x01) ! 0) {throw new RuntimeException(invalid nine-patch: length);}}//注释1处解析byte[]数据构建NinePatchChunk对象public static NinePatchChunk deserialize(byte[] data) {ByteBuffer byteBuffer ByteBuffer.wrap(data).order(ByteOrder.nativeOrder());byte wasSerialized byteBuffer.get();if (wasSerialized 0)//第一个字节不能为0return null;NinePatchChunk chunk new NinePatchChunk();chunk.mDivX new int[byteBuffer.get()];//第二个字节为x方向上的切割线的个数chunk.mDivY new int[byteBuffer.get()];//第三个字节为y方向上的切割线的个数chunk.mColor new int[byteBuffer.get()];//第四个字节为颜色的个数checkDivCount(chunk.mDivX.length);//判断x方向上的切割线的个数是否为偶数checkDivCount(chunk.mDivY.length);//判断y方向上的切割线的个数是否为偶数// skip 8 bytes跳过8个字节byteBuffer.getInt();byteBuffer.getInt();//注释2处处理padding发现都设置为0也可以。chunk.mPaddings.left byteBuffer.getInt();//左边的paddingchunk.mPaddings.right byteBuffer.getInt();//右边的paddingchunk.mPaddings.top byteBuffer.getInt();//上边的paddingchunk.mPaddings.bottom byteBuffer.getInt();//下边的padding// skip 4 bytesbyteBuffer.getInt();//跳过4个字节readIntArray(chunk.mDivX, byteBuffer);//读取x方向上的切割线的位置readIntArray(chunk.mDivY, byteBuffer);//读取y方向上的切割线的位置readIntArray(chunk.mColor, byteBuffer);//读取颜色return chunk;} }注释1处解析byte[]数据构建NinePatchChunk对象。我们添加了一些注释意思已经很清晰了。 然后我们根据这里类来构建byte[] chunk参数。 private fun buildChunk(): ByteArray {// 横向和竖向端点的数量 线段数量 * 2这里只有一个线段所以都是2val horizontalEndpointsSize 2val verticalEndpointsSize 2//这里计算的 arraySize 是 int 值最终占用的字节数是 arraySize * 4val arraySize 1 2 4 1 horizontalEndpointsSize verticalEndpointsSize COLOR_SIZE//这里乘以4是因为一个int占用4个字节val byteBuffer ByteBuffer.allocate(arraySize * 4).order(ByteOrder.nativeOrder())byteBuffer.put(1.toByte()) //第一个字节无意义不等于0就行byteBuffer.put(horizontalEndpointsSize.toByte()) //mDivX x数组的长度byteBuffer.put(verticalEndpointsSize.toByte()) //mDivY y数组的长度byteBuffer.put(COLOR_SIZE.toByte()) //mColor数组的长度// skip 8 bytesbyteBuffer.putInt(0)byteBuffer.putInt(0)//Note: 目前还没搞清楚发现都 byteBuffer.putInt(0)也没问题。//左右paddingbyteBuffer.putInt(mRectPadding.left)byteBuffer.putInt(mRectPadding.right)//上下paddingbyteBuffer.putInt(mRectPadding.top)byteBuffer.putInt(mRectPadding.bottom)//byteBuffer.putInt(0)//byteBuffer.putInt(0)//上下padding//byteBuffer.putInt(0)//byteBuffer.putInt(0)//skip 4 bytesbyteBuffer.putInt(0)//mDivX数组控制横向拉伸的线段数据目前只支持一个线段patchRegionHorizontal.forEach {byteBuffer.putInt(it.start * width / originWidth)byteBuffer.putInt(it.end * width / originWidth)}//mDivY数组控制竖向拉伸的线段数据目前只支持一个线段patchRegionVertical.forEach {byteBuffer.putInt(it.start * height / originHeight)byteBuffer.putInt(it.end * height / originHeight)}//mColor数组for (i in 0 until COLOR_SIZE) {byteBuffer.putInt(NO_COLOR)}return byteBuffer.array() }完整的类请参考 AnimationDrawableFactory.kt 。 使用 完整的使用请查看 ChatAdapter 类。 AnimationDrawableFactory 支持从文件构建动画也支持从Android的资源文件夹构建动画。 !!!注意从文件构建动画需要将请把工程下的bubbleframe文件夹拷贝到手机的Android/data/包名/files 目录下val fileDir getExternalFilesDir(null)否则会报错。 从文件构建动画 return AnimationDrawableFactory(context).setDrawableDir(pngsDir)//图片文件所在的目录.setHorizontalStretchBean(PatchStretchBean(60, 61))//水平拉伸区域.setVerticalStretchBean(PatchStretchBean(52, 53))//垂直拉伸区域.setOriginSize(128, 112)//原始图片大小.setPadding(Rect(31, 37, 90, 75))//padding区域.setHorizontalMirror(isSelf)//是否水平镜像不是必须的.setScaleFromFile(true)//是否从文件中读取图片的缩放比例不是必须的.setFinishCount(3)//动画播放次数.setFrameDuration(100)//每帧动画的播放时间.buildFromFile()这里注意一下因为文件中的图片是一倍图所以这里需要放大所以设置了setScaleFromFile(true)。 如果文件中的图片是3倍图就不需要设置这个参数了。如果需要更加精细的缩放控制后面再增加支持。 从Android的资源文件夹构建动画 private val resIdList mutableListOfInt().apply {add(R.drawable.bubble_frame1)add(R.drawable.bubble_frame2)add(R.drawable.bubble_frame3)add(R.drawable.bubble_frame4)add(R.drawable.bubble_frame5)add(R.drawable.bubble_frame6)add(R.drawable.bubble_frame7)add(R.drawable.bubble_frame8)add(R.drawable.bubble_frame9)add(R.drawable.bubble_frame10)add(R.drawable.bubble_frame11)add(R.drawable.bubble_frame12) }/*** 从正常的资源文件加载动态气泡*/ return AnimationDrawableFactory(context).setDrawableResIdList(resIdList)//图片资源id列表.setHorizontalStretchBean(PatchStretchBean(60, 61))//水平拉伸区域.setVerticalStretchBean(PatchStretchBean(52, 53))//垂直拉伸区域.setOriginSize(128, 112)//原始图片大小.setPadding(Rect(31, 37, 90, 75))//padding区域.setHorizontalMirror(isSelf)//是否水平镜像不是必须的.setFinishCount(3)//动画播放次数,不是必须的.setFrameDuration(100)//每帧动画的播放时间,不是必须的.buildFromResource()有时候可能我们只需要构建静态气泡也就是只需要一张 NinepatchDrawable我们提供了一个类来构建静态气泡NinePatchDrawableFactory.kt。 从文件加载 return NinePatchDrawableFactory(context).setDrawableFile(pngFile)//图片文件.setHorizontalStretchBean(PatchStretchBean(60, 61))//水平拉伸区域.setVerticalStretchBean(PatchStretchBean(52, 53))//垂直拉伸区域.setOriginSize(128, 112)//原始图片大小.setScaleFromFile(true)//是否从文件中读取图片的缩放比例不是必须的.setPadding(Rect(31, 37, 90, 75))//padding区域.setHorizontalMirror(isSelf)//是否水平镜像不是必须的.buildFromFile()从资源加载 return NinePatchDrawableFactory(context).setDrawableResId(R.drawable.bubble_frame1)//图片资源id.setHorizontalStretchBean(PatchStretchBean(60, 61))//水平拉伸区域.setVerticalStretchBean(PatchStretchBean(52, 53))//垂直拉伸区域.setOriginSize(128, 112)//原始图片大小.setPadding(Rect(31, 37, 90, 75))//padding区域.setHorizontalMirror(isSelf)//是否水平镜像不是必须的.buildFromResource()padding 取值 如图所示宽高是128*112。横向padding取值为31、90纵向padding取值为37、75。 其他 在实现过程中发现Android 的 帧动画 AnimationDrawable无法控制动画执行的次数。最后自定义了一个类CanStopAnimationDrawable.kt 解决。 参考链接 Carson带你学Android关于逐帧动画的使用都在这里了-腾讯云开发者社区-腾讯云聊天气泡图片的动态拉伸、镜像与适配 - 掘金Android 点九图机制讲解及在聊天气泡中的应用 - 掘金Android动态布局入门及NinePatchChunk解密Android点九图总结以及在聊天气泡中的使用-腾讯云开发者社区-腾讯云https://developer.android.com/studio/write/draw9patch?utm_sourceandroid-studiohlzh-cn
http://www.dnsts.com.cn/news/47843.html

相关文章:

  • 合肥住房城乡建设部的网站自建网站过程
  • 企业营销网站建设步骤最新电视剧在线观看免费
  • 物流公司网站制作模板在服务器上搭建网站
  • 做网站买一个域名多少钱制作图片视频的软件
  • 郑州做网站七彩科技陈村大良网站建设
  • ios移动网站开发搜狗搜索引擎优化指南
  • 教材资源网站建设seo研究中心qq群
  • 淘宝网站建设的目标是什么意思wordpress主题 演员
  • 专题型定制网站建设wordpress前台发帖
  • 国外网站建设方案基于jsp的购物网站开发
  • wordpress 用户组权限设置达州seo排名
  • 外贸网站推广如何做佛山专业网站建设哪家好
  • 快速seo整站优化排行做科技汽车的视频网站有哪些
  • 功能型网站介绍网页设计培训学校哪家好
  • 好的建设网站公司搭建网站的平台有哪些
  • 安阳网站建设兼职企业电脑管理软件
  • 的做网站公司小游戏制作软件
  • 网站建设行业政策门店管理网站建设
  • 去除 做网站就用建站之星专业柳州网站建设哪家好
  • 做外贸做什么英文网站好重庆市工程造价信息价查询
  • 怎么创建属于自己的网站科协科普网站建设
  • 食品网站建设项目的预算wordpress4.8.0
  • 温州 网站建设公司即墨区建设局网站
  • 网站建设英文版apache网站拒绝访问
  • 沈阳网站建设渠道兖州网站建设哪家便宜
  • 福州网站建设方案建设银行总部投诉网站
  • 企业网站设计收费海外宣传推广实施方案
  • 地产网站建设公司国内免费服务器地址
  • 做铝材什么什么网站好网站改版 理论
  • 临沂河东建设局网站什么网站可以请人做软件