- FAB란 앱의 주요 인터페이스 위에 둥둥 떠있다 하여 붙여진 이름으로서 앱의 기본 대표 동작들을 수행할 수 있도록 하는 버튼이다.
- 보통 화면 오른쪽 하단에 둥근 사각형, 타원, 원으로 많이 표시된다.

- 디자인 시스템 및 커스터마이징에 적합하도록 Compose 기반 직접 해당 버튼을 구현했다.
- 먼저 상위 컴포저블로 Surface를 사용해준다.
Surface(
modifier = Modifier
.size(52.dp)
.clip(CircleShape)
.clickable(
interactionSource = interactionSource,
indication = rememberRipple(
color = Color.Black.copy(alpha = 0.2f),
bounded = true
),
onClick = onClick
),
color = containerColor,
contentColor = contentColor
) {
- Surface를 사용한 이유는 클릭 효과 같은 Ripple 구현에 적합하기 때문이고, Elevation 효과를 주기 위함이다.
- Compose에서 기본으로 제공하는 FAB, Card, Button의 경우에도 해당 컴포저블을 사용하고 있다.
- clip에 CircleShape를 부여함으로써 완전한 둥근 원형으로 구성이 가능하다.
- color는 버튼 자체 컬러, contentColor는 내부 람다에 들어갈 요소의 컬러를 의미한다.
.clickable(
interactionSource = interactionSource,
indication = rememberRipple(
color = Color.Black.copy(alpha = 0.2f),
bounded = true
),
onClick = onClick
),
- clickable의 내부는 실제 사용자가 버튼을 클릭했을 때 나타나는 효과와 관련이 있다.
- interactionSource는 사용자 상호작용을 처리할 때 사용되는 수정자의 일종으로, 포커스가 맞춰진 상태의 테두리를 그리는 데 사용된다.
- indication의 경우에는 pressed 상태에서 나타나는 효과에 대해 정의할 수 있다.
- 또한 Surface Modifier의 clickable에 onClick 처리를 걸어줘야 실제 클릭 시, 그 효과를 확인 가능하다.
- 내부 요소는 아이콘 위치를 정중앙으로 배치해 줄 Box와 하위에 Icon을 구성했다.
Box(
contentAlignment = Alignment.Center,
modifier = Modifier.fillMaxSize()
) {
Icon(
painter = painterResource(id = R.drawable.ic_plus),
contentDescription = contentDescription,
modifier = Modifier.size(24.dp),
tint = contentColor
)
}
- Icon의 색상은 contentColor를 통해 정해진다.
- 이후 프리뷰를 통해 확인이 가능하다.
@Composable
@Preview(showBackground = true)
fun FloatingActionButtonPreview() {
MaterialTheme {
TbFloatingActionButton(
containerColor = colorResource(R.color.blue),
contentColor = colorResource(R.color.white)
) {}
}
}

- FAB란 앱의 주요 인터페이스 위에 둥둥 떠있다 하여 붙여진 이름으로서 앱의 기본 대표 동작들을 수행할 수 있도록 하는 버튼이다.
- 보통 화면 오른쪽 하단에 둥근 사각형, 타원, 원으로 많이 표시된다.

- 디자인 시스템 및 커스터마이징에 적합하도록 Compose 기반 직접 해당 버튼을 구현했다.
- 먼저 상위 컴포저블로 Surface를 사용해준다.
Surface(
modifier = Modifier
.size(52.dp)
.clip(CircleShape)
.clickable(
interactionSource = interactionSource,
indication = rememberRipple(
color = Color.Black.copy(alpha = 0.2f),
bounded = true
),
onClick = onClick
),
color = containerColor,
contentColor = contentColor
) {
- Surface를 사용한 이유는 클릭 효과 같은 Ripple 구현에 적합하기 때문이고, Elevation 효과를 주기 위함이다.
- Compose에서 기본으로 제공하는 FAB, Card, Button의 경우에도 해당 컴포저블을 사용하고 있다.
- clip에 CircleShape를 부여함으로써 완전한 둥근 원형으로 구성이 가능하다.
- color는 버튼 자체 컬러, contentColor는 내부 람다에 들어갈 요소의 컬러를 의미한다.
.clickable(
interactionSource = interactionSource,
indication = rememberRipple(
color = Color.Black.copy(alpha = 0.2f),
bounded = true
),
onClick = onClick
),
- clickable의 내부는 실제 사용자가 버튼을 클릭했을 때 나타나는 효과와 관련이 있다.
- interactionSource는 사용자 상호작용을 처리할 때 사용되는 수정자의 일종으로, 포커스가 맞춰진 상태의 테두리를 그리는 데 사용된다.
- indication의 경우에는 pressed 상태에서 나타나는 효과에 대해 정의할 수 있다.
- 또한 Surface Modifier의 clickable에 onClick 처리를 걸어줘야 실제 클릭 시, 그 효과를 확인 가능하다.
- 내부 요소는 아이콘 위치를 정중앙으로 배치해 줄 Box와 하위에 Icon을 구성했다.
Box(
contentAlignment = Alignment.Center,
modifier = Modifier.fillMaxSize()
) {
Icon(
painter = painterResource(id = R.drawable.ic_plus),
contentDescription = contentDescription,
modifier = Modifier.size(24.dp),
tint = contentColor
)
}
- Icon의 색상은 contentColor를 통해 정해진다.
- 이후 프리뷰를 통해 확인이 가능하다.
@Composable
@Preview(showBackground = true)
fun FloatingActionButtonPreview() {
MaterialTheme {
TbFloatingActionButton(
containerColor = colorResource(R.color.blue),
contentColor = colorResource(R.color.white)
) {}
}
}
