首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何优雅的从网络加载点九图?

如何优雅的从网络加载点九图?

作者头像
吴延宝
发布2018-09-10 15:28:04
2K0
发布2018-09-10 15:28:04
举报

如何处理从网络加载点九的图

我们开发Android应用的时候,当需要适配可拉伸的背景,我们会使用.9.png的图。通常我们是放在res目录下的,这种方式我们很容易做到。但是如果需要我们去网络获取.9的图该如何做呢?

1 背景

1.1 什么是点九图

其实点九图和我们用的其他格式的图没有什么大的不同,只不过是在图片的四周各增加了1px的纯黑(#FF000000)的线进行标记。例如:

标记位置

含义

左-黑线

纵向拉伸区域

上-黑线

横向拉伸区域

右-黑线

纵向显示区域

下-黑线

横向显示区域

1.2 Android是如何加载点九图的

当我们将点九图放在res目录下,Android不是直接去加载点九图的,而是在编译的时候将其转换成另一种格式,这种格式是将其四周的黑色像素保存在Bitmap类中的mNinePatchChunk的byte[]数组中,并去掉四周一像素的宽度;在使用的时候,当判断mNinePatchChunk不为空且为9patchchunk,则将其构造为NinePatchDrawable,否则构造为BitmapDrawable,最终设置给view。所以,最后打包后的点九图已经不是原来带黑线的点九图了。

2 使用方案

2.1 遇到的坑

如果没做任何处理,当我们从服务端直接拉取点九的图设置到我们的view上时,发现图片并不会拉伸,并且图片周围的黑线也会显示出来。从上1.2Android加载点九图的原理可知,之所以出现这种问题,是因为我们少了编译这一步,是直接拿原始的点九图设置到view上的,所以才出现问题。 知道错误的原因后,我们可以做如下几种方式处理:

  • 让产品或者设计师先进行转换后(转换工具由开发提供)再上传到服务器,这时客户端再从服务端拉取到的就是编译处理后的点九图了
  • 将原始点九图上传到一个转换平台,平台进行转换后再上传到服务器
  • 另外一种是客户端拿到原始的点九图后自行处理,根据加载的原理自行构造出NinePatchDrawable,这个过程放到客户端渲染的时候显然太耗时,不符合要求 我们以QQ的方案为例(第一种)来讨论实现方案。
2.2 使用方案

先看下总的流程图:

使用上述方案的注意事项:

  • 步骤2画黑线必须是纯黑色像素,且图片的四个角必须为透明像素点,否则Android无法识别,且在步骤3中将无法转换
  • 步骤3中,可以使用Android SDK自带工具aapt进行转换:aapt c -v -S . -C .\output,其中.表示当前目录,.\output表示目标目录
  • 步骤4中,上传过程中不能对转换后的图进行压缩,因为转换后的点九图的黑线信息被保存到了png图片的辅助数据快中,这部分数据在压缩的过程中会消失,导致最终客户端拉取到的图片不是点九图
  • 步骤4中,某些cdn因为省流量,或者其他原因,对图片进行压缩或者转码为webp格式,这样会导致最终拉取到的图片不是点九图。
  • 步骤8中,需要通过Bitmap创建drawable,如果是使用res目录下的,Android系统会自动完成,如果是获取网络图片则需要自己手动创建,如下:
  • 步骤9中,一定要使用缓存,不然异步加载的过程中,在list中显示会有问题,跳变很严重。
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-07-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 南京Android部落 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 如何处理从网络加载点九的图
    • 1 背景
      • 1.1 什么是点九图
      • 1.2 Android是如何加载点九图的
    • 2 使用方案
      • 2.1 遇到的坑
      • 2.2 使用方案
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档