ImageView

我们知道Android View中ImageView用来显示图片,而Compose中我们使用Image展示图片,来看看简单用法:

// Image用法
Image(
    painter = painterResource(id = R.drawable.ic_launcher_background),
    contentDescription = "这是一张图片"
)

上面使用了像素画painterResource方法传入了图片Id资源,并添加了文字描述,非常简单,看下效果:

《Jetpack Compose系列学习》-9 Compose的简单控件之Image、ProgressBar

接下来看看Image的源码,了解它的更多使用方法:

@Composable
fun Image( // 构造方法1
    bitmap: ImageBitmap,
    contentDescription: String?, // 图片描述文本
    modifier: Modifier = Modifier, // 修饰符
    alignment: Alignment = Alignment.Center, // 对齐参数
    contentScale: ContentScale = ContentScale.Fit, // 缩放比例
    alpha: Float = DefaultAlpha, // 透明度
    colorFilter: ColorFilter? = null // 颜色过滤器
) {
    // 省略...
}
@Composable
fun Image( // 构造方法2
    painter: Painter,
    contentDescription: String?,
    modifier: Modifier = Modifier,
    alignment: Alignment = Alignment.Center,
    contentScale: ContentScale = ContentScale.Fit,
    alpha: Float = DefaultAlpha,
    colorFilter: ColorFilter? = null
) {
    // 省略...
}

这俩重载方法,除了第一个参数不同外,其他的参数都一样,我们重点看看第一个参数的类型。

ImageBitmap

bitmap参数类型携程为ImageBitmap,不是Bitmap,是Compose中特有的类,可以通过Bi像素游戏tmap扩展方法asImag携程旅游网eBitmap将Bitmgithub打不开ap转成Image中需要的Imagebitmap像素工厂

val bitmap = BitmapFactory.decodeFile("图片路径")
Image(bitmap = bitmap.asImageBitmap(), contentDescription = "这是一张图片")
Painter

painter参数类型是Painter,是一个抽象类,有三个子类,最常用的是BitmapPainter。

《Jetpack Compose系列学习》-9 Compose的简单控件之Image、ProgressBar

由于直接使用BitmapPainter有些复杂,所以Compose为我们封装好了方法来生像素地牢成Painter,上面的例子中调用的painterResource就是官方推荐的方法,我们只需要传入资源Id即可。

设置图片样式

Image控件还有好几个参数没有使用,我们来看看各自有什么效果。

  1. alignment

alignment是可选对齐参数,类型为Alignment,用于将Image放置在由宽度和高度自定义的范围内,用法:

Image(
    painter = painterResource(id = R.drawable.ic_launcher_background),
    contentDescription = "这是一张图片",
    alignment = Alignment.Center
)

Alignment用场用于像素画定义父布局中子布局的像素冒险世界对齐方式,后面我们会一起学习这块。

  1. contentScale

用来设置横竖缩放比例,类型为ContentScale。如果布局边界大小和Image固定大小不同,可以选择scale参数来确定要使用的缩放比例携程。这里默认缩放方式为ContentScale.gitiFit,保持原图片的宽高比。当然它还有其它几种类型:

@Stable
interface ContentScale {
    /**
     * 计算比例因子以相互独立地应用于水平轴和垂直轴,以使源内容与给定的目标适配
     */
    fun computeScaleFactor(srcSize: Size, dstSize: Size): ScaleFactor
    /**
     * 伴生对象
     */
    companion object {
        /**
         * 保持图片的宽高比,以使图片的宽度和高度都等于或大于目标的相应尺寸。
         */
        @Stable
        val Crop = object : ContentScale {
            override fun computeScaleFactor(srcSize: Size, dstSize: Size): ScaleFactor =
                computeFillMaxDimension(srcSize, dstSize).let {
                    ScaleFactor(it, it)
                }
        }
        /**
         * 保持图片的宽高比,以使图片的宽度和高度都等于或小于目标的相应尺寸。
         */
        @Stable
        val Fit = object : ContentScale {
            override fun computeScaleFactor(srcSize: Size, dstSize: Size): ScaleFactor =
                computeFillMinDimension(srcSize, dstSize).let {
                    ScaleFactor(it, it)
                }
        }
        /**
         * 缩放图片,并保持宽高比,以使边界与目标高度匹配,如果高度大于宽度,则
         * 可以覆盖比目标更大的区域
         */
        @Stable
        val FillHeight = object : ContentScale {
            override fun computeScaleFactor(srcSize: Size, dstSize: Size): ScaleFactor =
                computeFillHeight(srcSize, dstSize).let {
                    ScaleFactor(it, it)
                }
        }
        /**
         * 缩放图片,并保持宽高比,以使边界与目标宽度匹配,如果宽度大于高度,则
         * 可以覆盖比目标更大的区域
         */
        @Stable
        val FillWidth = object : ContentScale {
            override fun computeScaleFactor(srcSize: Size, dstSize: Size): ScaleFactor =
                computeFillWidth(srcSize, dstSize).let {
                    ScaleFactor(it, it)
                }
        }
        /**
         * 如果图片大于目标,则缩放图片将宽高比保持在目标范围内
         * 如果源内容在宽高维度上都小于或者等于目标,则其行为类似于“无”。
         * 这将始终包含在目标范围内。
         */
        @Stable
        val Inside = object : ContentScale {
            override fun computeScaleFactor(srcSize: Size, dstSize: Size): ScaleFactor {
                return if (srcSize.width <= dstSize.width &&
                    srcSize.height <= dstSize.height
                ) {
                    ScaleFactor(1.0f, 1.0f)
                } else {
                    computeFillMinDimension(srcSize, dstSize).let {
                        ScaleFactor(it, it)
                    }
                }
            }
        }
        /**
         * 不对图片进行任何缩放
         */
        @Stable
        val None = FixedScale(1.0f)
        /**
         * 横向和纵向不均匀缩放以填充目标范围
         */
        @Stable
        val FillBounds = object : ContentScale {
            override fun computeScaleFactor(srcSize: Size, dstSize: Size): ScaleFactor =
                ScaleFactor(
                    computeFillWidth(srcSize, dstSize),
                    computeFillHeight(srcSize, dstSize)
                )
        }
    }
}

