原文地址 Jetpack Compose学习(4)——Image(图片)使用及Coil图片异步加载库使用 | Stars-One的杂货小窝

本篇讲解下关于Image的使用及使用Coil开源库异步加载网络图片显示

本系列以往文章请查看此分类链接Jetpack compose学习

Image使用

首先,先看下参数

fun Image(
painter: Painter,
contentDescription: String?,
modifier: Modifier = Modifier,
alignment: Alignment = Alignment.Center,
contentScale: ContentScale = ContentScale.Fit,
alpha: Float = DefaultAlpha,
colorFilter: ColorFilter? = null
)

可以看到Image图片的参数大体上是和是Icon一样,基本使用呢,和上一篇讲的Icon类似,我们加载一张本地的图片,代码如下

Image(painter = painterResource(id = R.drawable.download),
contentDescription = null
)

比较基础的参数这里就不再赘述了,这里主要讲解下面的其他参数

1.alignment

图片对齐方向,前提是Image设置了宽高,取值为Alignment的定义的枚举

设置宽高是通过Modifier.size()来设置

取值有图中几种:

注意: 图中特意方框围起来的,其返回值不是Alignment类型的,这几个并不能取,你选了的话编辑器也会贴心的给出错误提示的 笑

这个alignment参数有九种取值,将一个固定的长方形分为九块,如下图所示

Column() {
//为了便于区分,这里使用Modifier添加了个黄色的背景
Image(modifier = Modifier.size(200.dp,300.dp).background(color = Color.Yellow),
//图片自己随便找张即可
painter = painterResource(id = R.drawable.download),
contentDescription = null,
alignment = Alignment.Center)
}

可以看到实际效果中,图片是居中对齐的,其他效果也就不一一展示了

2.contentScale

图片缩放设置,和原生的ImageView的scaleType属性类似,取值是ContentScale的枚举,默认是ContentScale.Fit(即自适应)

  • ContentScale.Crop 裁剪
  • ContentScale.FillBounds 拉伸图片宽高填满形状
  • ContentScale.FillHeight 拉伸图片高度填满高度
  • ContentScale.FillWidth 拉伸图片宽填满宽度
  • ContentScale.Fit
  • ContentScale.Inside
  • ContentScale.None 不缩放

这个也是需要Image设置宽高才可以看出效果

下面演示各种不同效果的Image(由于Fit是默认的,下面就没展示出来了)

代码如下

Column(Modifier.verticalScroll(rememberScrollState())) {
//为了便于区分,这里使用Modifier添加了个黄色的背景
Image(modifier = Modifier
.size(200.dp, 150.dp)
.background(color = Color.Yellow),
painter = painterResource(id = R.drawable.download),
contentDescription = null,
contentScale = ContentScale.Crop) Image(modifier = Modifier
.size(200.dp, 150.dp)
.background(color = Color.Yellow),
painter = painterResource(id = R.drawable.download),
contentDescription = null,
contentScale = ContentScale.Inside) Image(modifier = Modifier
.size(200.dp, 150.dp)
.background(color = Color.Yellow),
painter = painterResource(id = R.drawable.download),
contentDescription = null,
contentScale = ContentScale.FillBounds) Image(modifier = Modifier
.size(200.dp, 150.dp)
.background(color = Color.Yellow),
painter = painterResource(id = R.drawable.download),
contentDescription = null,
contentScale = ContentScale.FillHeight) Image(modifier = Modifier
.size(200.dp, 150.dp)
.background(color = Color.Yellow),
painter = painterResource(id = R.drawable.download),
contentDescription = null,
contentScale = ContentScale.FillWidth) Image(modifier = Modifier
.size(200.dp, 150.dp)
.background(color = Color.Yellow),
painter = painterResource(id = R.drawable.download),
contentDescription = null,
contentScale = ContentScale.None)
}

3.alpha

