본문 바로가기

안드로이드 Android

안드로이드 개발 (19) Compose의 맞춤 그래픽

안녕하세요 Loner입니다. Compose에 대한 뜨거운 열망은 계속 이어집니다.

이번편은 Compose의 그래픽이라는 문서를 정리한 내용입니다. 

Compose의 그래픽

Compose를 사용하면 커스텀 그래픽을 더 쉽게 사용할 수 있습니다.

Compose의 선언적 방식을 사용하면 모든 그래픽 구성이 메서드 호출과

 Paint 도우미 객체 간에 분할되는 대신 한곳에서 발생합니다.

 

Compose가 필요한 객체를 효율적인 방법으로 만들고 업데이트합니다.

 

 

1.Compose를 사용한 그래픽

Compose는 그래픽도 선언적 접근 방식으로 처리합니다. Compose의 접근방식은 여러 이점을 제공합니다.

 

(1)Compose는 그래픽 요소의 상태를 최소화하므로 상태의 프로그래밍 실수를 피할 수 있음

(2)항목을 그릴 때 모든 옵션이 Composable 함수의 예상되는 위치에 있습니다.

(3)Compose의 그래픽 API가 효율적인 방법으로 객체를 만들고 해제합니다.

 

내부적으로 Compose는 View 기반 UI의 캔버스 및 기타 관련 객체를 사용합니다. 

하지만 Compose를 사용하면 내부에서 세부내용을 처리하기 때문에 Canvas의 많은 부분을 대부분 단순화됩니다

 

2. Canvas

- 맞춤 그래픽의 핵심 Composable은 Canvas

- 레이아웃에 Canvas를 배치해서 사용

- Canvas 내에서 스타일과 위치를 정밀하게 제어하는 요소를 그릴 수 있음

 

참고: Canvas Composable 특수한 Compose Canvas 객체를 사용하며 이 객체가 뷰 기반 Canvas를 만들고 관리합니다. 하지만 Compose는 상태를 유지하고 필요한 도우미 객체를 만들고 해제하는 등 많은 작업을 처리합니다.

 

 

Canvas(modifier = Modifier.fillMaxSize()){

}

 

DrawScope -> Canvas는 자체 상태를 유지하는 범위가 지정된 그리기 환경 

DrawScope는 DrawScope의 현재 및 최대 크기를 지정하는 Size 객체인 size와 같은 여러 유용한 필드를 제공합니다.

 

 

예제1.drawLine

Canvas(modifier = Modifier.fillMaxSize()){
    val canvasWidth = size.width
    val canvasHeight = size.height

    drawLine(
        start = Offset(x=canvasWidth, y = 0f),
        end = Offset(x = 0f, y = canvasHeight),
        color = Color.Blue
    )
}

- drawLine은 선을 그어줍니다. 

- Canvas의 DrawScope에서 현재 size를 구할 수 있음

 

결과

 

 

예제2. drawLine에 굵기 설정 추가 

Canvas(modifier = Modifier.fillMaxSize()){
    val canvasWidth = size.width
    val canvasHeight = size.height

    drawLine(
        start = Offset(x=canvasWidth, y = 0f),
        end = Offset(x = 0f, y = canvasHeight),
        color = Color.Blue,
        strokeWidth = 5F
    )
}

- strokeWidth 매개변수를 추가해주었습니다.

 

예제2. 결과

 

 

 

drawLine 말고도 drawRect, drawCircle 등 기타 간단한 그리기 함수가 많이 있습니다.

 

예제3. drawCircle

  Canvas(modifier = Modifier.fillMaxSize()) {
            val canvasWidth = size.width
            val canvasHeight = size.height

            drawLine(
                start = Offset(x = canvasWidth, y = 0f),
                end = Offset(x = 0f, y = canvasHeight),
                color = Color.Blue,
                strokeWidth = 5f
            )
        }

- 기본적으로 drawCircle은 채워진 원을 그림

 

 

 

그려진 요소는 상위 범위 설정의 기본 설정을 기반으로 하므로

 DrawScope 그리기 메서드에 명시적 매개변수를 제공하여 이 기능을 활용할 수 있습니다.

 