以上几种缩放方式可以根据具体项目需求github中文社区来使用携程旅行app官方下载

alpha

图片透明度,类型为Float,Image中alpha默认值是DefaultAlpha。

const val DefaultAlpha: Float = 1.0f

常量值为1.0f,图片完全不透明。如果设置成完全透明,则将alpha值设置成0f即可:

Box {
    Text(text = "这是一个文字")
    Image(
        painter = painterResource(id = R.drawable.ic_launcher_background),
        modifier = Modifier.size(200.dp, 200.dp),
        contentDescription = "这是一张图片",
        alignment = Alignment.Center,
        alpha = 0.1f
    )
}

《Jetpack Compose系列学习》-9 Compose的简单控件之Image、ProgressBar

这里容器我们携程电话用了Box,相当于Android View中gitlab的帧布局Framel携程电话ayout,一个文本Text,上面放置一张Image,将图片的透明度设置成0.1f后,图片下面的文字就能清晰的看到了。

colorFilter

colorFilter可以对Image进行着色,也可以为Imaggithub中文官网网页e设置颜色矩阵,还可以为Image创建简单的照明效果,来看看源码:

@Immutable
class ColorFilter internal constructor(internal val nativeColorFilter: NativeColorFilter) {
    companion object {
        /**
         * 创建一个颜色滤镜,该滤镜作为第二个参数给出的混合模式
         * 源颜色是第一个参数指定的颜色,目标颜色是来自要合成的图层颜色
         */
        @Stable
        fun tint(color: Color, blendMode: BlendMode = BlendMode.SrcIn): ColorFilter =
            actualTintColorFilter(color, blendMode)
        /**
         * 创建一个ColorFilter以通过4*5颜色矩阵转换颜色
         * 该滤镜可用于更改像素的饱和度,从YUV转换为RGB等
         */
        @Stable
        fun colorMatrix(colorMatrix: ColorMatrix): ColorFilter =
            actualColorMatrixColorFilter(colorMatrix)
        /**
         * 创建可用于模拟简单照明效果的ColorFilter
         * ColorFilter由两个参数定义,一个参数用于乘以源颜色,另一个参数用于添加至源颜色
         */
        @Stable
        fun lighting(multiply: Color, add: Color): ColorFilter =
            actualLightingColorFilter(multiply, add)
    }
}

我们来简携程电话单设置下ColorFilter:

Box {
    Text(text = "这是一个文字")
    Image(
        painter = painterResource(id = R.drawable.ic_launcher_background),
        modifier = Modifier.size(200.dp, 200.dp),
        contentDescription = "这是一张图片",
        alignment = Alignment.Center,
        alpha = 1.0f,
        colorFilter = ColorFilter.tint(Color.Red)
    )
}

《Jetpack Compose系列学习》-9 Compose的简单控件之Image、ProgressBar

显示网络图

Android中显示一张网络图片,最开始都是自己写网路请求,请求下载后的Bitmap再通过ImageView去显示,当然现在有现成的图片库Gli携程网上订票飞机de、Fresco等;在Compose中显示网络图也github打不开不难,只需要添加一个依赖库:

implementation 'com.google.accompanist:accompanist-coil:0.10.0'

coi像素生存者2l是一个很新的图片加载库,用kotlin开发的,使用了kotlin的协程,网络请求默认为Okhttp,特点:足够快,图片存储、内存、下载等都做了大幅度优化,支持Compose,里面实现了网络图片的可组合项。具体使用如下:

Box {
    Image(
        painter = rememberCoilPainter(request = "https://picsum.photos/300/300"),
        contentDescription = null
    )
}

