huzit
___을 입력해주세요
huzit
전체 방문자
  • 분류 전체보기 (137)
    • 안드로이드(Compose) (10)
      • UI (4)
      • 개념 (6)
    • 안드로이드 (50)
      • 기본개념 (6)
      • 응용 (4)
      • Debug (18)
      • Binding (3)
      • RecyclerView (5)
      • Firebase (6)
      • Retrofit (1)
      • Activity & Fragment (4)
    • 코틀린 (22)
    • 코딩테스트 (38)
      • 백준 (10)
      • 프로그래머스 (28)
    • 일상 (6)
    • CS 지식 (4)
    • 라즈베리파이 (7)

블로그 메뉴

  • 홈
  • 태그
  • 글쓰기
  • 관리

공지사항

인기 글

태그

  • docker
  • 코틀린
  • gts4mini
  • 브레빌 밤비노 플러스
  • recyclerView ClickEvent
  • RecyclerView
  • Kotlin
  • compose
  • Java
  • 공돌이파파
  • firebase
  • FCM
  • 라즈베리 파이
  • 프로그래머스
  • IFTTT
  • jetpack
  • Retrofit
  • Debug
  • 공돌카돈
  • Android

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
huzit

___을 입력해주세요

Button Material 3
안드로이드(Compose)/UI

Button Material 3

2024. 4. 16. 10:36
728x90

이전엔 버튼의 매개변수별 특징을 알아봤다면 이번엔 Material3에서 제시하는 버튼의 종류에 대해 알아보겠습니다.

버튼 기본 매개변수에 대해 모르신다면 이전 글을 보고 오시는 걸 추천드립니다.

 

Button 기본

compose의 기본적인 컴포저블 중 하나입니다. 일반적으로 머티리얼3의 컴포저블를 사용하지만 머티리얼의 컴포저블도 Button에 기반을 둔 컴포저블이 많으므로 알아두고 가는게 좋습니다. 속성 modi

huzit.tistory.com

종류

  1. Elevated button
  2. Filled button(일반 Button)
  3. Filled tonal button
  4. Outlined button
  5. Text button
  6. Icon button
  7. Segmented button
  8. Floating action button(FAB)
  9. Extended FAB

각 버튼별 사용 사례

강조 수준 요소 이론적 해석 예시 작업
높은 강조 – 화면에서 가장 중요하거나 가장 일반적인 작업
Extended FAB 확장된 FAB의 더 넓은 형식과 텍스트 라벨은 FAB보다 시각적으로 더 눈에 띕니다.
FAB가 너무 작아 보이는 대형 화면에서 자주 사용됩니다.
Compose 만들기
새 스레드
새 파일
FAB FAB는 화면의 기본 작업에 대한 기본 구성 요소로 남아 있습니다.
소형 FAB , FAB 및 대형 FAB 의 세 가지 크기로 제공됩니다 .
새 컴포즈 생성
Filled Button 채워진 버튼의 대조적인 표면 색상으로 인해 FAB 다음으로 가장 눈에 띄는 버튼이 됩니다.
흐름의 최종 작업 또는 차단 해제 작업에 사용됩니다.
저장
확인
완료
중간 강조 - 다른 화면 요소에 방해가 되지 않는 중요한 작업에 사용됩니다.
Filled Tonal Button 채워진 색조 버튼은 배경색이 더 밝고 레이블 색상이 더 어둡기 때문에 일반 채워진 버튼보다 시각적으로 덜 눈에 띕니다.
흐름에서 최종 작업이나 차단 해제 작업에 여전히 사용되지만 덜 강조됩니다.
저장
확인
완료
Elevation Button 상승된 버튼은 본질적으로 더 밝은 배경색과 그림자로 채워진 버튼입니다.
그림자 크리프를 방지하려면 버튼이 패턴이 있는 배경과 시각적으로 분리되어야 하는 경우와 같이 꼭 필요한 경우에만 사용하십시오.
답장
모두 보기
장바구니에 담기
휴지통에서 꺼내기
Outlined Button 모두 보기 또는 장바구니에 추가 등 주의가 필요하지만 기본 작업이 아닌 작업에는 윤곽선이 있는 버튼을 사용하세요사용하세요.
이는 누군가에게 마음을 바꾸거나 흐름에서 벗어날 수 있는 기회를 제공하는 데 사용되는 버튼이기도 합니다.
답장
모두 보기
장바구니에 담기
휴지통에서 꺼내기
낮은 강조 – 눈에 띄는 정도가 가장 적은 선택 또는 보충 작업에 사용됩니다.
Text button 텍스트 버튼은 시각적으로 덜 눈에 띄므로 대체 옵션과 같이 강조가 낮은 작업에 사용해야 합니다. 자세히 알아
보기 모두 보기
계정 변경
켜기
Segmented button 분할된 버튼은 단일 아이콘 버튼보다 시각적으로 더 눈에 띕니다.
왼쪽 정렬 / 중간 정렬 / 오른쪽 정렬
Icon Button 가장 컴팩트하고 섬세한 버튼 형태인 아이콘 버튼은 '북마크', '별표' 등 선택적인 보조 동작을 위해 사용됩니다. 즐겨찾기에 추가
인쇄