3. DrawScope

- Compose Canvas는 범위가 지정된 그리기 환경인 DrawScope를 노출합니다.

- 이 환경에서 실제로 그리기 명령어를 실행합니다.

 

위에서 언급한 DrawScope와 같습니다.

 

예제

Canvas(modifier = Modifier.fillMaxSize()){
    val canvasQuadrantSize = size / 2F
    drawRect(
        color = Color.Green,
        size = canvasQuadrantSize
    )
}

 

결과

 

 

 

 

예제2. DrawScope.inset() 

val canvasQuadrantSize = size / 2F
inset(50F,30F){
    drawRect(
        color = Color.Green,
        size = canvasQuadrantSize
    )
}

- inset() 함수를 사용하면 현재 범위의 기본 매개변수를 조정하고 그리기 경계를 변경하고 그림을 적절히 변환할 수 있습니다. inset() 은 상응하는 람다 내 모든 그리기 작업에 적용됩니다.

 

예제2.결과

 

 

예제3. rotate()

val canvasSize = size
val canvasWidth = size.width
val canvasHeight = size.height
drawRect(
    color = Color.Gray,
    topLeft = Offset(x = canvasWidth / 3F, y = canvasHeight / 3F),
    size = canvasSize / 3F
)

 

- 위 예제는 rotate()를 사용하지 않은 코드입니다.

 

 

 

rotate(degrees = 45F){
    drawRect(
        color = Color.Gray,
        topLeft = Offset(x = canvasWidth / 3F , y = canvasHeight / 3F),
        size = canvasSize / 3F
    )
}

-이제 DrawScope에 회전을 적용하여 직사각형을 회전할 수 있습니다.

- rotate() 를 사용하면 회전 할수 있습니다.

 

 

여러가지 변환을 적용하려는 경우 중첩된 DrawScope 환경을 만드는건 좋지 않습니다.

그래서 withTransform() 함수를 사용해야 합니다.

 - withTransform()는 원하는 모든 변경사항을 결합한 단일 변환을 만들고 적용

 - withTransform()은 Compose가 중첩된 각 변환을 계산하고 저장할 필요 없이 단일 작업으로 실행되므로 중첩 호출하는 것보다 더 효율적입니다.

 

 

예제

withTransform({
    translate(left = canvasWidth/5F)
    rotate(degrees=45F)
}) {
    drawRect(
        color = Color.Gray,
        topLeft = Offset(x = canvasWidth / 3F, y = canvasHeight / 3F),
        size = canvasSize / 3F
    )
}

-translate와 rotate를 같이 사용 

 

결과

 

4. 정리

- Compose의 커스텀 그래픽은 선언형 방식으로 진행되기 때문에 프로그래밍적으로 실수할 확률이 적음

- Compose의 그래픽 API는 효율적으로 객체를 만들거나 해제함 

- Compose만의 특수한 Canvas Composable은 내부적으로 알아서 세부 작업을 해주기 때문에 간결하게 사용할 수 있음

- Canvas Composable의 DrawScope 영역안에서 주로 커스텀 UI를 제작할 수 있음

- Canvas Composable의 DrawScope 영역은 현재 Composable의 size 나 그리기를 돕는 여러 함수들을 지원해줌 

- DrawScope 영역은 기본적으로 상위 범위의 설정을 기준으로 잡음 

- DrawScope에서 기본적으로 drawLine, drawCircle, drawRect 등등으로 그릴 수 있음

- DrawScope의 inset(),rotate() 와 같이 변환을 지원해주는 함수들이 있음

- DrawScope에서 여러변환을 적용할 때 withTransform을 사용할 것을 권장함 모든 변경 사항을 단일 변환으로 적용하기 때문에 중첩으로 여러 변환을 적용하는것보다 훨씬 효율적임 

 

선언형 프로그래밍의 위대함을 다시 살펴볼 수 있는 명목이네요 Canvas 작업까지 프레임워크에서 세부내용을 다 처리해준다니 안드로이드 개발을 너무 편리하게 할 수 있는 세상이 다가온거 같습니다. 여전히 스테이블을 기다리는 Loner 였습니다. 

 