《Jetpack Compose系列学习》-9 Compose的简单控件之Image、ProgressBar

我们看看remember携程机票CoilPainter的构造参数:

@Composable
fun rememberCoilPainter(
    request: Any?, // 图片地址
    imageLoader: ImageLoader = CoilPainterDefaults.defaultImageLoader(), // 请求图片时使用的ImageLoader,默认为CoilPainterDefaults.defaultImageLoader()
    shouldRefetchOnSizeChange: ShouldRefetchOnSizeChange = ShouldRefetchOnSizeChange { _, _ -> false }, // 大小更改时回调,允许可选地重新获取图片,返回true以重新获取图片
    requestBuilder: (ImageRequest.Builder.(size: IntSize) -> ImageRequest.Builder)? = null, // ImageRequest的可选生成器
    fadeIn: Boolean = false, // 成功加载图片后是否进行淡入动画
    fadeInDurationMs: Int = LoadPainterDefaults.FadeInTransitionDuration, // 淡入动画时长(单位毫秒)
    @DrawableRes previewPlaceholder: Int = 0, // 占位图
)

这个图片加载库的其他用法可以参考其官网:google.github.io/accompanist…

progressBar

进度条应用场景也很多,比如页面加载时的loading,下载文件时的进度、播放视频时的进度条等。

圆形像素勇士大创造攻略进度条

先看看Compose中怎样使用圆形进度条:

Row(
    modifier = Modifier.fillMaxSize(),
    horizontalArrangement = Arrangement.Center,
    verticalAlignment = Alignment.CenterVertically
) {
    CircularProgressIndicator() // 圆形进度条
}

《Jetpack Compose系列学习》-9 Compose的简单控件之Image、ProgressBar

Rowgiti是横向布局,Cir携程网飞机票预订官网c像素射击下载ularProgressIndicator就是圆形进度条,一行代码就搞定。这种实时刷新的控件,通过Preview方式进行预览的话,会很卡,所以建议运行在真机或模拟git教程器查看。像素射击来看看CircularProgrgithub直播平台永久回家essIndicator源码:

@Composable
fun CircularProgressIndicator(
    modifier: Modifier = Modifier, // 修饰符
    color: Color = MaterialTheme.colors.primary, // 进度条颜色
    strokeWidth: Dp = ProgressIndicatorDefaults.StrokeWidth // 进度条宽度
) {
    // 省略...
}

我们来看看属性的用法:

Row(
    modifier = Modifier.fillMaxSize(),
    horizontalArrangement = Arrangement.Center,
    verticalAlignment = Alignment.CenterVertically
) {
    CircularProgressIndicator( // 圆形进度条
        modifier = Modifier.size(80.dp),
        color = Color.Red,
        strokeWidth = 10.dp
    )
}

《Jetpack Compose系列学习》-9 Compose的简单控件之Image、ProgressBar

还有另外一个可以设置进度giti值的构造方法:

@Composable
fun CircularProgressIndicator(
    /*@FloatRange(from = 0.0, to = 1.0)*/
    progress: Float,
    modifier: Modifier = Modifier,
    color: Color = MaterialTheme.colors.primary,
    strokeWidth: Dp = ProgressIndicatorDefaults.StrokeWidth
)

progress参数Git矩阵置0.0没有进度,1.0表示已完成进度。这里需要注意,设置进度值的进度条是没有转像素勇士大创造攻略圈动画效果的。

条形进度条

条形进度条和圆形携程网站官网进度条的使用上基本一致,来看看:

Row(
    modifier = Modifier.fillMaxSize(),
    horizontalArrangement = Arrangement.Center,
    verticalAlignment = Alignment.CenterVertically
) {
    LinearProgressIndicator() // 条形进度条
}

《Jetpack Compose系列学习》-9 Compose的简单控件之Image、ProgressBar

来看看它的源码:

@Composable
fun LinearProgressIndicator(
    modifier: Modifier = Modifier,
    color: Color = MaterialTheme.colors.primary,
    backgroundColor: Color = color.copy(alpha = IndicatorBackgroundOpacity)
)

除了修饰符外,还可以设置背景色:

Row(
    modifier = Modifier.fillMaxSize(),
    horizontalArrangement = Arrangement.Center,
    verticalAlignment = Alignment.CenterVertically
) {
    LinearProgressIndicator(
        color = Color.Red, // 进度条颜色
        backgroundColor = Color.Yellow // 背景色
    )
}

《Jetpack Compose系列学习》-9 Compose的简单控件之Image、ProgressBar

同样,也可以设置进度progress

@Composable
fun LinearProgressIndicator(
    /*@FloatRange(from = 0.0, to = 1.0)*/
    progress: Float,
    modifier: Modifier = Modifier,
    color: Color = MaterialTheme.colors.primary,
    backgroundColor: Color = color.copy(alpha = IndicatorBackgroundOpacity)
) 

设置进度后,进度条也变成静态的、没有动画效果git命令。后面我们会学习Compose里的布局组件。