透明度,数值类型为float,数值范围为0f-1f之间,默认是1f

如下代码所示

Image(modifier = Modifier
.size(200.dp, 150.dp)
.background(color = Color.Yellow),
painter = painterResource(id = R.drawable.download),
contentDescription = null,
alpha = 1f
) Image(modifier = Modifier
.size(200.dp, 150.dp)
.background(color = Color.Yellow),
painter = painterResource(id = R.drawable.download),
contentDescription = null,
alpha = 0.5f)

效果如下图所示

4.colorFilter

着色效果,可以使用颜色对图片进行混合加工,有下面三种方法进行设置

  • ColorFilter.tint(Color, BlendMode) 着色效果
  • ColorFilter.lighting(Color,Color)
  • ColorFilter.colorMatrix(colorMatrix)

这个我不是研究太多,各位可以百度参考下其他大神写的文章

这里就讲个小例子,改变图片的颜色

美工给的图标有些是单一的颜色,比如说选中后是蓝色,不选中是灰色的

但有时候项目需要更改颜色,如选中后要改为绿色,这个时候得要美工再次切图,十分麻烦

这个时候我们可以这个属性,去修改颜色,如下面代码

Image(modifier = Modifier
.size(200.dp, 150.dp),
painter = painterResource(id = R.drawable.eye_show),
contentDescription = null,
alpha = 1f,
colorFilter = ColorFilter.tint(color = Color.Green, BlendMode.SrcAtop)
)

效果:

R.drawable.eye_show图片原本是灰色的,现在被我们渲染成了绿色,这种方法比较适合那种单一颜色的图标文件

而且有了这种方法,我们甚至只需要一种灰色的图标即可,蓝色的图标就不需要,可以省下不少apk的体积大小

至于更多内容,需要各位去研究啦...

Coil图片异步加载库使用

上述我们一直使用的是本地图片,如果是网络图片,该怎么办呢?以往我们都是使用Glide加载,但现在由于Compose是采用State状态监测机制去渲染UI,所以如果我们自己去实现就会十分麻烦

刚好现在已经有大神整了框架,我们拿来使用即可

Coil这个框架是Accompanist的子库,那么Accompanist是什么呢?

Accompanist 是一组旨在扩充 Jetpack Compose 功能的第三方库集合,这个库中所提供的功能是开发者普遍需要的。

注: 写这篇文章后发现,在Accompanist0.16.0版本更新日志中,移除了Coil等图片加载的库,Coil好像是单独出来了,下面是摘自官方的更新说明:

Coil, Glide and Image Loading Core have been removed

After being deprecated in v0.14.0, it's time to remove the coil, glide and imageloading-core libraries. Some discussion about this can be seen on the Kotlin Slack: https://kotlinlang.slack.com/archives/CJLTWPH7S/p1627482619344000.

TL;DR: the recommendation is to move to Coil Compose.

迁移到此开源库coil-kt/coil: Image loading for Android backed by Kotlin Coroutines.

基本使用

基本流程,先导依赖

implementation("io.coil-kt:coil:1.3.2")

图片的painter参数使用rememberImagePainter此方法,可传入一个网络图片

Image(
painter = rememberImagePainter("https://img0.baidu.com/it/u=312301072,1324966529&fm=26&fmt=auto&gp=0.jpg"),
contentDescription = null,
modifier = Modifier.size(128.dp)
)

PS:不要忘记加网络权限<uses-permission android:name="android.permission.INTERNET" />哦!!

效果:

占位图 过渡及圆形裁剪

  • 占位图 placeholder
  • 过渡 transitions
  • 变化效果 transformations

由于是网络图片,我们在预览界面是无法看到有图片的,这个时候我们可以考虑设置下占位图片,好方便调试UI