예제

참고사항으로 각 버튼은 컴포즈의 기본 버튼과 동일하게 내부적으로 Surface를 사용하고 있거나 Box, Button을 사용하고 있으므로 FAB (Floating Action Button)을 제외하고 사용 방법이나 매개변수는 동일합니다.

간단하게 출력되는 결과물과 코드, 내부 코드만 보고 넘어가겠습니다.

Elevated button

Button의 elevation가 기본적으로 할당되어 있는 Material 버튼입니다.

ElevatedButton(onClick = { /*TODO*/ }) {
    Text("ElevatedButton")
}
@Composable
fun ElevatedButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    shape: Shape = ButtonDefaults.elevatedShape,
    colors: ButtonColors = ButtonDefaults.elevatedButtonColors(),
    elevation: ButtonElevation? = ButtonDefaults.elevatedButtonElevation(),
    border: BorderStroke? = null,
    contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    content: @Composable RowScope.() -> Unit
) =
    Button(
        onClick = onClick,
        modifier = modifier,
        enabled = enabled,
        shape = shape,
        colors = colors,
        elevation = elevation,
        border = border,
        contentPadding = contentPadding,
        interactionSource = interactionSource,
        content = content
    )

Filled button (일반 Button)

기본 버튼이라 동일합니다.

Filled tonal button

중간 강조를 위한 Material3 버튼입니다

FilledTonalButton(onClick = { /*TODO*/ }) {
    Text("FilledTonalButton")
}
@Composable
fun FilledTonalButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    shape: Shape = ButtonDefaults.filledTonalShape,
    colors: ButtonColors = ButtonDefaults.filledTonalButtonColors(),
    elevation: ButtonElevation? = ButtonDefaults.filledTonalButtonElevation(),
    border: BorderStroke? = null,
    contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    content: @Composable RowScope.() -> Unit
) =
    Button(
        onClick = onClick,
        modifier = modifier,
        enabled = enabled,
        shape = shape,
        colors = colors,
        elevation = elevation,
        border = border,
        contentPadding = contentPadding,
        interactionSource = interactionSource,
        content = content
    )

Outlined button

외곽선이 있는 버튼입니다.

OutlinedButton(onClick = { /*TODO*/ }) {
    Text(text = "OutlinedButton")
}
@Composable
fun OutlinedButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    shape: Shape = ButtonDefaults.outlinedShape,
    colors: ButtonColors = ButtonDefaults.outlinedButtonColors(),
    elevation: ButtonElevation? = null,
    border: BorderStroke? = ButtonDefaults.outlinedButtonBorder,
    contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    content: @Composable RowScope.() -> Unit
) =
    Button(
        onClick = onClick,
        modifier = modifier,
        enabled = enabled,
        shape = shape,
        colors = colors,
        elevation = elevation,
        border = border,
        contentPadding = contentPadding,
        interactionSource = interactionSource,
        content = content
    )

