hemant
hemant

Reputation: 243

How to call a composable function in onClick event

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

Answers (1)

Thracian
Thracian

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

Related Questions