Reputation: 243
This is a composable function. When I click on the CardView then the article should open in the Android view. I'm not sure how how to achieve this.
I also tried it with a lambda but had no success.
I want to call the composable ShowOnWebView
function when the NewsCardView(Card View)
function is clicked but the compiler shows an error:
@Composable invocations can only happen from the context of a @Composable function
How to call my function when the CardView is clicked?
@Composable
fun NewsCardView(
article: Article,
modifier: Modifier = Modifier,
) {
Card(
modifier = modifier
.height(150.dp)
.fillMaxWidth()
.padding(2.dp)
.clickable {
// I want to call ShowOnWebView here
},
elevation = 5.dp,
backgroundColor = Color.White
) {
val painter = rememberImagePainter(data = article.urlToImage) {
crossfade(1000)
error(R.drawable.ic_placeholder)
placeholder(R.drawable.ic_placeholder)
}
Row(
modifier = Modifier
.fillMaxSize(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceEvenly
) {
Column(
modifier = Modifier.fillMaxWidth(.3f),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Image(
modifier = Modifier.size(100.dp),
painter = painter,
contentDescription = "News",
contentScale = ContentScale.Crop,
)
Text(
text = article.author ?: "",
fontSize = 12.sp,
)
Text(
text = article.publishedAt,
fontSize = 12.sp,
)
}
Column(
modifier = Modifier.fillMaxWidth(.7f),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(modifier = Modifier.fillMaxWidth(),
text = article.title,
color = Color.Black,
fontWeight = FontWeight.Bold,
fontSize = 16.sp
)
Text(modifier = Modifier.fillMaxWidth(),
text = article.description ?: "",
color = Color.Black,
fontWeight = FontWeight.Medium,
fontSize = 14.sp
)
}
}
}
}
This composable function displays an article in the AndroidView:
@Composable
fun ShowOnWebView(url:String) {
val context= LocalContext.current
AndroidView(factory = {
WebView(context).apply {
webViewClient= WebViewClient()
loadUrl(url)
}
})
}
Upvotes: 13
Views: 11916
Reputation: 67268
You can't call a composable inside your non-composable scope. What you should do, is have a State with a boolean and set it to true when you want to show your composable.
var showWebView by remember { mutableStateOf(false) }
Modifier.clickable {
showWebView = true
}
if(showWebView) {
ShowOnWebView(someUrl)
}
This is also how we display dialogs or conditional composables such as Loading, Result, Error. It's also used for expanded or shrinked composables, too.
Upvotes: 21