Text button

단일 텍스트 출력을 위한 버튼입니다.

TextButton(onClick = { /*TODO*/ }) {
    Text(text = "TextButton")
}
@Composable
fun TextButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    shape: Shape = ButtonDefaults.textShape,
    colors: ButtonColors = ButtonDefaults.textButtonColors(),
    elevation: ButtonElevation? = null,
    border: BorderStroke? = null,
    contentPadding: PaddingValues = ButtonDefaults.TextButtonContentPadding,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    content: @Composable RowScope.() -> Unit
) =
    Button(
        onClick = onClick,
        modifier = modifier,
        enabled = enabled,
        shape = shape,
        colors = colors,
        elevation = elevation,
        border = border,
        contentPadding = contentPadding,
        interactionSource = interactionSource,
        content = content
    )

Icon button

아이콘 버튼입니다.

IconButton(onClick = { /*TODO*/ }) {
    Icon(painter = painterResource(id = R.drawable.icon_test), contentDescription = "")
}
@Composable
fun IconButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    colors: IconButtonColors = IconButtonDefaults.iconButtonColors(),
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    content: @Composable () -> Unit
) {
    Box(
        modifier = modifier
            .minimumInteractiveComponentSize()
            .size(IconButtonTokens.StateLayerSize)
            .clip(IconButtonTokens.StateLayerShape.toShape())
            .background(color = colors.containerColor(enabled).value)
            .clickable(
                onClick = onClick,
                enabled = enabled,
                role = Role.Button,
                interactionSource = interactionSource,
                indication = rememberRipple(
                    bounded = false,
                    radius = IconButtonTokens.StateLayerSize / 2
                )
            ),
        contentAlignment = Alignment.Center
    ) {
        val contentColor = colors.contentColor(enabled).value
        CompositionLocalProvider(LocalContentColor provides contentColor, content = content)
    }
}

Filled Icon button

FilledIconButton(onClick = { /*TODO*/ }) {
    Icon(painter = painterResource(id = R.drawable.icon_test), contentDescription = "")
}
@Composable
fun FilledIconButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    shape: Shape = IconButtonDefaults.filledShape,
    colors: IconButtonColors = IconButtonDefaults.filledIconButtonColors(),
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    content: @Composable () -> Unit
) = Surface(
    onClick = onClick,
    modifier = modifier.semantics { role = Role.Button },
    enabled = enabled,
    shape = shape,
    color = colors.containerColor(enabled).value,
    contentColor = colors.contentColor(enabled).value,
    interactionSource = interactionSource
) {
    Box(
        modifier = Modifier.size(FilledIconButtonTokens.ContainerSize),
        contentAlignment = Alignment.Center
    ) {
        content()
    }
}

Floating action button(FAB)

플롯팅 액션 버튼입니다. 주로 추가, 삭제 또는 사용자 메뉴를 보여줄 때 사용합니다.

FloatingActionButton(onClick = { /*TODO*/ }) {
    Icon(painter = painterResource(id = R.drawable.icon_test), contentDescription = "")
}
@Composable
fun FloatingActionButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    shape: Shape = FloatingActionButtonDefaults.shape,
    containerColor: Color = FloatingActionButtonDefaults.containerColor,
    contentColor: Color = contentColorFor(containerColor),
    elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    content: @Composable () -> Unit,
) {
    Surface(
        onClick = onClick,
        modifier = modifier.semantics { role = Role.Button },
        shape = shape,
        color = containerColor,
        contentColor = contentColor,
        tonalElevation = elevation.tonalElevation(interactionSource = interactionSource).value,
        shadowElevation = elevation.shadowElevation(interactionSource = interactionSource).value,
        interactionSource = interactionSource,
    ) {
        CompositionLocalProvider(LocalContentColor provides contentColor) {
            // Adding the text style from [ExtendedFloatingActionButton] to all FAB variations. In
            // the majority of cases this will have no impact, because icons are expected, but if a
            // developer decides to put some short text to emulate an icon, (like "?") then it will
            // have the correct styling.
            ProvideTextStyle(
                MaterialTheme.typography.fromToken(ExtendedFabPrimaryTokens.LabelTextFont),
            ) {
                Box(
                    modifier = Modifier
                        .defaultMinSize(
                            minWidth = FabPrimaryTokens.ContainerWidth,
                            minHeight = FabPrimaryTokens.ContainerHeight,
                        ),
                    contentAlignment = Alignment.Center,
                ) { content() }
            }
        }
    }
}

