'Using Custom Views with Jetpack Compose

Let's suppose I'm using some library that's intended to provide some UI Widgets. Let's say this library provides a Button Widget called FancyButton.

In the other hand, I have a new project created with Android Studio 4 that allows me to create a new project with an Empty Compose Activity.

The question is: How should I add this FancyButton to the view stack? Is it possible? Or with Jetpack Compose I can only use components that had been developed specifically for Jetpack Compose. In this case, AFAIK I could only use Android standars components (Text, MaterialTheme, etc).

If I try to use something like this:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
        MaterialTheme {
            Greeting("Android")
            FancyButton(context, "Some text")
        }
    }
}

then I get this error:

e: Supertypes of the following classes cannot be resolved. Please make sure you have the required dependencies in the classpath.



Solution 1:[1]

Currently (as of 0.1.0-dev04), there is not a good solution to this. In the future, you'll be able to simply call it as FancyButton("Some text") (no context needed).

You can see a demo of what it will look like in the Compose code here.

Solution 2:[2]

Update in alpha 06

It is possible to import Android View instances in a composable.

Use ContextAmbient.current as the context parameter for the View.

Column(modifier = Modifier.padding(16.dp)) {

    // CustomView using Object
    MyCustomView(context = ContextAmbient.current)

    // If the state updates
    AndroidView(viewBlock = ::CustomView, modifier = modifier) { customView ->
        // Modify the custom view
    }

    // Using xml resource
    AndroidView(resId = R.layout.view_demo)
}

Solution 3:[3]

You can wrap your custom view within the AndroidView composable:

@Composable
fun RegularTextView() {
    AndroidView(
        factory = { context ->
            TextView(context).apply {
                text = "RegularTextView"
                textSize = 34.dp.value
            }
        },
    )
}

And here is how to update your custom view during a recomposition, by using the update parameter:

@Composable
fun RegularTextView() {
    var string by remember {
        mutableStateOf("RegularTextView")
    }
    Column(horizontalAlignment = Alignment.CenterHorizontally) {
        AndroidView(
            factory = { context ->
                TextView(context).apply {
                    textSize = 34.dp.value
                }
            },
            update = { textView ->
                textView.text = string
            }
        )
        Spacer(modifier = Modifier.height(8.dp))
        Button(
            onClick = {
                string = "Button clicked"
            },
        ) {
            Text(text = "Update text")
        }
    }
}

Solution 4:[4]

@Composable

fun ButtonType1(text: String,  onClick: () -> Unit) 

{

   Button (
    modifier=Modifier.fillMaxWidth().height(50.dp),
    onClick = onClick,
    shape = RoundedCornerShape(5.dp),
    border = BorderStroke(3.dp, colorResource(id = R.color.colorPrimaryDark)),
    colors = ButtonDefaults.buttonColors(contentColor = Color.White, backgroundColor = colorResource(id = R.color.colorPrimaryDark))
    )
    {
        Text(text = text , color = colorResource(id = R.color.white),
        fontFamily = montserrat,
        fontWeight = FontWeight.Normal,
        fontSize = 15.sp
    )
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ryan M
Solution 2
Solution 3 Raed Mughaus
Solution 4 Codemaker