이전 Compose 내용 정리

 

https://gift123.tistory.com/33?category=967702

 

안드로이드 개발 (8) Compose 이해 정리

이번 포스팅부터 Compose에 대해 차근히 파헤쳐 가보겠습니다. Android Compose 공식 문서를 보면서 정리한 내용들 입니다. https://developer.android.com/jetpack/compose/mental-model?hl=en Compose 이해  |..

gift123.tistory.com

https://gift123.tistory.com/34?category=967702 

 

안드로이드 개발 (9) Compose 상태 관리

jetpack compose 에 한창 포스팅 중입니다. https://gift123.tistory.com/33 안드로이드 개발 (8) Compose 이해 정리 이번 포스팅부터 Compose에 대해 차근히 파헤쳐 가보겠습니다. Android Compose 공식 문서를..

gift123.tistory.com

 

https://gift123.tistory.com/38?category=967702 

 

안드로이드 개발 (10) Compose Composable Lifecycle

안녕하세요 Loner 입니다. 오늘은 Compose의 컴포저블 라이프사이클 공부를 정리해 봤습니다. 아래 문서를 정리한 내용입니다. https://developer.android.com/jetpack/compose/lifecycle?hl=en 컴포저블 수명 주..

gift123.tistory.com

https://gift123.tistory.com/39?category=967702 

 

안드로이드 개발 (11) Compose Side-effects

https://developer.android.com/jetpack/compose/side-effects#state-effect-use-cases Compose의 부수 효과  | Jetpack Compose  | Android Developers 컴포저블에는 부수 효과가 없어야 합니다. 하지만 앱의..

gift123.tistory.com

https://gift123.tistory.com/41?category=967702 

 

안드로이드 개발 (13) Layout in Compose 1편

지금까지 Compose에 대해 composable 라이프사이클, Compose 내부흐름 , Composition, recompostion, Sdie-effects 활용방법에 대한 원론 방법에 알았다면 이제 실질적으로 Compose로 Layout을 어떻게 구성하는지..

gift123.tistory.com

https://gift123.tistory.com/42?category=967702 

 

안드로이드 개발 (14) Layout in Compose 2편

1편 정리 https://gift123.tistory.com/41 안드로이드 개발 (13) Layout in Compose 1편 지금까지 Compose에 대해 composable 라이프사이클, Compose 내부흐름 , Composition, recompostion, Sdie-effects 활용방..

gift123.tistory.com

https://gift123.tistory.com/43?category=967702

 

안드로이드 개발 (15) Theming in Compose

https://developer.android.com/jetpack/compose/themes?hl=en Compose의 레이아웃  | Jetpack Compose  | Android Developers Jetpack Compose를 사용하면 앱의 UI를 훨씬 쉽게 디자인하고 빌드할 수 있습니다...

gift123.tistory.com

https://gift123.tistory.com/44?category=967702

 

안드로이드 개발 (16) Compose Lists

안녕하세요 안드로이드 개발자 Loner입니다. Compose의 정리를 이어서 진행해보도록 하겠습니다. List 기존 Xml방식으로 List는 주로 리싸이클러 뷰 혹은 리스트뷰로 많이 구현을 해왔습니다. Compose에

gift123.tistory.com

 

 

https://gift123.tistory.com/45?category=967702

 

안드로이드 개발 (17) Compose Text 1편

안녕하세요 안드로이드 개발자 Loner입니다. Compose 연구에 푹 빠져사는 요즘 새로운 세계를 맛보고 있어서 즐거운것 같습니다. 이번에는 Compose의 텍스트에 관해 정리를 해봤습니다. Compose 의 텍스

gift123.tistory.com

 

 

https://gift123.tistory.com/46?category=967702

 

안드로이드 개발 (18) Compose Text 2편

이전 내용 Compose Text 1편 https://gift123.tistory.com/45?category=967702 안드로이드 개발 (17) Compose Text 1편 안녕하세요 안드로이드 개발자 Loner입니다. Compose 연구에 푹 빠져사는 요즘 새로운 세계..

gift123.tistory.com