Group 10.png

Objective

Recreate the Customizable Button from the Taskose UI design kit I acquired, utilizing Android Jetpack Compose.

Environment

Implementation

Step 1

Download the needed icons here.

Step 2

Create the CustomButton.kt file with the following content.

// Your package ...

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

data class CustomButtonStyle(
    val buttonTextStyle: TextStyle = TextStyle(
        fontWeight = FontWeight.Bold,
        fontSize = 14.sp
    ),
    val buttonContainerColor: Color = Color(0xFF7980FF),
    val buttonContentColor: Color = Color.White,
    val buttonPaddingValues: PaddingValues = PaddingValues(16.dp),
    val roundedCornerRadius: Dp = 12.dp,
    val height: Dp = 48.dp,
    val iconDrawableId: Int? = null,
)

@Composable
fun CustomButton(
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    buttonText: String = "Some Action",
    style: CustomButtonStyle = CustomButtonStyle(),
    testTag: String = "",
    onClick: () -> Unit = {}
) {
    Button(
        enabled = enabled,
        onClick = {
            onClick()
        },
        shape = RoundedCornerShape(style.roundedCornerRadius),
        modifier = modifier
            .height(style.height)
            .fillMaxWidth()
            .testTag(testTag),
        colors = ButtonDefaults.buttonColors(
            style.buttonContainerColor,
            style.buttonContentColor
        ),
        contentPadding = style.buttonPaddingValues
    ) {
        Box(
            modifier = Modifier.fillMaxSize()
        ) {
            if (style.iconDrawableId != null) {
                Icon(
                    modifier = Modifier.align(Alignment.CenterEnd),
                    imageVector = ImageVector.vectorResource(id = style.iconDrawableId),
                    tint = style.buttonContentColor,
                    contentDescription = null
                )
            }
            Text(
                modifier = Modifier.align(Alignment.Center),
                text = buttonText,
                style = style.buttonTextStyle
            )
        }
    }
}

Step 3

Create the CustomButtonPreview.kt file with the following content.

// Your package ...

import android.widget.Toast
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp

@Preview
@Composable
fun StyledButtonPreview() {
    val context = LocalContext.current
    Box(
        modifier = Modifier
            .fillMaxSize()
            .padding(24.dp),
        contentAlignment = Alignment.Center
    ) {
        Column(
            verticalArrangement = Arrangement.spacedBy(16.dp)
        ) {
            CustomButton {
                Toast.makeText(context, "Some Action", Toast.LENGTH_SHORT).show()
            }
            CustomButton(
                buttonText = "Delete Task",
                style = CustomButtonStyle(
                    buttonContainerColor = Color(0xFFF05A5A),
                    iconDrawableId = R.drawable.ic_delete
                )
            ) {
                Toast.makeText(context, "Delete Task", Toast.LENGTH_SHORT).show()
            }
            val isTracking = remember {
                mutableStateOf(false)
            }
            CustomButton(
                buttonText = if (isTracking.value) "Stop Tracking" else "Start Tracking",
                style = CustomButtonStyle(
                    iconDrawableId = if (isTracking.value) R.drawable.ic_stop else R.drawable.ic_play
                )
            ) {
                isTracking.value = !isTracking.value
            }
        }
    }
}

Preview Result

untitled.gif