Image(
modifier = Modifier.size(128.dp),
painter = rememberImagePainter(
data = "https://img0.baidu.com/it/u=312301072,1324966529&fm=26&fmt=auto&gp=0.jpg",
builder = {
//占位图
placeholder(R.drawable.placeholder)
//淡出效果
crossfade(true)
//圆形效果
transformations(CircleCropTransformation())
}
),
contentDescription = null,
)

预览界面可以看到占位图

加载网络的图片过渡效果:

可能图中看不出圆形裁剪,我们可以加上背景看看,图片其实已经是被裁剪了的

目前,Coil自带了两种过渡效果:

  • CrossfadeTransition 从当前可绘制到成功/错误可绘制的淡入淡出(即上文代码出现的crossfade)
  • Transition.NONE它在Target没有动画的情况下立即设置可绘制对象。

    想要实现自定义,可以参考下CrossfadeTransition源代码,本文就不过多展开了

transformations主要是变化的意思,官方的解释是

transformations允许您在Drawable从请求返回之前修改图像的像素数据。

Coil默认提供了4种类型 blur(高斯模糊) circle crop(圆形裁剪) grayscale(灰度) rounded corners(圆角)

对应的代码如下:

//radis是外层圆角,sample为高斯模糊的程度(要大于1f即可)
BlurTransformation(context,radius,sample) //灰度
GrayscaleTransformation() //圆角
RoundedCornersTransformation(0.8f)

效果如下所示

源代码:

@ExperimentalCoilApi
@Preview(showBackground = true)
@Composable
fun ImagePageDemo() { val context = LocalContext.current
ComposeDemoTheme {
Column(Modifier.verticalScroll(rememberScrollState())) {
/*Image(
painter = rememberImagePainter("https://img0.baidu.com/it/u=312301072,1324966529&fm=26&fmt=auto&gp=0.jpg"),
contentDescription = null,
modifier = Modifier.size(128.dp),
)*/
Image(
modifier = Modifier.size(128.dp).background(Color.Blue),
painter = rememberImagePainter(
data = "https://img0.baidu.com/it/u=312301072,1324966529&fm=26&fmt=auto&gp=0.jpg",
builder = {
crossfade(true)
placeholder(R.drawable.placeholder)
transformations(BlurTransformation(context,0.1f,2f))
}
),
contentDescription = null,
)
Image(
modifier = Modifier.size(128.dp).background(Color.Blue),
painter = rememberImagePainter(
data = "https://img0.baidu.com/it/u=312301072,1324966529&fm=26&fmt=auto&gp=0.jpg",
builder = {
crossfade(true)
placeholder(R.drawable.placeholder)
transformations(GrayscaleTransformation())
}
),
contentDescription = null,
)
Image(
modifier = Modifier.size(128.dp).background(Color.Blue),
painter = rememberImagePainter(
data = "https://img0.baidu.com/it/u=312301072,1324966529&fm=26&fmt=auto&gp=0.jpg",
builder = {
crossfade(true)
placeholder(R.drawable.placeholder)
transformations(RoundedCornersTransformation(0.8f))
}
),
contentDescription = null,
)
} }
}

加载gif

需要添加依赖插件包

implementation("io.coil-kt:coil-gif:1.3.2")
val context = LocalContext.current
val imageLoader = ImageLoader.Builder(context)
.componentRegistry {
add(GifDecoder())
add(SvgDecoder(context))
}
.build() Image(
modifier = Modifier.size(128.dp).background(Color.Blue), painter = rememberImagePainter(
data = "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.zcool.cn%2Fcommunity%2F01bdd05a436090a80121974142c9f3.gif&refer=http%3A%2F%2Fimg.zcool.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1634225053&t=eaa097d38a32f901b7096fae16bfb98f",
builder = {
//加了这个解码,如果图片是jpg等格式,是没法成功解析出来的
decoder(GifDecoder())
crossfade(true)
placeholder(R.drawable.placeholder)
}
),
contentDescription = null,
)

效果如下所示

PS:上述代码是我自己大概摸索出来的,没想到竟然能用...