Extended FAB

자체적으로 Row를 가지고 있어서 여러 content를 넣을 수 있습니다.

ExtendedFloatingActionButton(onClick = { /*TODO*/ }) {
    Icon(painter = painterResource(id = R.drawable.icon_test), contentDescription = "")
    Spacer(modifier = Modifier.width(10.dp))
    Text(text = "FAB")
}
@Composable
fun ExtendedFloatingActionButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    shape: Shape = FloatingActionButtonDefaults.extendedFabShape,
    containerColor: Color = FloatingActionButtonDefaults.containerColor,
    contentColor: Color = contentColorFor(containerColor),
    elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    content: @Composable RowScope.() -> Unit,
) {
    FloatingActionButton(
        onClick = onClick,
        modifier = modifier,
        shape = shape,
        containerColor = containerColor,
        contentColor = contentColor,
        elevation = elevation,
        interactionSource = interactionSource,
    ) {
        Row(
            modifier = Modifier
                .sizeIn(minWidth = ExtendedFabMinimumWidth)
                .padding(horizontal = ExtendedFabTextPadding),
            horizontalArrangement = Arrangement.Center,
            verticalAlignment = Alignment.CenterVertically,
            content = content,
        )
    }
}

Segmented button

아직 개발 중이라 바뀌거나 사라질 수 있는 기능입니다.

material3의 버전이 1.2.0 이상이어야 합니다.

SegmentedButton은 두 종류가 있습니다.

  • SingleChoiceSegmentedButton
  • MultiChoiceSegmentedButton

단일 선택 또는 다중 선택 시 유용한 버튼입니다.

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SegmentedButtonSnippets() {
    var selectedIndex by remember { mutableStateOf(-1) }
    val options = listOf("Day", "Month", "Week")
    val checkedList = remember { mutableStateListOf<Int>() }
    Column {
        SingleChoiceSegmentedButtonRow {
            options.forEachIndexed { index, label ->
                SegmentedButton(
                    selected = index == selectedIndex,
                    onClick = {
                        if(selectedIndex == index)
                            selectedIndex = -1
                        else
                            selectedIndex = index
                    },
                    shape = SegmentedButtonDefaults.itemShape(index = index, count = options.size)
                ) {
                    Text(label)
                }
            }
        }

        MultiChoiceSegmentedButtonRow {
            options.forEachIndexed { index, s ->
                SegmentedButton(
                    checked = index in checkedList,
                    onCheckedChange = {
                        if(index in checkedList){
                            checkedList.remove(index)
                        } else{
                            checkedList.add(index)
                        }
                    },
                    shape = SegmentedButtonDefaults.itemShape(index = index, count = options.size)
                ) {
                    Text(text = s)
                }
            }
        }
    }
}

참고

https://github.com/Huzit/ComposeBlogSample

https://m3.material.io/components/all-buttons

https://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary

https://developer.android.com/develop/ui/compose/touch-input/user-interactions/handling-interactions?hl=ko#build-advanced

 

728x90
저작자표시 (새창열림)

'안드로이드(Compose) > UI' 카테고리의 다른 글

Button 기본  (0) 2024.04.16
[Text] Text 패러미터 정리  (0) 2023.06.29
Preview  (0) 2023.06.27
    '안드로이드(Compose)/UI' 카테고리의 다른 글
    • Button 기본
    • [Text] Text 패러미터 정리
    • Preview
    huzit
    huzit
    simple is best

    티스토리툴바