Jetpack Compose基础组件 - Image

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
)

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

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

@Composable
fun ImageScreen1() {
    Image(
        painter = painterResource(id = R.drawable.ic_launcher_background),
        contentDescription = null
    )
}

@Preview(showBackground = true)
@Composable
fun ImageScreenPreview1() {
    ImageScreen1()
}

图片大小

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

@Composable
fun ImageScreen1() {
    Image(
        painter = painterResource(id = R.drawable.ic_launcher_foreground),
        contentDescription = null,
        modifier = Modifier.size(350.dp)
    )
}

图片形状

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

@Composable
fun ImageScreen() {
    Surface(
        shape = CircleShape
    ) {
        Image(
            painter = painterResource(id = R.drawable.wallpaper),
            contentDescription = null,
            modifier = Modifier.size(350.dp)
        )
    }

}

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

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

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

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

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

@Composable
fun ImageScreen() {
    Surface(
        shape = CircleShape
    ) {
        Image(
            painter = painterResource(id = R.drawable.wallpaper),
            contentDescription = null,
            modifier = Modifier.size(350.dp),
            contentScale = ContentScale.Crop
        )
    }

}

图像边框

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

@Composable
fun ImageScreen() {
    Surface(
        shape = CircleShape,
        border = BorderStroke(5.dp, Color.Gray)
    ) {
        Image(
            painter = painterResource(id = R.drawable.wallpaper),
            contentDescription = null,
            modifier = Modifier.size(350.dp),
            contentScale = ContentScale.Crop
        )
    }
}

使用 Coil 来动态加载图片

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

<uses-permission android:name="android.permission.INTERNET" />
implementation("io.coil-kt:coil-compose:2.4.0")
Image(
    painter = rememberAsyncImagePainter(data = "https://picsum.photos/300/300"),
    contentDescription = null
)

加载Gif图像

implementation("io.coil-kt:coil-gif:2.4.0") // KTS
val gif_url="https://s1.chu0.com/src/img/gif/db/dba873378578488a9de51f01c101cd6a.gif?e=1735488000&token=1srnZGLKZ0Aqlz6dk7yF4SkiYf4eP-YrEOdM1sob:ENutG45YK-AdEpn2dSKWQRZ_8qY="

val imageLoader = ImageLoader.Builder(context)
        .components {
            if (SDK_INT >= 28) {
                add(ImageDecoderDecoder.Factory())
            } else {
                add(coil.decode.GifDecoder.Factory())
            }
        }
        .build()

Image(
    painter = rememberAsyncImagePainter(
        gif_url,
        imageLoader = imageLoader
    ),
    contentDescription = null
)

加载 Svg 图像

Coil 可以加载 Svg 图像

添加依赖

implementation("io.coil-kt:coil-svg:2.4.0") // KTS
val imageLoader = ImageLoader.Builder(context)
        .components {
            add(SvgDecoder.Factory(true))
        }
        .build()

Image(
    painter = rememberAsyncImagePainter(
        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 = rememberAsyncImagePainter(
                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()
                )
        )
    }
}

那么要解决这个问题,就是尝试实现 svg 转换为 vector drawable, 需要添加三方依赖 

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
)

Image 参数详情

Ucrop 一个图片裁剪库

Coil

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值