官方给的文档一直没有个标准的使用例子,也不知道上面这样写对不对,仅供参考

下面这个好像是正确的代码,image可以同时支持加载gif或者是jpg等图片

Column() {
val context = LocalContext.current
//创建图片加载器
val myImageLoader = ImageLoader.Builder(context)
.componentRegistry {
//这里可以加多个图片解码器
add(GifDecoder())
}
.build() Image(
modifier = Modifier
.size(128.dp)
.background(Color.Blue),
painter = rememberImagePainter(
data = "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.zcool.cn%2Fcommunity%2F01bdd05a436090a80121974142c9f3.gif&refer=http%3A%2F%2Fimg.zcool.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1634225053&t=eaa097d38a32f901b7096fae16bfb98f",
//设置图片加载器
imageLoader = myImageLoader,
builder = {
crossfade(true)
placeholder(R.drawable.placeholder) }
),
contentDescription = null,
)
}

加载svg

如gif一样,也是要加个插件依赖,之后注册即可

implementation("io.coil-kt:coil-svg:1.3.2")
val context = LocalContext.current
//创建图片加载器
val myImageLoader = ImageLoader.Builder(context)
.componentRegistry {
add(GifDecoder())
add(SvgDecoder(context))
}
.build()

补充

下面的都是一样的,不过使用Coil加载图片会出现图片放大后失真问题,所以有另外款开源库推荐landscapist

implementation "com.github.skydoves:landscapist-coil:1.3.2"
CoilImage(
imageModel = "https://coil-kt.github.io/coil/images/coil_logo_black.svg",
contentDescription = null,
imageLoader = myImageLoader
)

参考

Jetpack Compose学习(4)——Image(图片)使用及Coil图片异步加载库使用的更多相关文章

  1. Cocos2d-js 开发记录:图片数据资源等的异步加载

    这里说的是在需要的使用加载图片,比如游戏中的某个关卡的图片,不用在游戏一开始就加载(万一用户玩不到那关,岂不是很冤,流量费了那么多),否则载入速度也慢.这种方式加载资源要用到cc.loader官方文档 ...

  2. 【JAVAWEB学习笔记】网上商城实战2:异步加载分类、Redis缓存分类和显示商品

    网上商城实战2 今日任务 完成分类模块的功能 完成商品模块的功能 1.1      分类模块的功能: 1.1.1    查询分类的功能: 1.1.2    查询分类的代码实现: 1.1.2.1  创建 ...

  3. [置顶] iOS学习笔记47——图片异步加载之EGOImageLoading

    上次在<iOS学习笔记46——图片异步加载之SDWebImage>中介绍过一个开源的图片异步加载库,今天来介绍另外一个功能类似的EGOImageLoading,看名字知道,之前的一篇学习笔 ...

  4. Android图片异步加载之Android-Universal-Image-Loader

    将近一个月没有更新博客了,由于这段时间以来准备毕业论文等各种事务缠身,一直没有时间和精力沉下来继续学习和整理一些东西.最近刚刚恢复到正轨,正好这两天看了下Android上关于图片异步加载的开源项目,就 ...

  5. [置顶] Android图片异步加载之Android-Universal-Image-Loader

    将近一个月没有更新博客了,由于这段时间以来准备毕业论文等各种事务缠身,一直没有时间和精力沉下来继续学习和整理一些东西.最近刚刚恢复到正轨,正好这两天看了下Android上关于图片异步加载的开源项目,就 ...

  6. Android-Universal-Image-Loader 图片异步加载类库的使用

    在博客中看到一篇利用组件进行图片异步加载的文章在此作记录 原文:http://blog.csdn.net/vipzjyno1/article/details/23206387 这个图片异步加载并缓存的 ...

  7. Android-Universal-Image-Loader 图片异步加载类库的使用(超详细配置)

    这个图片异步加载并缓存的类已经被很多开发者所使用,是最常用的几个开源库之一,主流的应用,随便反编译几个火的项目,都可以见到它的身影. 可是有的人并不知道如何去使用这库如何进行配置,网上查到的信息对于刚 ...

  8. android异步加载图片并缓存到本地实现方法

    图片过多造成内存溢出,这个是最不容易解决的,要想一些好的缓存策略,比如大图片使用LRU缓存策略或懒加载缓存策略.今天首先介绍一下本地缓存图片     在android项目中访问网络图片是非常普遍性的事 ...

  9. 【转】Android-Universal-Image-Loader 图片异步加载类库的使用(超详细配置)

    Android-Universal-Image-Loader 原文地址:http://blog.csdn.net/vipzjyno1/article/details/23206387 这个图片异步加载 ...

  10. 解决ListView滑动时卡的问题,实现异步加载图片解决

    ListView是最为常见的空间之一,现在的应用的呈现形式大多数都需要用到ListView来呈现,以列表的方式最直观最便于操作. 那么在使用的过程中大家一定使用adapter适配器来匹配这个ListV ...

