[Android]Jetpack Compose加载图标和图片

一、加载本地矢量图标

在 Android 开发中使用本地矢量图标是一种常见的做法,因为矢量图标(通常保存为 SVG 或 Android 的 XML vector format)具有可缩放性和较小的文件大小。

在 Jetpack Compose 中加载本地矢量图标可以使用内置的支持,也可以通过流行的第三方库来实现。

矢量图在线查询:https://fonts.google.com/icons?icon.set=Material+Icons

1.使用 Jetpack Compose 加载本地矢量图标

Jetpack Compose 原生支持加载 Android Vector Drawable 格式的图标。这些图标可以直接在 res/drawable 目录下以 XML 格式存储。

(1).创建 Vector Drawable

首先,在 res/drawable 目录中创建一个 Vector Drawable 文件。

例如,创建一个名为 ic_arrow_back.xml 的文件。

Kotlin 复制代码
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <path
        android:fillColor="#FF000000"
        android:pathData="M11,19l-7,-7 7,-7 1.41,1.41L6.83,12l5.58,5.59z"/>
</vector>

(2).在 Compose 中使用 Vector Drawable

在 Compose 函数中使用 painterResource 来加载并显示这个矢量图标。

Kotlin 复制代码
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.painterResource
import com.example.myapp.R

@Composable
fun BackIcon() {
    Image(
        painter = painterResource(R.drawable.ic_arrow_back),
        contentDescription = "返回"
    )
}

2.使用流行的Material Icons库加载矢量图标

(1).使用material-icons-core库提供的基础矢量图标

在 Jetpack Compose 中,androidx.compose.material:material-icons-core 库提供了一组基本的 Material Design 图标,这个库是 androidx.compose.material:material 的一部分,通常已经包含在默认的 Compose 设置中。

Kotlin 复制代码
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material3.Icon

@Composable
fun ExtendedIconExample() {
    Icon(imageVector = Icons.Filled.ArrowBack, contentDescription = "返回")
}

(2).添加 material-icons-extended库拓展矢量图标

这个库包含了更为广泛的图标集合,覆盖了更多的用例和设计需求。如果你需要更多特定的图标,比如 Icons.Filled.ArrowBackIos,就需要导入这个扩展库。

确保在项目的 build.gradle 文件中添加了 material-icons-extended 库的依赖。

查询最新版本:Maven Central: Search

Kotlin 复制代码
dependencies {
    implementation('androidx.compose.material:material-icons-extended:1.6.2')  // 使用适合你项目的版本
}
Kotlin 复制代码
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBackIos
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable

@Composable
fun ExtendedIconExample() {
    Icon(
        imageVector = Icons.AutoMirrored.Filled.ArrowBackIos,
        contentDescription = "iOS风格的返回图标"
    )
}

虽然你可能包含了 material-icons-extended 库,这个库确实包含了大量的图标资源,但是 Android 的构建系统(包括 Gradle 和 Android Studio)使用了一种称为资源清理(resource shrinking)的技术,这可以帮助移除未使用的资源,以减少最终 APK 的大小。

二、加载本地图片资源

1. 加载 Drawable 资源

如果你的图片已经作为资源文件存储在 res/drawableres/mipmap 目录下,你可以使用 painterResource 方法来加载这些图片。这是最常见的方法,用于加载静态资源。

Kotlin 复制代码
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.painterResource
import com.example.myapp.R

@Composable
fun LoadDrawableResource() {
    Image(
        painter = painterResource(id = R.drawable.my_image),
        contentDescription = "描述性文本"
    )
}

2. 加载 Asset 资源

assets 文件夹通常用于存储那些不会通过 Android 资源系统进行访问的文件,如字体文件、数据文件或图片等。

  • 在Android工程的main目录,选择 New > Folder > Assets Folder。按照向导完成assets文件夹的创建。
  • 将你想要在应用中使用的图片文件复制到这个新创建的 assets 文件夹中。你可以创建子文件夹来组织你的文件。

如果你的图片存储在 assets 文件夹中(这不同于资源文件夹 res),你需要使用 painterResource 方法的另一个形式或者 rememberImagePainter(需要引入外部库 Coil)来加载这些图片。

