Imageの枠線のアニメーションの説明がYoutubeのおすすめにたまたま出てきたので試してみました
https://www.youtube.com/watch?v=0mfCbXrYBPE&list=WL&index=2
※ 動画の一番最後のセクションで紹介されてます
扱いやすくるためテンプレートが生成したColor.ktを以下のように変更しました
虹色のブラシを作るため色を追加しています
原色だとちょっとキツイ感じがしたので調整しています
Theme.ktもAppColorに対応した修正をしてください
@Immutable
object AppColor {
val Purple80 = Color(0xFFD0BCFF)
val PurpleGrey80 = Color(0xFFCCC2DC)
val Pink80 = Color(0xFFEFB8C8)
val Purple40 = Color(0xFF6650a4)
val PurpleGrey40 = Color(0xFF625b71)
val Pink40 = Color(0xFF7D5260)
val RedAA0 = Color(0xA0FF0000)
val OrangeAA0 = Color(0xA0FFA500)
val YellowAA0 = Color(0xA0FFFF00)
val GreenAA0 = Color(0xA0008000)
val CyanAA0 = Color(0xA000FFFF)
val BlueAA0 = Color(0xA00000FF)
val PurpleAA0 = Color(0xA0800080)
val RainbowColors = listOf(
RedAA0,
OrangeAA0,
YellowAA0,
GreenAA0,
CyanAA0,
BlueAA0,
PurpleAA0
)
}
アニメーションを実装します
動画の説明にあったtweenのdurationMillisが1000だと早すぎな気がしたので2000にしてます
@Composable
fun CircleBorderAnimationImage(
bitmap: Bitmap,
modifier: Modifier = Modifier,
drush: Brush = Brush.linearGradient(listOf(Color.Yellow, Color.Green)),
borderWidth: Float = 12f,
contentDescription: String? = null
) {
val infinityTransition = rememberInfiniteTransition(label = "CircleBorderTransition")
val rotationAnimation = infinityTransition.animateFloat(
initialValue = 0f,
targetValue = 360f,
animationSpec = infiniteRepeatable(tween(2000, easing = LinearEasing)),
label = "CircleBorderAnimation"
)
Image(
bitmap = bitmap.asImageBitmap(),
contentDescription = contentDescription,
contentScale = ContentScale.Crop,
modifier = modifier
.drawBehind {
rotate(rotationAnimation.value) {
drawCircle(drush, style = Stroke(borderWidth))
}
}.padding(borderWidth.dp).clip(CircleShape)
)
}
今回はAssetsに置いた画像を使うため別のところでも紹介したAssetsからイメージを読み込む実装をします
/**
* Assetsにあるイメージファイルを読込みBitmapを返す
*/
fun Context.assetsToBitmap(fileName: String): Bitmap? {
return try {
with(assets.open(fileName)) {
BitmapFactory.decodeStream(this)
}
} catch (e: IOException) { null }
}
使い方はこんな感じです
Column(Modifier.padding(10.dp)) {
val context = LocalContext.current
val bitmap: Bitmap? by remember {
mutableStateOf(context.assetsToBitmap("xxx.png"))
}
val brush by remember { mutableStateOf(Brush.linearGradient(AppColor.RainbowColors)) }
bitmap?.let {
CircleBorderAnimationImage(it, Modifier.size(100.dp), brush)
}
}
Android Studio Giraffe 2022.3.1 built on June 29, 2023