Jetpack Compose-image组件

举报
坚果的博客 发表于 2022/05/28 13:57:27 2022/05/28
【摘要】 Image@Composablefun Image( painter: Painter, contentDescription: String?, modifier: Modifier = Modifier, alignment: Alignment = Alignment.Center, contentScale: ContentScale = Content...

Image

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


INFO

目前在 ComposeImage 有三种,详情可先在官网中找到

Image 可以帮我们加载一张图片。

@Composable
fun ImageDemo() {
​
    Image(
        painter = painterResource(id = R.drawable.wallpaper),
        contentDescription = null
    )
​
}


image-20220527150029151

1. 图片大小

我们可以使用 Modifier.size() 来设置图片大小。

@Composable
fun ImageDemo() {
 Image(
        painter = painterResource(id = R.mipmap.ic_launcher),
        contentDescription = null,
        modifier = Modifier.size(70.dp)
    )
​
}

image-20220527150749731

2. 图片形状

我们可以使用 Surface 来帮助我们设置形状,或者在 Image 组件中使用 modifier.clip() 来裁剪形状。

@Composable
fun ImageDemo() {
    Surface(
        shape = CircleShape
    ){ Image(
        painter = painterResource(id = R.mipmap.ic_launcher),
        contentDescription = null,
        modifier = Modifier.size(70.dp)
    )}
​
​
}


image-20220527150852657

是不是有一点小问题?似乎只有左右两边变成了圆形,而上下并没有。

这是因为 Image 中源码的 contentScale 参数默认是 ContentScale.Fit

也就是保持图片的宽高比,缩小到可以完整显示整张图片。

ContentScale.Crop 也是保持宽高比,但是尽量让宽度或者高度完整的占满。

所以我们将 contentScale 设置成 ContentScale.Crop

@Composable
fun ImageDemo() {
    Surface(
        shape = CircleShape
    ){ Image(
        painter = painterResource(id = R.mipmap.ic_launcher),
        contentDescription = null,
        modifier = Modifier.size(70.dp),
        contentScale = ContentScale.Crop
    )}
​
​
}
​


image-20220527151021427

3. 图像边框

你可以利用 Surface 中的 border 参数来设置边框。

@Composable
fun ImageDemo() {
    Surface(
        shape = CircleShape,
        border = BorderStroke(5.dp, Color.Gray)
    ){ Image(
        painter = painterResource(id = R.mipmap.ic_launcher),
        contentDescription = null,
        modifier = Modifier.size(70.dp),
        contentScale = ContentScale.Crop
    )}
​
​
}


image-20220527151212633

4. 使用 Coil 来动态加载图片

Compose 自带的 Image 只能加载资源管理器中的图片文件,如果想加载网络图片或者是其他本地路径下的文件,则需要考虑其他的库,比如 Coil

简单使用 Coil 加载网络图片:

记得打开网络权限测试

<uses-permission android:name="android.permission.INTERNET" />


​
​
package com.example.composestudy
​
​
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import coil.compose.rememberAsyncImagePainter
import coil.compose.rememberImagePainter
import com.example.composestudy.ui.theme.ComposestudyTheme
​
​
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ComposestudyTheme {
                ImageDemo()
            }
        }
    }
}
​
​
​
@Composable
fun ImageDemo() {
    Surface(
        shape = CircleShape,
        border = BorderStroke(5.dp, Color.Gray)
    ){ Image(
        painter = rememberAsyncImagePainter(model = "https://luckly007.oss-cn-beijing.aliyuncs.com/macimages/41pMi8LYH1L.jpeg"),
        contentDescription = null
    )}
​
​
}
​
@Preview(name = "Light Mode")
​
@Composable
fun PreviewMessageCard() {
    ComposestudyTheme {
​
        ImageDemo()
    }
}

image-20220527155601910

加载 Svg 图像

Coil 可以加载 Svg 图像

添加依赖

implementation "io.coil-kt:coil-svg:1.3.2" // Gradle
implementation("io.coil-kt:coil-svg:1.3.2") // KTS


val context = LocalContext.current
val imageLoader = ImageLoader.Builder(context)
    .componentRegistry {
        add(SvgDecoder(context))
    }
    .build()
​
Image(
    painter = rememberImagePainter(
        data = "https://coil-kt.github.io/coil/images/coil_logo_black.svg",
        imageLoader = imageLoader
    ),
    contentDescription = null
)


放大缩小 Svg 图像文件

虽然 Coil 可以显示 Svg 图像,但是如果在我们的 app 中,需要动态的放大 Svg 图像,那么你大概率会得到强行拉升 Svg 像素后的图像,而不是无损放大

导致的原因可能是 Coil 中的 ImageLoader 会把 Svg 转换成位图,而不是安卓的矢量图 vector drawable, 而位图则不能无损放大

val context = LocalContext.current
val imageLoader = ImageLoader.Builder(context)
    .componentRegistry {
        add(SvgDecoder(context))
    }
    .build()
​
var flag by remember { mutableStateOf(false) }
val size by animateDpAsState(targetValue = if(flag) 450.dp else 50.dp)
​
Box(
    modifier = Modifier.fillMaxSize(),
    contentAlignment = Alignment.Center
) {
    Column {
        Image(
            painter = rememberImagePainter(
                data = "https://coil-kt.github.io/coil/images/coil_logo_black.svg",
                imageLoader = imageLoader
            ),
            contentDescription = null,
            modifier = Modifier
                .size(size)
                .clickable(
                    onClick = {
                        flag = !flag
                    },
                    indication = null,
                    interactionSource = MutableInteractionSource()
                )
        )
    }
}


img

那么要解决这个问题,就是尝试实现 svg 转换为 vector drawable, 在 github 上可以搜索到这个库 Svg to Compose,但是它并不能支持动态加载图像,例如从网络上加载,或者是从 app 的内部存储或者外部存储加载。

但是在我搜寻中,发现了 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,
    modifier = Modifier
        .size(size)
        .clickable(
            onClick = {
                flag = !flag
            },
            indication = null,
            interactionSource = MutableInteractionSource()
        ),
    imageLoader = imageLoader
)


img

5. 更多

Image 参数详情

Ucrop 一个图片裁剪库

Coil

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。