핀수로그
  • Android Jetpack Compose 맛보기
    2022년 07월 03일 23시 03분 42초에 업로드 된 글입니다.
    작성자: 핀수
    728x90
    반응형

    Android Jetpack Compose

    네이티브 Android UI를 빌드하기 위한 최신 도구 키트

     

    Jetpack Compose

    선언적 UI 방식
    💡 상태를 UI 로 변환한다.

    UI는 변경할 수 없고 한번 생성하면 업데이트가 불가능하다.

    앱 상태가 바뀌면 새로운 상태를 새로운 표현으로 변환하는 것

    ⇒ 동기화 문제가 완전히 해결된다.

     

    문장을 읽었을 때는 상태가 바뀌면 다시 그림을 그리겠다는 것으로 이해되어 비효율적이지 않을까 생각했다.

    하지만 compose 는 지능적이기 때문에

    변경되지 않은 요소의 작업은 건너 뛴다고 한다.

     

    따라서 코드는 특정 상태에 대한 UI 형태를 설명할 뿐 생성 방법을 지정 하지는 않겠다는 것이다.

     

     

    Declarative UI Toolkit

    • 요즘의 앱들은 데이터가 동적이고 실시간으로 업데이트 된다.
    • 기존의 방식은 UI를 그리기 위해 xml 에 선언해야 했다.
      • 아래의 화면을 그리기 위해서 activity_login.xml 이라는 xml 파일에 UI를 구성했다.
      • 로그인 작업을 수행하기 위해서 해당 xml 을 찾아 inflate 한뒤 각 view 들을 조회하고 속성을 파악해야한다.

    Medium 클론 코딩 로그인 화면 (예시)

    → 데이터가 바뀌면 UI도 바뀌어야 했다.

    ⇒ 모델과 UI를 동기화하는 작업에서 많은 버그가 일어날 가능성이 있다.

     

     

    따라서 선언적 UI는…

    특정 상태에서의 UI 형태를 완전히 설명하고

    상태가 바뀌면 프레임워크에서 UI 업데이트를 처리하는 것

     

     

    가보자고

    백문이불여일견!

    직접 해보자.

     

    예를 들어 버튼을 누르면 ‘안녕하세요!’ 라는 인사말을 출력하는 앱을 만든다고 해보자.

     

    기존 방식

    1. activity 생성

    2. activity_xml.xml

    textView 의 속성은 다음과 같다.

    textSize = 25sp

    marginBottom = 12dp

    <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=".LegacyActivity">
    
        <TextView
            android:id="@+id/showHelloTv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="25sp"
            android:layout_marginBottom="12dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.498"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
        <Button
            android:id="@+id/showHelloBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/showHelloTv" />
        
        
    </androidx.constraintlayout.widget.ConstraintLayout>

     

    3. XmlActivity.kt

    1) inflate 할 layout 을 찾는다.

    2) 각 view 들의 id 를 찾는다.

    3) 버튼을 누르면 텍스트뷰에 안녕하세요가 출력될 수 있도록 한다.

    class XmlActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_xml)
    
            val showHelloBtn = findViewById<Button>(R.id.showHelloBtn)
            val showHelloTv = findViewById<TextView>(R.id.showHelloTv)
    
            showHelloBtn.setOnClickListener {
                showHelloTv.text = "안녕하세요!"
            }
        }
    }

     

    상태가 변경(버튼을 클릭)되면

    UI가 변경되는 것(textView.setText)을 알 수 있다.

     

    Compose

    1. Compose 생성

     

    2. ComposeActivity.kt 

    xml 방식과 다르게 setContent 임을 알 수 있다. (not setContentView)

    각 속성에 대해서는 여기서는 알아보지 않을 것이다.

     

    compose는 button 을 클릭했을 때 UI를 변경하지 않는다.

    (View 의 변경을 정의하지 않는다.)

     

    변경된 상태를 정의한다고 볼 수 있겠다.

    class ComposeActivity : ComponentActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContent {
                ComposeSampleTheme {
                    Surface(
                        modifier = Modifier.fillMaxSize(),
                        color = MaterialTheme.colorScheme.background
                    ) {
                        Column(
                            horizontalAlignment = Alignment.CenterHorizontally,
                            verticalArrangement = Arrangement.Center
                        ) {
                            var str by remember {
                                mutableStateOf("")
                            }
                            SayHello(str)
                            Button(
                                onClick = { str = "안녕하세요!" },
                                modifier = Modifier.wrapContentSize()
                            ) {
                                Text(text = "click")
                            }
                        }
                    }
                }
            }
        }
    }
    @Composable
    fun SayHello(str: String) {
        Text(text = str, modifier = Modifier
            .wrapContentSize()
            .padding(bottom = 12.dp), fontSize = 25.sp)
    }

     

     

    비교하기

    위 (xml), 아래 (compose) 모두 동일한 기능을 하는 것을 알 수 있다.

    예시가 너무 조그매서..

    큰 차이가 있을까? 라고 생각할 수 있지만

    UI 구성이 복잡해질수록 compose 는 위력을 발휘할 것이라 예상된다.

     

    xml
    compose

     

    항상 궁금했던 Jetpack Compose 에 대해 알아볼 수 있는 시간을 갖게 되어

    너무 기쁘다!

    그동안 시도 안한건 아니었는데

    이해가 잘 가지 않았었다..

    이번에는 그래도 그때보다는 이해가 잘됐다고 생각하는데..

    얼른 더 배워봐야겠다 크큭

     

     

    설명이 많이 부족할 수 있습니다.

    잘못된 정보가 있을 경우 지적해주시면 감사하겠습니다!!!


    References

    아래 글을 참고하여 작성 되었습니다.

    What's new in Jetpack Compose | Session

    https://developer.android.com/jetpack/androidx/releases/compose-compiler?hl=ko 

    https://developer.android.com/jetpack/compose/text?hl=ko

    Jetpack Compose 1 - Column, Row, Text by 오준석의 생존코딩

     

     

     

    728x90
    반응형
    댓글