(1).使用基础库

Kotlin 复制代码
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.assetPainter

@Composable
fun LoadAssetImage() {
    Image(
        painter = assetPainter("images/my_image.png"),
        contentDescription = "描述性文本"
    )
}

(2).使用 Coil

Coil 是一个流行的 Kotlin 图像加载库,它可以与 Compose 配合使用。

首先,添加 Coil 的依赖:

Kotlin 复制代码
dependencies {
    implementation('io.coil-kt:coil-compose:2.6.0') 
}

然后,使用 rememberImagePainter 来加载图片:

Kotlin 复制代码
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import coil.compose.rememberImagePainter

@Composable
fun LoadAssetImageWithCoil() {
    Image(
        painter = rememberImagePainter("file:///android_asset/images/my_image.png"),
        contentDescription = "描述性文本"
    )
}

3. 从文件系统加载图片

如果图片存储在设备的文件系统中,可以使用 Coil 来加载这些图片。

Kotlin 复制代码
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import coil.compose.rememberImagePainter
import java.io.File

@Composable
fun LoadImageFromFile(file: File) {
    Image(
        painter = rememberImagePainter(file),
        contentDescription = "描述性文本"
    )
}

三、加载网络图片

虽然 Jetpack Compose 本身不提供直接加载网络图片的组件,但可以很容易地通过集成第三方库如 Coil 或 Glide 来实现。这里主要介绍使用 Coil 来加载网络图片,因为 Coil 被设计为支持 Kotlin 协程,且与 Jetpack Compose 集成良好。

1.使用 Coil 加载网络图片

Coil (Coil-kt) 是一个现代的图片加载库,它使用 Kotlin 协程进行异步加载,并且为 Compose 提供了专门的支持。

(1).添加 Coil 的依赖

Kotlin 复制代码
dependencies {
    implementation('io.coil-kt:coil-compose:2.6.0') 
}

(2).编写 Compose 函数以加载和显示图片

在你的 Composable 函数中,使用 rememberImagePainter 来创建一个 Painter 对象,该对象负责异步加载图片。然后,你可以使用 Image 组件来显示这张图片。

Kotlin 复制代码
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import coil.compose.rememberImagePainter

@Composable
fun NetworkImage(url: String) {
    val painter = rememberImagePainter(data = url, builder = {
        placeholder(R.drawable.placeholder) // 加载中的占位图
        error(R.drawable.error) // 错误时的图片
    })
    Image(
        painter = painter,
        contentDescription = "网络图片",
        modifier = Modifier.fillMaxWidth() // 根据需要调整修饰符
    )
}

在这个例子中,url 是图片的网络地址。placeholdererror 是可选的,分别用于在图片加载时和加载失败时显示的图片。这些图片需要放在你的资源目录(res/drawable)下。

2.Coil 的高级配置

Coil 提供了许多配置选项来自定义图片加载的行为,例如缓存策略、图片解码、请求优先级等。你可以在 builder lambda 表达式中配置这些选项。

Kotlin 复制代码
val painter = rememberImagePainter(data = url, builder = {
    crossfade(true) // 启用淡入淡出效果
    transformations(CircleCropTransformation()) // 应用圆形裁剪
})

3.处理图片加载状态

Coil 提供了监听加载状态的功能,可以用来显示加载进度、处理错误或其他自定义行为。

Kotlin 复制代码
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.CircularProgressIndicator
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import coil.compose.AsyncImage
import coil.compose.AsyncImagePainter

@Composable
fun NetworkImageWithStatus(url: String) {
    Box(contentAlignment = Alignment.Center) {
        val painter = rememberImagePainter(url)
        Image(painter = painter, contentDescription = "网络图片")
        when (painter.state) {
            is AsyncImagePainter.State.Loading -> CircularProgressIndicator()
            is AsyncImagePainter.State.Error -> Text("加载失败")
            else -> {} // 在其他状态不显示任何东西
        }
    }
}

四、加载本地其它资源文件

