Jetpack compose: How to implement press listener

Introduction

This code demonstrates how to implement a press listener in Jetpack Compose. It creates a clickable circular button that displays a rotating text with a counter value. Each press on the button increments the counter by 45 degrees, with a maximum value of 360 degrees. The code utilizes various Jetpack Compose features including animations, state management, and gesture detection.

Breakdown

The code is divided into three main sections:

  1. MainActivity: This is the standard Android activity class that sets the content of the app using setContent with the MainContent composable function.

  2. MainContent: This composable function defines the main layout of the app. It uses a Column to center a clickable text element vertically and horizontally.

    • State Management:

      • remember is used to create a mutable state variable counter to track the current angle value.
      • animateFloatAsState animates the rotation angle based on the counter value.
    • Click detection:

      • A pointerInput modifier is applied to the text element. Inside this modifier, detectTapGestures identifies tap gestures.
      • The onPress callback within detectTapGestures increments the counter by 45 degrees, wrapping back to 0 if it reaches 360.
    • Text and Button Styling:

      • The text element displays the current counter value with a degree symbol (\u00B0).
      • Various modifiers are used to style the text element like a circular button:
        • fillMaxWidth sets the width of the element.
        • rotate applies rotation based on the animated angle value.
        • clip(CircleShape) clips the element into a circle shape.
        • background sets the background color of the button.
        • padding adds padding around the text.
  3. ComposablePreview: This is a preview function for the composable used for development purposes. It's currently commented out and doesn't display anything in this example.

Summary

This code effectively demonstrates how to combine state management, animations, and gesture detection to create an interactive button with a press listener in Jetpack Compose. It showcases a practical approach for handling user interaction and updating the UI accordingly.


MainActivity.kt

package com.cfsuman.jetpackcompose

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

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

        setContent {
            MainContent()
        }
    }


    @Composable
    fun MainContent(){
        Column(
            modifier = Modifier
                .background(Color(0xFFEDEAE0))
                .fillMaxSize(),
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            val counter = remember { mutableStateOf(0) }

            val angle: Float by animateFloatAsState(
                targetValue = counter.value.toFloat(),
                animationSpec = tween(
                    durationMillis = 3000, // duration
                    easing = FastOutSlowInEasing
                )
            )

            Text(
                text = "Press Me : ${counter.value}\u00B0",
                fontSize = 40.sp,
                color = Color(0xFFFFB200),
                textAlign = TextAlign.Center,
                modifier = Modifier
                    .pointerInput(Unit) {
                        detectTapGestures(
                            onPress = {
                                if (counter.value == 360){
                                    counter.value = 0
                                }else{
                                    counter.value += 45
                                }
                            }
                        )
                    }
                    .fillMaxWidth(0.9F)
                    .rotate(angle)
                    .clip(CircleShape)
                    .background(Color(0xFF58111A))
                    .padding(25.dp)
            )
        }
    }


    @Preview
    @Composable
    fun ComposablePreview(){
        //MainContent()
    }
}
More android jetpack compose tutorials