Jetpack Compose Long Press Button

It took me a bit to figure this out, so I’m posting it here with the hope that it’ll save you some time! 🙂

So, what do we need?

• A custom Modifier

• A custom Button

We could implement all of this within the custom Button itself, but I think separating them is cleaner. It keeps things simpler and leaves the door open for more customizations down the road.

    Custom Modifier

    @Composable
    fun Modifier.customClickable(
        interactionSource: MutableInteractionSource?,
        onClick: () -> Unit,
        onLongClick: () -> Unit
    ): Modifier {
        val viewConfiguration = LocalViewConfiguration.current
    
        LaunchedEffect(interactionSource) {
            var isLongClick = false
    
            interactionSource?.interactions?.collectLatest { interaction ->
                when (interaction) {
                    is PressInteraction.Press -> {
                        isLongClick = false
                        delay(viewConfiguration.longPressTimeoutMillis)
                        isLongClick = true
                        onLongClick()
                    }
    
                    is PressInteraction.Release -> {
                        if (isLongClick.not()) {
                            onClick()
                        }
                    }
                }
            }
        }
    
        return this
    }

    Custom Button

    @Composable
    fun LongPressButon(
        modifier: Modifier = Modifier,
        onClick: () -> Unit,
        onLongClick: () -> Unit = {},
        enabled: Boolean = true,
        shape: Shape = ButtonDefaults.shape,
        colors: ButtonColors = ButtonDefaults.buttonColors(),
        elevation: ButtonElevation? = ButtonDefaults.buttonElevation(),
        border: BorderStroke? = null,
        contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
        interactionSource: MutableInteractionSource? = remember { MutableInteractionSource() },
        content: @Composable RowScope.() -> Unit,
    ) {
        val modifierAdjusted = modifier.customClickable(
            interactionSource,
            onClick = onClick,
            onLongClick = onLongClick,
        )
        Button(
            onClick = onClick,
            modifier = modifierAdjusted,
            enabled = enabled,
            shape = shape,
            colors = colors,
            elevation = elevation,
            border = border,
            contentPadding = contentPadding,
            interactionSource = interactionSource,
            content = content
        )
    }
    

    Usage example:

     val context = LocalContext.current
        LongPressButon(
            onClick = {
                Toast.makeText(context, "Click", Toast.LENGTH_SHORT).show()
            },
            onLongClick = {
                Toast.makeText(context, "Long click", Toast.LENGTH_SHORT).show()
            },
        ) {
            Text(
                text = "Button",
            )
        }

    That’s it 🙂

    Happy coding!

    View binding Delegation

    Since Kotlin Android Extensions, including Kotlin synthetics, is deprecated we forced to use View Binding. To find out how to Migrate from Kotlin synthetics to Jetpack view binding follow the link.

    When you are done, you will find yourself with additional boilerplate code in each fragment. Inspired by this article Simple one-liner ViewBinding in Fragments and Activities with Kotlin I’ve created a little bit modified version of the fragment one-line view binding solution.

    Keep Reading

    Kotlin logging library – First Medium post

    I’m happy to share with you my new article at @AT&T Israel R&D Center Medium blog >>> https://bit.ly/2Noc2SO
    The default logging solution is minimal, and I believe that most of us have already written a wrapper class and copied it from project to project.
    Originally I created my Logging library in Java and recently I converted it to Kotlin. Now I want to share it with you.

    Kotlin DSL tutorial (simplified)

    If you are reading this, I assume that you have reached the same point as I have in the past and you decided to dig a little bit and understand what Kotlin DSL is all about.

    Upon googling it, I found the following post that explains this topic pretty well. If you wonder why this post exists, it’s because here I’ll try to explain the same topic with the same code example, but in a more detailed manner. I decided to do so because it took me a while to understand it myself and I’d like to simplify it for you.

    The whole solution is available in the following file: Github

    Keep Reading

    Mock final classes on Kotlin

    internal class Foo {
        internal fun bar(x: Int, y: Int, zip: Zip) = x + y + zip.doIt()
    }
    internal class Zip {
        internal fun doIt() = 0
    }
    

    When we have two classes like above and try to mock Zip class like below:

    Keep Reading

    Windows batch file – Short tutorial + Run tests from multiple modules

    Let’s start with some batch basics. If you are already familiar with them skip this section.

    • @echo off – Should be added at the top of your batch script to prevent printing all commands.
    • echo Some text Output: “Some text”
    • echo. – Empty line
    • set /a index=0 – Set numeric variable
    • echo Index is %index% – Output: “Index is 0”
    • Rem It is a comment
    • :: It is a comment too
    • echo Some text>> test.txt – Write “Some text” to test.txt file.
    Keep Reading