[Jetpack Compose] Glide経由でコンテンツ一覧を表示してタップされたらブラウザで開く

公開:2020/10/17
更新:2020/10/17
3 min読了の目安(約2900字TECH技術記事

MainActivity.kt
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val articleRepository = ArticleRepository(context = applicationContext)
        val articles = articleRepository.list()

        setContent {
            AppTheme {
                Surface(color = MaterialTheme.colors.background) {
                    val scroll = rememberScrollState(0f)
                    Column(
                        Modifier.padding(16.dp)
                            .verticalScroll(scroll)
                    ) {
                        articles.forEach {
                            Article(it)
                            Spacer(Modifier.preferredHeight(10.dp))
                        }
                    }
                }
            }
        }
    }
}
Article.kt
@Composable
fun Article(article: Article) {
    val context = ContextAmbient.current
    Card(elevation = 4.dp) {
        Column(
            Modifier
                .padding(16.dp)
                .fillMaxWidth()
                .height(200.dp)
                .clickable(onClick = {
                    val uri = Uri.parse(article.url)
                    val intent = Intent(Intent.ACTION_VIEW, uri)
                    ContextCompat.startActivity(context, intent, null)
                })
        ) {
            Text(text = "${article.title}")
            Column(
                Modifier.align(Alignment.CenterHorizontally)
                    .padding(16.dp)
            ) {
                ThumbnailImage(article.image)
            }
        }
    }
}
Thumbnail.kt
@Composable
fun ThumbnailImage(
    url: String
) {
    WithConstraints {
        val image = stateFor<ImageAsset?>(null) { null }
        val context = ContextAmbient.current

        onCommit(url) {
            val glide = Glide.with(context)
            val job = CoroutineScope(Dispatchers.Main).launch {
                glide
                    .asBitmap()
                    .load(url)
                    .override(constraints.maxWidth, constraints.maxHeight)
                    .into(object : CustomTarget<Bitmap>() {
                        override fun onResourceReady(
                            resource: Bitmap,
                            transition: Transition<in Bitmap>?
                        ) {
                            FrameManager.ensureStarted()
                            image.value = resource.asImageAsset()
                        }

                        override fun onLoadCleared(p0: Drawable?) {
                            image.value = null
                        }
                    })
            }

            onDispose {
                image.value = null
                job.cancel()
            }
        }

        val value = image.value
        if (value != null) {
            Image(asset = value)
        }
    }
}