随机推荐

  1. 【大前端之打通账号系统】passport应该如何落地?

    前言 之前接入百度账号系统的时候写了一篇博客做研究:[大前端]认识单点登录,出来后才发现,很多小公司其实并没有将账号系统打通,总结一下账号系统没通的原因是: ① 最初设计就没想过身份认证应该做整合 ② ...

  2. Python自动化测试(1)-自动化测试及基本技术手段概述

    生产力概述 在如今以google为首的互联网时代,软件的开发和生产模式都已经发生了变化, 在<参与感>一书提到:某位从微软出来的工程师很困惑,微软在google还有facebook这些公司 ...

  3. Eclipse中Ctrl+方法名发现无法进入到该方法中……

    我现在的情况是,按住Ctrl点击该方法后,发现进入不到这个方法的定义. 后来我发现,是因为这个项目是在某个项目文件夹中,如下: 这时直接找到server这个项目就没有问题了,如图:

  4. How Tomcat Works读书笔记之升级架构

    上一篇HttpServer类职责很多,包括启动服务器,创建ServerSocket,得到客户端Socket,创建Request对象和Response对象,并解析Http请求,这样很混乱,不利于以后服务 ...

  5. [Objective-c 基础 - 3.1] 内存管理

    A.内存存放.retain.release 1.栈内存:存放局部变量,运行超过变量作用域自后编译器自动回收 2.堆内存:存放对象(地址,对象实体) 3.对象的基本结构 (1)引用计数器(4字节):当计 ...

  6. 【转】Linux(ubuntu14.04)上编译Android4.4源码的环境搭建及编译全过程

    原文网址:http://jileniao.net/linux-android-building.html sublime text让我伤心.本来很信任sublime text的自动保存功能,之前使用一 ...

  7. 自己实现一个SQL解析引擎

    自己实现一个SQL解析引擎 功能:将用户输入的SQL语句序列转换为一个可运行的操作序列,并返回查询的结果集. SQL的解析引擎包含查询编译与查询优化和查询的执行,主要包含3个步骤: 查询分析: 制定逻 ...

  8. Python中函数的嵌套及闭包

    函数的嵌套 调用:在函数中调用函数 定义:在函数中定义函数 地址:函数名有内存地址,内存地址可赋值 示例 a = 1 def outer(): a = 1 def inner(): a = 2 def ...

  9. mysql----------mysql5.7如何配置主从数据库

    主库: 1.配置文件里面加入以下两行 server-id=1 log-bin=MySQL-bin 2.创建账户 grant replication client,replication slave o ...

  10. Shell 编程 (变量和条件测试)

    变量: 1 . 变量声明 直接使用变量 + 赋值 #!/bin/bash NAME='HELLO WORD' echo $NAME 使用 declare 关键字声明 declare(选项)(参数) + ...