컴포즈 오랜만에 사용하려니 기억이 가물가물해서

확인차 공식문서의 튜토리얼을 시도해보려고 한다.

 

강의 1: 구성 가능한 함수

공식 문서에 따르면 Compose는 함수 중심 빌드 방식을 채용했다고 한다.

해당 방식을 사용하면 높은 가독성으로 UI를 정의할 수 있다고 한다.

 

이때 중요한 방식이 @Composable 어노테이션을 사용하여

해당 함수가 Compose UI를 사용한다는 표시이다.

 

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.Text //compose Text

class MainActivity : ComponentActivity() {
	override fun onCreate(savedInstanceState: Bundle?) {
    	super.onCreate(saveInstanceState)
        setContent {
        	Text("Hello world")
        }
    }
}

위 소스코드는  간단한 텍스트 요소를 추가하는 코드인데

컴포즈 방식이 최신 기술이다보니 Kotlin 언어를 채용해서 사용한 듯 하다.

 

코드상으로 볼 때

setContent 는 옛 방식인 xml 방식에서 setContentView 대체인 것 같다.

이후 바인딩 된 화면(xml로 보면 Layout 가장 루트영역)에 TextView를 추가한 느낌이다.

코드로 본다면 아래와 같다 생각된다.

//import ...

class MainActivity : AppCompatActivity() {
	override fun onCreate(savedInstanceState: Bundle?) {
    	super.onCreate(saveInstanceState)
        setContentView(R.layout.activity_main)
        
        textView = findView.ById(R.id.textView)
        textView.text = "Hello world"
    }
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
	xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    
    <TextView
    	android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello world" />
</androidx.constraintlayout.widget.ConstraintLayout>

기존 XML 방식에서는 바인딩이 필수적으로 필요했기에 Kotlin으로 작성된 바인딩 코드로 위에 작성하였고

그에 따른 바인딩 될 필수 xml도 필요했기에 아래처럼 표현했다.

 

기존 방식인 XML은 바인딩코드(Kotlin or Java)와 바인딩 할 화면 코드(XML) 이렇게 두개가 필요했으나

Compose 방식은 코드가 간결해지고 하나를 위해 두가지를 작업하던 방식을 개선하였다.

 

그리고 이전 방식에 포함되지 않던 미리보기 기능을 하는 @Preview 어노테이션이 추가되었다.

해당 어노테이션을 통해 에뮬레이터 설치 없이 미리보기가 가능하다고 한다.

...

@Composable
fun MessageCard(name: String) {
	Text(text = "Hello $name!")
}

@Preview
@Composable
fun PreviewMessageCard() {
    MessageCard("Android")
}

(좌) XML 미리보기 방식, (우) @Preview 어노테이션 방식

좌측에 사용되던 XML 방식은 미리보기가 가능하나 마크업 언어이기에 재사용성 함수를 사용할 수 없기에 동적 변화에 대한 대응이 불가능하다는 단점이 있었으나 우측의 방식은 @Preview 어노테이션을 사용하는 Compose 방식으로 미리보기를 봄과 동시에 재사용성 함수에 대한 동적 변화도 확인할 수 있는 장점이 있다!

(라고는 하나 사실 방식의 차이일뿐 기능은 같다봐야될 것 같다.)
+) 함수형이라 테스트해봤는데 변수를 넣고 디자인에서 변경됨을 확인해봤으나 변경되지 않음을 확인했다... 안되는건가..?

 

강의 2: 레이아웃

XML 방식에서도 레이아웃 방식이 존재했었다.

대표적으로 ConstraintLayout, RelativeLayout, LinearLayout 정도가 있다.

그 외에도 테이블이니 그리드니 여러가지가 존재했지만 사실상 자주 사용되던 방식은 저 세가지가 가장 많았던 것 같다.

 

@LinearLayout
- 가장 많이 사용했던 레이아웃이다. 순서대로 쌓는 느낌이라보면 되는데 쌓는다는게 '스택'처럼 위로 쌓이는 것이 아닌 한쪽 방향으로 쌓인다 보면 될 것 같다. 예를 들어 TextView를 왼쪽에서 오른쪽 방향으로 코드를 작성한다면

TextView, TextView, TextView

로 될 것이다.

@RelativeLayout

- 부모 혹은 특정 뷰를 기준으로 정렬하는 방식입니다. 예를 들어 좌측에 TextView(a) 가 존재하고 해당 a라는 뷰 옆에 b 라는 TextView를 놓는 코드를 작성하게 된다면