在 Jetpack Compose 中加载本地资源文件主要涉及到两种常见的资源:图片和其他类型的文件(例如文本文件或JSON文件)。

1.添加文件到资源目录

将你的文件(如 example.txt 或 data.json)放入 res/raw 文件夹中。如果该文件夹不存在,你可以创建它。

2.在 Compose 中读取文件

你需要使用 Android 的资源管理 API 来读取这些文件。这通常不是在 Composable 函数中直接完成的,而是应该在 ViewModel 或其他数据管理类中处理。

Kotlin 复制代码
import android.content.Context
import androidx.compose.runtime.Composable
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewmodel.compose.viewModel

class FileViewModel(private val context: Context) : ViewModel() {
    fun readRawResource(): String {
        val inputStream = context.resources.openRawResource(R.raw.example)
        return inputStream.bufferedReader().use { it.readText() }
    }
}

@Composable
fun DisplayFileContents(viewModel: FileViewModel = viewModel()) {
    val contents = viewModel.readRawResource()
    Text(text = contents)
}

在这个例子中,R.raw.example 是你放在 res/raw 目录下的文件的资源 ID。

五、处理图像的缩放和裁剪

1.图像的缩放

缩放通常涉及调整图像的大小以适应或填充特定的空间。在 Compose 中,这可以通过设置 Image 组件的 contentScale 属性来实现:

  • ContentScale.Fit - 图像将被统一缩放(保持图像的宽高比),以确保整个图像适配容器的边界。这通常意味着图像的某些边可能不会触及容器的边界。
  • ContentScale.Crop - 图像将被统一缩放(保持图像的宽高比),直到填满容器的边界,可能会裁剪图像的部分内容。
  • ContentScale.FillBounds - 图像将被缩放以完全填充容器,但不保持宽高比,可能导致图像失真。
  • ContentScale.FillHeight / ContentScale.FillWidth - 图像将被缩放以填充容器的高度或宽度,同时保持图像的宽高比。
Kotlin 复制代码
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource

@Composable
fun ScaledImage() {
    Image(
        painter = painterResource(id = R.drawable.your_image),
        contentDescription = "缩放的图像",
        modifier = Modifier.fillMaxSize(),
        contentScale = ContentScale.Crop // 根据需求选择适合的缩放模式
    )
}

2.图像的裁剪

在 Jetpack Compose 中,裁剪图像通常可以通过使用 clip Modifier 和 Shape 来实现。这允许你创建各种形状(如圆形、矩形等),并且只显示图像的相应部分。

Kotlin 复制代码
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ClipOp
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp

@Composable
fun CroppedImage() {
    Image(
        painter = painterResource(id = R.drawable.your_image),
        contentDescription = "裁剪的图像",
        modifier = Modifier
            .size(150.dp)
            .clip(CircleShape) // 使用圆形裁剪,也可以使用 RoundedCornerShape(10.dp) 等其他形状
    )
}

在这个例子中,使用 CircleShape 来裁剪图像为圆形。如果希望有圆角矩形,可以改用 RoundedCornerShape 并指定角的半径。

相关推荐
水瓶丫头站住15 分钟前
安卓APP如何适配不同的手机分辨率
android·智能手机
xvch1 小时前
Kotlin 2.1.0 入门教程(五)
android·kotlin
xvch5 小时前
Kotlin 2.1.0 入门教程(七)
android·kotlin
望风的懒蜗牛5 小时前
编译Android平台使用的FFmpeg库
android
浩宇软件开发5 小时前
Android开发,待办事项提醒App的设计与实现(个人中心页)
android·android studio·android开发
ac-er88886 小时前
Yii框架中的多语言支持:如何实现国际化
android·开发语言·php
苏金标7 小时前
The maximum compatible Gradle JVM version is 17.
android
zhangphil7 小时前
Android BitmapShader简洁实现马赛克,Kotlin(一)
android·kotlin
iofomo11 小时前
Android平台从上到下,无需ROOT/解锁/刷机,应用级拦截框架的最后一环,SVC系统调用拦截。
android
我叫特踏实12 小时前
SensorManager开发参考
android·sensormanager