TextView(b), TextView(a)

로 될 것이다.

@ConstraintLayout

- 자주...사용하던 방식은 아니나 참 괜찮은 방식인 걸로 알고 있다. RelativeLayout에서 아쉬운 점을 보완하여 체인 스타일이라는 시스템이 존재하고 예를 들어 TextView 두 개를 중앙 정렬 공평하게 두 개로 둔다는 코드를 작성하면

ㅁㅁㅁㅁTextViewㅁㅁTextViewㅁㅁㅁㅁ

와 같은 화면이 된다. (이때 ㅁ은 띄어쓰기로 생각)

(라고 찾아보니 그렇게 명시되어 있으나 사실 자주 쓰지 않아서 명확히는 모르겠다.)

 

근.데

이번에 새로 나온 Compose 방식은 Flutter 방식과 유사한 Column과 Row 방식을 채택하였습니다.

그래서 기존에 Layout 방식이 아닌 가로 배열 및 세로 배열만 주로 사용될 예정입니다.

(추가로 기본 레이아웃은 Flutter에 Stack 구조인 듯 합니다. 그래서 Text 함수를 두 번 작성할 시 서로 겹치게 됩니다.)

Column {
	Text(text = "저자")
	Text(text = "내용")
}

위 처럼 세로 배열 방식 Column을 사용 시

저자
내용

위 처럼 결과가 나오게 됩니다.

 

Row {
	Text(text = "저자")
	Text(text = "내용")
}

반대로 위처럼 Row를 사용할 경우

저자내용

위처럼 가로 배열 방식이 나오게 된다.

 

배열을 통해 레이아웃에 혁신적인(?) 느낌으로 만들 수 있게 되었다.

기존에 layout 시스템들은 너무 View마다 의존하는 느낌도 강했고 하나를 고치면 다른 것들도 다 고쳐야 됐었으나..(특히나 ConstraintLayout이 대표적으로 그랬다......) Compose Layout의 배열방식이 새롭게 생겨나면서 기존 레이아웃과는 의존도도 낮아지고 굉장히 좋아졌었다.

 

이번에는 배열이 아닌 이미지를 한번 확인해보자.

Image(
            painter = painterResource(R.drawable.profile_picture),
            contentDescription = "Contact profile picture",
        )

Image 위젯을 만드는 예시이다.

paint와 contentDescription은 Image 위젯의 파라미터로 사용되는 변수들이다.

각각 painter는 painterResource를 통해 asset에 들어있는 xml 이미지를 불러올 수 있고 contentDescription은 이미지 설명으로 사용되는 느낌이다.

 

다음은 위젯에 대한 padding과 margin 처리다.

이전에 XML 방식에서는

layout, view 등등에 margin을 각각 넣거나 인자를 추가해서 사용하는 방식이었다.

XML 방식 padding

(진짜 세상....복잡하다..)

 

Compose에서는 해당 방식을 Modifier(수정자)를 통해 변경이 가능하다.

Column {
            Text("all_padding", 
            	modifier = Modifier.padding(all = 20.dp).background(Color(0xFF00FFFF)))
            Text("normal", 
            	modifier = Modifier.background(Color(0xFFCAA926)))
            Text("padding", 
            	modifier = Modifier.padding(top = 50.dp, start = 50.dp, end = 50.dp, bottom = 50.dp).background(Color(0xFF00F05F)))
        }

저렇게 긴 xml이 불필요한 것을 제외시키면 위와 같은 간단한(?) 코드가 완성된다.

(사실 인자로만 보면 간단하긴해도 짧아진 건 못느끼겠다.)

꽤나 간단 명료하게 해결가능하다.

 

여기까지가 강의 4개 중 2개의 내용인데

확실히 어떤 느낌의 방식인지 UI적으로는 납득했다.

다만 소스코드 상에서 동적 변경이나 여러 동작들을 곁들이는 것이 가능할 지 여부까지는 잘 모르겠다.

 

원래는 cloudtype 사이트에 대해 다뤄보려했으나 모종의 이유로 먼저 다루게 되었으며

이후에는 남은 강의 2개에 대해 작성하거나 혹은 이번에 다우기술 채용과 관련하여 사전과제를 하면서 정말정말 정말 많이 부족하단 사실을 알게되어서.. 해당 과제에서 다뤘던 기술들에 대해 공부하고 포스팅을 써볼 예정이다.

+ Recent posts