<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>세상을 바꾸는 개발자</title>
    <link>https://healthcoding.tistory.com/</link>
    <description>세상을 바꾸는 개발자</description>
    <language>ko</language>
    <pubDate>Sat, 11 Apr 2026 19:06:59 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>헬창코딩</managingEditor>
    <image>
      <title>세상을 바꾸는 개발자</title>
      <url>https://tistory1.daumcdn.net/tistory/4763373/attach/ed830a5bbd05468cbb149bc2ea4f0443</url>
      <link>https://healthcoding.tistory.com</link>
    </image>
    <item>
      <title>Compose 공식문서정리 - Theming</title>
      <link>https://healthcoding.tistory.com/69</link>
      <description>&lt;h1 style=&quot;color: #000000; text-align: start;&quot;&gt;Material Design 3 in Compose&lt;/h1&gt;
&lt;div style=&quot;color: #202124; text-align: start;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;제트팩 컴포즈는 머티리얼 디자인의 차세대 진화 버전인 머티리얼 디자인 3를 구현합니다. 머티리얼 3에는 업데이트된 테마, 컴포넌트 및 동적 색상과 같은 머티리얼 유 개인화 기능이 포함되어 있으며, 안드로이드 12 이상의 새로운 비주얼 스타일 및 시스템 UI와 조화를 이루도록 설계되었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;b&gt;&lt;/b&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #006dd7; text-align: start;&quot;&gt;참고: &quot;머티리얼 디자인 3&quot;, &quot;머티리얼 3&quot;, &quot;M3&quot;라는 용어는 서로 바꿔서 사용할 수 있습니다. 기존 머티리얼 디자인 사양 및 해당 androidx.compose.material 라이브러리는 &quot;머티리얼 디자인 2&quot;, &quot;머티리얼 2&quot; 또는 &quot;M2&quot;로 불립니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;아래에서는 Reply 샘플 앱을 예로 들어 머티리얼 디자인 3 구현을 보여줍니다. 응답 샘플은 전적으로 머티리얼 디자인 3을 기반으로 합니다.&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #9d9d9d; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;841&quot; data-origin-height=&quot;701&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bG4MEc/btsHqdjpdEA/5BWEuhl7hG7QqaKGnkyHUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bG4MEc/btsHqdjpdEA/5BWEuhl7hG7QqaKGnkyHUk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bG4MEc/btsHqdjpdEA/5BWEuhl7hG7QqaKGnkyHUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbG4MEc%2FbtsHqdjpdEA%2F5BWEuhl7hG7QqaKGnkyHUk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;841&quot; height=&quot;701&quot; data-origin-width=&quot;841&quot; data-origin-height=&quot;701&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;b&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;color: #202124; text-align: start;&quot;&gt;그림 1. 머티리얼 디자인3 을 사용한 답장 샘플 앱&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;
&lt;h2 id=&quot;dependency&quot; data-text=&quot;Dependency&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;종속성&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;컴포즈 앱에서 머티리얼 3을 사용하려면 build.gradle 파일에 컴포즈 머티리얼 3 종속성을 추가하세요&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;nginx&quot; style=&quot;color: #000000; text-align: left;&quot;&gt;&lt;code&gt;implementation &quot;androidx.compose.material3:material3:$material3_version&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;종속성이 추가되면 색상, 타이포그래피 및 모양을 포함한 머티리얼 디자인 시스템을 앱에 추가할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;experimental-apis&quot; data-text=&quot;Experimental APIs&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt; 실험적 APIs&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;일부 M3 API는 실험적인 것으로 간주됩니다. 이러한 경우 함수 또는 파일 수준에서 ExperimentalMaterial3Api 어노테이션을 사용하여 옵트인해야 합니다&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;pre class=&quot;less&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_material3_experimental_annotation&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/designsystems/Material3Snippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_material3_experimental_annotation&quot;&gt;&lt;code&gt;// import androidx.compose.material3.ExperimentalMaterial3Api
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AppComposable() {
&amp;nbsp; &amp;nbsp; // M3 composables
}
&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;h2 data-text=&quot;Material theming&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 id=&quot;material-theming&quot; data-text=&quot;Material theming&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;머터리얼 테마&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;M3 테마에는 &lt;a style=&quot;color: #000000;&quot; href=&quot;https://m3.material.io/styles/color/overview&quot;&gt;color scheme&lt;/a&gt;, &lt;a style=&quot;color: #000000;&quot; href=&quot;https://m3.material.io/styles/typography/overview&quot;&gt;typography&lt;/a&gt; 및 &lt;a style=&quot;color: #000000;&quot; href=&quot;https://m3.material.io/styles/shape/overview&quot;&gt;shapes&lt;/a&gt;과 같은 하위 시스템이 포함되어 있습니다. 이러한 값을 사용자 지정하면 변경 사항이 앱을 빌드하는 데 사용하는 M3 구성 요소에 자동으로 반영됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;912&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VW6k0/btsHrvJT3QG/LMWZNGRsem8VSWcw5lXTa1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VW6k0/btsHrvJT3QG/LMWZNGRsem8VSWcw5lXTa1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VW6k0/btsHrvJT3QG/LMWZNGRsem8VSWcw5lXTa1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVW6k0%2FbtsHrvJT3QG%2FLMWZNGRsem8VSWcw5lXTa1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;912&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;912&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
머티리얼 디자인의 하위 시스템: 색상, 타이포그래피 및 모양
&lt;div style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;젯팩 컴포즈는 M3 머티리얼테마 컴포저블로 이러한 개념을 구현합니다&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;jboss-cli&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_material3_theme_definition&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/designsystems/Material3Snippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_material3_theme_definition&quot;&gt;&lt;code&gt;MaterialTheme(
&amp;nbsp; &amp;nbsp; colorScheme = /* ...
&amp;nbsp; &amp;nbsp; typography = /* ...
&amp;nbsp; &amp;nbsp; shapes = /* ...
) {
&amp;nbsp; &amp;nbsp; // M3 app content
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;애플리케이션 콘텐츠를 테마로 하려면 앱에 맞는 색 구성표, 타이포그래피 및 모양을 정의하세요.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-text=&quot;Color scheme&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 id=&quot;color-scheme&quot; data-text=&quot;Color scheme&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Color scheme&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;색 구성표의 기본은 다섯 가지 주요 색상 세트입니다. 이러한 각 색상은 머티리얼 3 컴포넌트에서 사용되는 13개의 톤 팔레트와 관련이 있습니다. 예를 들어 응답의 라이트 테마에 대한 색 구성표입니다:&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;887&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nijRw/btsHpzN5gtf/ivIk4l2uZMiJbAfIaez6i1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nijRw/btsHpzN5gtf/ivIk4l2uZMiJbAfIaez6i1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nijRw/btsHpzN5gtf/ivIk4l2uZMiJbAfIaez6i1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnijRw%2FbtsHpzN5gtf%2FivIk4l2uZMiJbAfIaez6i1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;887&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;887&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;b&gt;&lt;/b&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;앱 조명 색 구성표 샘플&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-text=&quot;Generate color schemes&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 id=&quot;generate_color_schemes&quot; data-text=&quot;Generate color schemes&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;color schemes 생성&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;사용자 정의 컬러스킴을 수동으로 만들 수도 있지만 브랜드의 소스 색상을 사용하여 생성하는 것이 더 쉬운 경우가 많습니다.&lt;a style=&quot;color: #000000;&quot; href=&quot;https://material.io/material-theme-builder&quot;&gt;Material Theme Builder&lt;/a&gt; 도구를 사용하면 이 작업을 수행할 수 있으며, 선택적으로 테마 코드 작성 코드를 내보낼 수 있습니다. 다음 파일이 생성됩니다:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;Color.kt 에는 밝은 테마 색상과 어두운 테마 색상 모두에 대해 정의된 모든 역할과 함께 테마 색상이 포함되어 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;reasonml&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_material3_theme_colors&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/designsystems/Material3Snippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_material3_theme_colors&quot;&gt;&lt;code&gt;val md_theme_light_primary = Color(0xFF476810)
val md_theme_light_onPrimary = Color(0xFFFFFFFF)
val md_theme_light_primaryContainer = Color(0xFFC7F089)
// ..
// ..

val md_theme_dark_primary = Color(0xFFACD370)
val md_theme_dark_onPrimary = Color(0xFF213600)
val md_theme_dark_primaryContainer = Color(0xFF324F00)
// ..
// ..&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Theme.kt에는 밝고 어두운 색 구성표와 앱 테마에 대한 설정이 포함되어 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;kotlin&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_material3_theme_color_setup&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/designsystems/Material3Snippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_material3_theme_color_setup&quot;&gt;&lt;code&gt;private val LightColorScheme = lightColorScheme(
&amp;nbsp; &amp;nbsp; primary = md_theme_light_primary,
&amp;nbsp; &amp;nbsp; onPrimary = md_theme_light_onPrimary,
&amp;nbsp; &amp;nbsp; primaryContainer = md_theme_light_primaryContainer,
&amp;nbsp; &amp;nbsp; // ..
)
private val DarkColorScheme = darkColorScheme(
&amp;nbsp; &amp;nbsp; primary = md_theme_dark_primary,
&amp;nbsp; &amp;nbsp; onPrimary = md_theme_dark_onPrimary,
&amp;nbsp; &amp;nbsp; primaryContainer = md_theme_dark_primaryContainer,
&amp;nbsp; &amp;nbsp; // ..
)

@Composable
fun ReplyTheme(
&amp;nbsp; &amp;nbsp; darkTheme: Boolean = isSystemInDarkTheme(),
&amp;nbsp; &amp;nbsp; content: @Composable () -&amp;gt; Unit
) {
&amp;nbsp; &amp;nbsp; val colorScheme =
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!darkTheme) {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; LightColorScheme
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; } else {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DarkColorScheme
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&amp;nbsp; &amp;nbsp; MaterialTheme(
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; colorScheme = colorScheme,
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; content = content
&amp;nbsp; &amp;nbsp; )
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;밝고 어두운 테마를 지원하려면 isSystemInDarkTheme()를 사용합니다. 시스템 설정에 따라 사용할 색 구성표를 밝게 또는 어둡게 정의합니다.&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 id=&quot;dynamic_color_schemes&quot; data-text=&quot;Dynamic color schemes&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;Dynamic color schemes&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://m3.material.io/styles/color/dynamic-color/overview&quot;&gt;Dynamic color&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;는 &lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;알고리즘이 사용자의 배경 화면에서 사용자 지정 색상을 도출하여 앱과 시스템 UI에 적용하는 Material You의 핵심 부분입니다. 이 색상 팔레트는 밝은 색상과 어두운 색상을 생성하기 위한 시작점으로 사용됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;878&quot; data-origin-height=&quot;950&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/W8tN2/btsHqyN7rD0/yCkHGKoKaWG0iZI0w2ShM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/W8tN2/btsHqyN7rD0/yCkHGKoKaWG0iZI0w2ShM0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/W8tN2/btsHqyN7rD0/yCkHGKoKaWG0iZI0w2ShM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FW8tN2%2FbtsHqyN7rD0%2FyCkHGKoKaWG0iZI0w2ShM0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;878&quot; height=&quot;950&quot; data-origin-width=&quot;878&quot; data-origin-height=&quot;950&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div style=&quot;color: #202124; text-align: start;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;배경 화면(왼쪽)과 기본 앱 테마(오른쪽)의 답장 샘플 앱 동적 테마&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;color: #202124; text-align: start;&quot;&gt;&lt;br /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;동적 색상은 Android 12 이상에서 사용할 수 있습니다. 동적 색상을 사용할 수 있는 경우 동적 컬러스킴을 설정할 수 있습니다. 그렇지 않은 경우 사용자 지정 밝은 색 또는 어두운 색 구성표를 사용해야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;ColorScheme은 &lt;a style=&quot;color: #000000;&quot; href=&quot;https://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#dynamiclightcolorscheme&quot;&gt;light&lt;/a&gt; 이나 &lt;a style=&quot;color: #000000;&quot; href=&quot;https://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#dynamicdarkcolorscheme&quot;&gt;dark&lt;/a&gt;&amp;nbsp;만들기 위한 빌더 기능을 제공합니다:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;xl&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_material3_theme_dynamic_color&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/designsystems/Material3Snippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_material3_theme_dynamic_color&quot;&gt;&lt;code&gt;// Dynamic color is available on Android 12+
val dynamicColor = Build.VERSION.SDK_INT &amp;gt;= Build.VERSION_CODES.S
val colors = when {
&amp;nbsp; &amp;nbsp; dynamicColor &amp;amp;&amp;amp; darkTheme -&amp;gt; dynamicDarkColorScheme(LocalContext.current)
&amp;nbsp; &amp;nbsp; dynamicColor &amp;amp;&amp;amp; !darkTheme -&amp;gt; dynamicLightColorScheme(LocalContext.current)
&amp;nbsp; &amp;nbsp; darkTheme -&amp;gt; DarkColorScheme
&amp;nbsp; &amp;nbsp; else -&amp;gt; LightColorScheme
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-text=&quot;Color usage&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 id=&quot;color_usage&quot; data-text=&quot;Color usage&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;Color usage&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;MaterialTheme.colorScheme을 통해 앱에서 머티리얼 테마 색상에 액세스할 수 있습니다:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_material3_use_color_theme&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/designsystems/Material3Snippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_material3_use_color_theme&quot;&gt;&lt;code&gt;Text(
&amp;nbsp; &amp;nbsp; text = &quot;Hello theming&quot;,
&amp;nbsp; &amp;nbsp; color = MaterialTheme.colorScheme.primary
)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;각 색상 역할은 컴포넌트의 상태, 눈에 잘 띄는 정도, 강조하는 정도에 따라 다양한 위치에 사용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;기본 색은 눈에 잘 띄는 버튼, 활성 상태, 높은 표면의 색조와 같은 주요 구성 요소에 사용되는 기본 색상입니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;보조 키 컬러는 필터 칩과 같이 UI에서 덜 눈에 띄는 구성 요소에 사용되며 색상 표현의 기회를 넓혀줍니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;세 번째 키 색상은 기본 색상과 보조 색상의 균형을 맞추거나 요소에 대한 주의를 환기시키는 데 사용할 수 있는 대비되는 액센트의 역할을 도출하는 데 사용됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;답장 샘플 앱 디자인은 기본 컨테이너 위에 기본 컨테이너 색상을 사용하여 선택한 항목을 강조합니다.&lt;/span&gt;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;876&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UcuUY/btsHrq2VGNS/Ah6fKjGclJAlLPItvkuZsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UcuUY/btsHrq2VGNS/Ah6fKjGclJAlLPItvkuZsK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UcuUY/btsHrq2VGNS/Ah6fKjGclJAlLPItvkuZsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUcuUY%2FbtsHrq2VGNS%2FAh6fKjGclJAlLPItvkuZsK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;876&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;876&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;기본 컨테이너 및 기본 컨테이너 색상이 있는 텍스트 필드&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;pre class=&quot;stylus&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_material3_use_color_theme_2&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/designsystems/Material3Snippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_material3_use_color_theme_2&quot;&gt;&lt;code&gt;Card(
&amp;nbsp; &amp;nbsp; colors = CardDefaults.cardColors(
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; containerColor =
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (isSelected) MaterialTheme.colorScheme.primaryContainer
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; else
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; MaterialTheme.colorScheme.surfaceVariant
&amp;nbsp; &amp;nbsp; )
) {
&amp;nbsp; &amp;nbsp; Text(
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; text = &quot;Dinner club&quot;,
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; style = MaterialTheme.typography.bodyLarge,
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; color =
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (isSelected) MaterialTheme.colorScheme.onPrimaryContainer
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; else MaterialTheme.colorScheme.onSurface,
&amp;nbsp; &amp;nbsp; )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;여기에서 댓글 &lt;span style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot;&gt;Navigation drawer&lt;/span&gt;에서 보조 및 보조 컨테이너 색상을 대조적으로 사용하여 강조와 악센트를 만드는 방법을 확인할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;841&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6fcLZ/btsHrwINXbK/1usSXBPaluViBKAa3aQ2Ck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6fcLZ/btsHrwINXbK/1usSXBPaluViBKAa3aQ2Ck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6fcLZ/btsHrwINXbK/1usSXBPaluViBKAa3aQ2Ck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6fcLZ%2FbtsHrwINXbK%2F1usSXBPaluViBKAa3aQ2Ck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;841&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;841&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;color: #202124; text-align: start;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;플로팅 액션 버튼에 대한 3차 컨테이너와 온-테리 컨테이너 조합.&lt;/span&gt;&lt;br /&gt;
&lt;h3 data-text=&quot;Typography&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 id=&quot;typography&quot; data-text=&quot;Typography&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Typography&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;머티리얼 디자인 3은 머티리얼 디자인 2에서 적용된 텍스트 스타일을 포함한 유형 배율을 정의합니다. 이름 지정 및 그룹화는 디스플레이, 헤드라인, 제목, 본문, 라벨로 단순화되었으며 각각 대, 중, 소 크기로 나뉘어 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;856&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Urpm0/btsHrviPiuO/2NrtUY4TisVwndPHPinwa0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Urpm0/btsHrviPiuO/2NrtUY4TisVwndPHPinwa0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Urpm0/btsHrviPiuO/2NrtUY4TisVwndPHPinwa0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUrpm0%2FbtsHrviPiuO%2F2NrtUY4TisVwndPHPinwa0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;856&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;856&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;머티리얼 디자인 3의 기본 타이포그래피 스케일&lt;/span&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;color: #202124; text-align: start;&quot;&gt;
&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;&lt;b&gt;M3&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;&lt;b&gt;Default Font Size/Line Height&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;displayLarge&lt;/td&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;Roboto 57/64&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;displayMedium&lt;/td&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;Roboto 45/52&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;displaySmall&lt;/td&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;Roboto 36/44&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;headlineLarge&lt;/td&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;Roboto 32/40&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;headlineMedium&lt;/td&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;Roboto 28/36&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;headlineSmall&lt;/td&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;Roboto 24/32&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;titleLarge&lt;/td&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;New- Roboto Medium 22/28&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;titleMedium&lt;/td&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;Roboto Medium 16/24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;titleSmall&lt;/td&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;Roboto Medium 14/20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;bodyLarge&lt;/td&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;Roboto 16/24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;bodyMedium&lt;/td&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;Roboto 14/20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;bodySmall&lt;/td&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;Roboto 12/16&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;labelLarge&lt;/td&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;Roboto Medium 14/20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;labelMedium&lt;/td&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;Roboto Medium 12/16&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;labelSmall&lt;/td&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;New Roboto Medium,&lt;span&gt;&amp;nbsp;&lt;/span&gt;11/16&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;span style=&quot;background-color: #ffffff; color: #006dd7; text-align: start;&quot;&gt;M2 타이포그래피 클래스와 달리 M3 타이포그래피 클래스에는 현재 defaultFontFamily 매개변수가 포함되어 있지 않습니다. 대신 각 개별 TextStyles에서 fontFamily 매개 변수를 사용해야 합니다.&lt;/span&gt;&lt;br /&gt;
&lt;h4 data-text=&quot;Define typography&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 id=&quot;define_typography&quot; data-text=&quot;Define typography&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;Define typography&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;Compose는 기존 TextStyle 및 폰트 관련 클래스와 함께 M3 Typography 클래스를 제공하여 머티리얼 3 유형 스케일을 모델링할 수 있습니다. Typography 생성자는 각 스타일에 대한 기본값을 제공하므로 사용자 정의하지 않으려는 매개 변수를 생략할 수 있습니다:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;jboss-cli&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_material3_typography_definition&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/designsystems/Material3Snippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_material3_typography_definition&quot;&gt;&lt;code&gt;val replyTypography = Typography(
&amp;nbsp; &amp;nbsp; titleLarge = TextStyle(
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fontWeight = FontWeight.SemiBold,
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fontSize = 22.sp,
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; lineHeight = 28.sp,
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; letterSpacing = 0.sp
&amp;nbsp; &amp;nbsp; ),
&amp;nbsp; &amp;nbsp; titleMedium = TextStyle(
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fontWeight = FontWeight.SemiBold,
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fontSize = 16.sp,
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; lineHeight = 24.sp,
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; letterSpacing = 0.15.sp
&amp;nbsp; &amp;nbsp; ),
&amp;nbsp; &amp;nbsp; // ..
)
// ..&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1210&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wXVvs/btsHo5UdFsW/EWzMq47dT8ZougwJbJtOhK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wXVvs/btsHo5UdFsW/EWzMq47dT8ZougwJbJtOhK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wXVvs/btsHo5UdFsW/EWzMq47dT8ZougwJbJtOhK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwXVvs%2FbtsHo5UdFsW%2FEWzMq47dT8ZougwJbJtOhK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;1210&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1210&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;다양한 타이포그래피 용도에 따른 본문 대형, 본문 중형 및 라벨 중형&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;color: #202124; text-align: start;&quot;&gt;&lt;br /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;제품에 머티리얼 디자인 유형 스케일의 15가지 기본 스타일이 모두 필요하지 않을 수 있습니다. 이 예에서는 축소된 세트에 대해 5개의 크기가 선택되고 나머지는 생략되었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;TextStyle의 기본값과 fontFamily 및 letterSpacing과 같은 글꼴 관련 속성을 변경하여 타이포그래피를 사용자 지정할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;pre class=&quot;nix&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_material3_typography_body_large&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/designsystems/Material3Snippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_material3_typography_body_large&quot;&gt;&lt;code&gt;bodyLarge = TextStyle(
&amp;nbsp; &amp;nbsp; fontWeight = FontWeight.Normal,
&amp;nbsp; &amp;nbsp; fontFamily = FontFamily.SansSerif,
&amp;nbsp; &amp;nbsp; fontStyle = FontStyle.Italic,
&amp;nbsp; &amp;nbsp; fontSize = 16.sp,
&amp;nbsp; &amp;nbsp; lineHeight = 24.sp,
&amp;nbsp; &amp;nbsp; letterSpacing = 0.15.sp,
&amp;nbsp; &amp;nbsp; baselineShift = BaselineShift.Subscript
),&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;타이포그래피를 정의했으면 M3 MaterialTheme에 전달합니다&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;pre class=&quot;gcode&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_material3_typography_theme_setup&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/designsystems/Material3Snippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_material3_typography_theme_setup&quot;&gt;&lt;code&gt;MaterialTheme(
&amp;nbsp; &amp;nbsp; typography = replyTypography,
) {
&amp;nbsp; &amp;nbsp; // M3 app Content
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-text=&quot;Use text styles&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 id=&quot;use_text_styles&quot; data-text=&quot;Use text styles&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;Use text styles&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;MaterialTheme.typography를 사용하여 M3 MaterialTheme 컴포저블에 제공된 타이포그래피를 검색할 수 있습니다:&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;pre class=&quot;excel&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_material3_typography_use&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/designsystems/Material3Snippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_material3_typography_use&quot;&gt;&lt;code&gt;Text(
&amp;nbsp; &amp;nbsp; text = &quot;Hello M3 theming&quot;,
&amp;nbsp; &amp;nbsp; style = MaterialTheme.typography.titleLarge
)
Text(
&amp;nbsp; &amp;nbsp; text = &quot;you are learning typography&quot;,
&amp;nbsp; &amp;nbsp; style = MaterialTheme.typography.bodyMedium
)&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;타이포그래피 적용에 대한 자세한 내용은 &lt;a href=&quot;https://m3.material.io/styles/typography/applying-type&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;머티리얼 가이드라인&lt;/a&gt;을 참조하세요.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-text=&quot;Shapes&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 id=&quot;shapes&quot; data-text=&quot;Shapes&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Shapes&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot;&gt;Material&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot;&gt;surfaces&lt;/span&gt;은 다양한 모양으로 표시할 수 있습니다. 모양은 주의를 집중시키고, 구성 요소를 식별하고, 상태를 전달하고, 브랜드를 표현합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;모양 스케일은 컨테이너 모서리의 스타일을 정의하며, 정사각형부터 완전한 원형까지 다양한 둥근 모양을 제공합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-text=&quot;Define shapes&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 id=&quot;define_shapes&quot; data-text=&quot;Define shapes&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;Define shapes&lt;/span&gt;&lt;/h4&gt;
&lt;h4 data-text=&quot;Define shapes&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;Compose는 새로운 M3 도형을 지원하기 위해 확장된 매개변수를 M3 도형 클래스에 제공합니다. M3 셰이프 스케일은 유형 스케일과 비슷하여 UI 전체에서 다양한 셰이프를 표현할 수 있습니다.&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;다양한 크기의 모양이 있습니다:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Extra Small&lt;/li&gt;
&lt;li&gt;Small&lt;/li&gt;
&lt;li&gt;Medium&lt;/li&gt;
&lt;li&gt;Large&lt;/li&gt;
&lt;li&gt;Extra Large&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;기본적으로 각 도형에는 기본값이 있지만 이를 재정의할 수 있습니다:&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;pre class=&quot;kotlin&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_material3_shape_setup&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/designsystems/Material3Snippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_material3_shape_setup&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;val replyShapes = Shapes(
&amp;nbsp; &amp;nbsp; extraSmall = RoundedCornerShape(4.dp),
&amp;nbsp; &amp;nbsp; small = RoundedCornerShape(8.dp),
&amp;nbsp; &amp;nbsp; medium = RoundedCornerShape(12.dp),
&amp;nbsp; &amp;nbsp; large = RoundedCornerShape(16.dp),
&amp;nbsp; &amp;nbsp; extraLarge = RoundedCornerShape(24.dp)
)&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;셰이프를 정의한 후에는 M3 MaterialTheme에 전달할 수 있습니다:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;gcode&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_material3_shape_theme&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/designsystems/Material3Snippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_material3_shape_theme&quot;&gt;&lt;code&gt;MaterialTheme(
&amp;nbsp; &amp;nbsp; shapes = replyShapes,
) {
&amp;nbsp; &amp;nbsp; // M3 app Content
}&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;h4 data-text=&quot;Use shapes&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 id=&quot;use_shapes&quot; data-text=&quot;Use shapes&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;Use shapes&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;MaterialTheme의 모든 컴포넌트에 대해 모양 배율을 사용자 지정하거나 컴포넌트별로 사용자 지정할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;기본값으로 중간 및 큰 모양을 적용합니다:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;stylus&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_material3_shape_usage&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/designsystems/Material3Snippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_material3_shape_usage&quot;&gt;&lt;code&gt;Card(shape = MaterialTheme.shapes.medium) { /* card content */ }
FloatingActionButton(
&amp;nbsp; &amp;nbsp; shape = MaterialTheme.shapes.large,
&amp;nbsp; &amp;nbsp; onClick = {
&amp;nbsp; &amp;nbsp; }
) {
&amp;nbsp; &amp;nbsp; /* fab content */
}&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;445&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bB9AYw/btsHq0XHWUs/xn5zmCOYTCSd88sJ4R57Ik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bB9AYw/btsHq0XHWUs/xn5zmCOYTCSd88sJ4R57Ik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bB9AYw/btsHq0XHWUs/xn5zmCOYTCSd88sJ4R57Ik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbB9AYw%2FbtsHq0XHWUs%2Fxn5zmCOYTCSd88sJ4R57Ik%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;445&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;445&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;답장 샘플 앱에서 카드의 중간 모양과 플로팅 작업 버튼의 큰 모양&lt;/span&gt;&lt;br /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;다른 두 가지 도형인 직사각형 모양과 원 모양이 있으며, 이는 작성 기능의 일부입니다. 직사각형 모양은 테두리 반경이 없고 원 모양은 가장자리가 완전히 동그라미로 표시됩니다:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;stylus&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_material3_shape_usage_2&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/designsystems/Material3Snippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_material3_shape_usage_2&quot;&gt;&lt;code&gt;Card(shape = RectangleShape) { /* card content */ }
Card(shape = CircleShape) { /* card content */ }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;아래 예시는 기본 모양 값이 적용된 일부 컴포넌트를 보여줍니다:&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1004&quot; data-origin-height=&quot;1680&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Pfq5j/btsHqMelleJ/v10hDGzIAFXeiMsi8kQUi0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Pfq5j/btsHqMelleJ/v10hDGzIAFXeiMsi8kQUi0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Pfq5j/btsHqMelleJ/v10hDGzIAFXeiMsi8kQUi0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPfq5j%2FbtsHqMelleJ%2Fv10hDGzIAFXeiMsi8kQUi0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1004&quot; height=&quot;1680&quot; data-origin-width=&quot;1004&quot; data-origin-height=&quot;1680&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;모든 머티리얼 3 컴포넌트의 기본 모양 값입니다.&lt;/span&gt;&lt;br /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;모양 적용에 대한 &lt;a href=&quot;https://m3.material.io/styles/shape/overview&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;머티리얼 가이드라인&lt;/a&gt;에 대한 자세한 내용을 확인할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-text=&quot;Emphasis&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-text=&quot;Emphasis&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 id=&quot;emphasis&quot; data-text=&quot;Emphasis&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Emphasis&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;M3의 강조 기능은 다양한 색상과 색상 조합을 사용하여 제공됩니다. M3에서는 UI에 강조를 추가하는 두 가지 방법이 있습니다:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;확장된 M3 색상 시스템에서 표면, 표면 변형 및 배경을 표면, 표면 변형 색상과 함께 사용할 수 있습니다. 예를 들어 표면을 표면상의 변형과 함께 사용하고 표면상의 변형은 표면상의 변형과 함께 사용하여 다양한 수준의 강조를 제공할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;221&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCe4nY/btsHrrne1Rc/qUMSiPsl3ItmlYCOKGzrsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCe4nY/btsHrrne1Rc/qUMSiPsl3ItmlYCOKGzrsK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCe4nY/btsHrrne1Rc/qUMSiPsl3ItmlYCOKGzrsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCe4nY%2FbtsHrrne1Rc%2FqUMSiPsl3ItmlYCOKGzrsK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;221&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;221&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;강조를 위해 중성적인 색상 조합 사용.&lt;/span&gt;&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;텍스트에 다른 글꼴 가중치 사용하기. 위에서 유형 눈금에 사용자 지정 가중치를 제공하여 다양한 강조를 제공할 수 있음을 확인했습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;pre class=&quot;mathematica&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_material3_emphasis&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/designsystems/Material3Snippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_material3_emphasis&quot;&gt;&lt;code&gt;bodyLarge = TextStyle(
&amp;nbsp; &amp;nbsp; fontWeight = FontWeight.Bold
),
bodyMedium = TextStyle(
&amp;nbsp; &amp;nbsp; fontWeight = FontWeight.Normal
)&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;color: #202124; text-align: start;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #006dd7; text-align: start;&quot;&gt;M3에서 비활성화된 상태의 경우 알파값이 있는 &quot;on-x&quot;(여기서 x는 기본, 보조, 표면 등일 수 있음) 색상을 사용할 수 있습니다.&lt;/span&gt;&lt;br /&gt;
&lt;h2 data-text=&quot;Elevation&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-text=&quot;Elevation&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 id=&quot;elevation&quot; data-text=&quot;Elevation&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;Elevation&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Material &lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;3은 주로 톤 컬러 오버레이를 사용하여 높이를 나타냅니다. 이는 컨테이너와 표면을 서로 구별하는 새로운 방법으로, 그림자와 더불어 더 눈에 띄는 톤을 사용하여 톤의 높이를 높입니다.&lt;/span&gt;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;883&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bH8u98/btsHp4msVbO/s4XRSA7Jc4BaScJlmYv0H0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bH8u98/btsHp4msVbO/s4XRSA7Jc4BaScJlmYv0H0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bH8u98/btsHp4msVbO/s4XRSA7Jc4BaScJlmYv0H0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbH8u98%2FbtsHp4msVbO%2Fs4XRSA7Jc4BaScJlmYv0H0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;883&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;883&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;그림자 높이가 있는 톤&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;어두운 테마의 &lt;span style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot;&gt;Elevation&lt;/span&gt; 오버레이도 머티리얼 3에서 톤 컬러 오버레이로 변경되었습니다. 오버레이 색상은 기본 색상 슬롯에서 가져옵니다.&lt;/span&gt;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;848&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kAI0i/btsHpxbAyID/5UkG9sro6EqfTYBf4UgDv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kAI0i/btsHpxbAyID/5UkG9sro6EqfTYBf4UgDv1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kAI0i/btsHpxbAyID/5UkG9sro6EqfTYBf4UgDv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkAI0i%2FbtsHpxbAyID%2F5UkG9sro6EqfTYBf4UgDv1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;848&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;848&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;머티리얼 디자인에서 그림자 높이와 톤 높이 비교 3&lt;/span&gt;&lt;br /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;대부분의 M3 컴포넌트 뒤에 구성 가능한 배경인 M3 Surface는 톤 및 섀도 엘리베이션을 모두 지원합니다:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;jboss-cli&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_material3_elevation&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/designsystems/Material3Snippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_material3_elevation&quot;&gt;&lt;code&gt;Surface(
&amp;nbsp; &amp;nbsp; modifier = Modifier,
&amp;nbsp; &amp;nbsp; tonalElevation = /*...
&amp;nbsp; &amp;nbsp; shadowElevation = /*...
) {
&amp;nbsp; &amp;nbsp; Column(content = content)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;h2 id=&quot;material-components&quot; data-text=&quot;Material components&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;Material components&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;머티리얼 디자인에는 버튼, 칩, 카드, 탐색 모음 등 머티리얼 테마를 따르고 멋진 머티리얼 디자인 앱을 만드는 데 도움이 되는 다양한 &lt;a style=&quot;color: #000000;&quot; href=&quot;https://m3.material.io/components/all-buttons&quot;&gt;Material components&lt;/a&gt;&lt;span style=&quot;color: #202124; text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&gt; 세트가 함께 제공됩니다. 기본 속성이 있는 컴포넌트를 바로 사용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;pre class=&quot;less&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_material3_button_usage&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/designsystems/Material3Snippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_material3_button_usage&quot;&gt;&lt;code&gt;Button(onClick = { /*..*/ }) {
&amp;nbsp; &amp;nbsp; Text(text = &quot;My Button&quot;)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;M3는 강조점과 주목도에 따라 다양한 역할에 사용할 수 있도록 동일한 구성 요소의 여러 버전을 제공합니다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;920&quot; data-origin-height=&quot;1059&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqtL0U/btsHpLnap8g/38DsUP8yxT4TzpAmQh6Yy1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqtL0U/btsHpLnap8g/38DsUP8yxT4TzpAmQh6Yy1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqtL0U/btsHpLnap8g/38DsUP8yxT4TzpAmQh6Yy1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqtL0U%2FbtsHpLnap8g%2F38DsUP8yxT4TzpAmQh6Yy1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;920&quot; height=&quot;1059&quot; data-origin-width=&quot;920&quot; data-origin-height=&quot;1059&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;FAB, 기본에서 텍스트 버튼으로 버튼 강조 표시&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;color: #202124; text-align: start;&quot;&gt;&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;가장 강조된 동작을 위한 확장된 플로팅 동작 버튼입니다:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;kotlin&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_material3_extended_button_usage&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/designsystems/Material3Snippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_material3_extended_button_usage&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;ExtendedFloatingActionButton(
&amp;nbsp; &amp;nbsp; onClick = { /*..*/ },
&amp;nbsp; &amp;nbsp; modifier = Modifier
) {
&amp;nbsp; &amp;nbsp; Icon(
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; imageVector = Icons.Default.Edit,
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; contentDescription = stringResource(id = R.string.edit),
&amp;nbsp; &amp;nbsp; )
&amp;nbsp; &amp;nbsp; Text(
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; text = stringResource(id = R.string.add_entry),
&amp;nbsp; &amp;nbsp; )
}&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;강조 표시가 있는 버튼은 강조 표시가 있는 동작을 위한 버튼입니다&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;kotlin&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_material3_filled_button_high_emphasis&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/designsystems/Material3Snippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_material3_filled_button_high_emphasis&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;Button(onClick = { /*..*/ }) {
&amp;nbsp; &amp;nbsp; Text(text = stringResource(id = R.string.view_entry))
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;강조도가 낮은 동작을 위한 텍스트 버튼입니다&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;kotlin&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_material3_text_button_low_emphasis&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/designsystems/Material3Snippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_material3_text_button_low_emphasis&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;TextButton(onClick = { /*..*/ }) {
&amp;nbsp; &amp;nbsp; Text(text = stringResource(id = R.string.replated_articles))
}&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;&lt;a href=&quot;https://m3.material.io/components/all-buttons&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;머티리얼 버튼 및 기타 컴포넌트&lt;/a&gt;에 대해 자세히 알아볼 수 있습니다. Material 3는 다양한 사용 사례와 화면 크기에 맞게 특별히 설계된 버튼, 앱 바, 탐색 컴포넌트 등 다양한 컴포넌트 제품군을 제공합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;navigation-components&quot; data-text=&quot;Navigation components&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Navigation components&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;머티리얼은 또한 다양한 화면 크기와 상태에 따라 Navigation 을 구현하는 데 도움이 되는 여러 &lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;Navigation&lt;/span&gt; 구성 요소를 제공합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;내비게이션바는 &lt;span style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot;&gt;destinations 을&lt;/span&gt;&amp;nbsp;5개 이하로 지정하려는 경우 소형 기기에 사용합니다:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;stylus&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_material3_nav_bar_usage&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/designsystems/Material3Snippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_material3_nav_bar_usage&quot;&gt;&lt;code&gt;NavigationBar(modifier = Modifier.fillMaxWidth()) {
&amp;nbsp; &amp;nbsp; Destinations.entries.forEach { replyDestination -&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; NavigationBarItem(
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; selected = selectedDestination == replyDestination,
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; onClick = { },
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; icon = { }
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )
&amp;nbsp; &amp;nbsp; }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NavigationRail &lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;은 가로 모드에서 중소형 태블릿 또는 휴대폰에 사용됩니다. 사용자에게 인체공학적 디자인을 제공하고 해당 디바이스의 사용자 경험을 개선합니다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;pre class=&quot;jboss-cli&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_material3_nav_rail_usage&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/designsystems/Material3Snippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_material3_nav_rail_usage&quot;&gt;&lt;code&gt;NavigationRail(
&amp;nbsp; &amp;nbsp; modifier = Modifier.fillMaxHeight(),
) {
&amp;nbsp; &amp;nbsp; Destinations.entries.forEach { replyDestination -&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; NavigationRailItem(
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; selected = selectedDestination == replyDestination,
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; onClick = { },
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; icon = { }
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )
&amp;nbsp; &amp;nbsp; }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1067&quot; data-origin-height=&quot;836&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cF1Kaz/btsHqL7zNFR/XkFKenRkP1KHvyIGSuYmx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cF1Kaz/btsHqL7zNFR/XkFKenRkP1KHvyIGSuYmx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cF1Kaz/btsHqL7zNFR/XkFKenRkP1KHvyIGSuYmx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcF1Kaz%2FbtsHqL7zNFR%2FXkFKenRkP1KHvyIGSuYmx1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1067&quot; height=&quot;836&quot; data-origin-width=&quot;1067&quot; data-origin-height=&quot;836&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;하단 Navigation 모음(왼쪽) 및 NavigationRail(오른쪽)의 댓글 쇼케이스&lt;/span&gt;&lt;br /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;기본 테마에서 두 가지를 모두 사용하여 댓글을 작성하면 모든 디바이스 크기에 맞는 몰입형 사용자 경험을 제공할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;&lt;span style=&quot;background-color: #f8f9fa; color: #37474f; text-align: left;&quot;&gt;NavigationDrawer&lt;/span&gt;는 세부 정보를 표시하기에 충분한 공간이 있는 중대형 태블릿에 사용됩니다.&lt;span style=&quot;background-color: #f8f9fa; color: #37474f; text-align: left;&quot;&gt;NavigationRail과&lt;/span&gt; 함께 &lt;span style=&quot;background-color: #f8f9fa; color: #37474f; text-align: left;&quot;&gt;PermanentNavigationDrawer&lt;/span&gt; 또는 &lt;span style=&quot;background-color: #f8f9fa; color: #37474f; text-align: left;&quot;&gt;ModalNavigationDrawer &lt;/span&gt;를 모두 사용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;pre class=&quot;nix&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_material3_permanent_nav_drawer&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/designsystems/Material3Snippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_material3_permanent_nav_drawer&quot;&gt;&lt;code&gt;PermanentNavigationDrawer(modifier = Modifier.fillMaxHeight(), drawerContent = {
&amp;nbsp; &amp;nbsp; Destinations.entries.forEach { replyDestination -&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; NavigationRailItem(
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; selected = selectedDestination == replyDestination,
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; onClick = { },
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; icon = { },
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; label = { }
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )
&amp;nbsp; &amp;nbsp; }
}) {
}&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1058&quot; data-origin-height=&quot;1462&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cKM3Wn/btsHq2gVokP/eER4IXTTgPlikw5G9cO2j0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cKM3Wn/btsHq2gVokP/eER4IXTTgPlikw5G9cO2j0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cKM3Wn/btsHq2gVokP/eER4IXTTgPlikw5G9cO2j0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcKM3Wn%2FbtsHq2gVokP%2FeER4IXTTgPlikw5G9cO2j0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1058&quot; height=&quot;1462&quot; data-origin-width=&quot;1058&quot; data-origin-height=&quot;1462&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;span style=&quot;background-color: #f8f9fa; color: #37474f; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;PermanentNavigationDrawer &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;쇼케이스&lt;/span&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;br /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Navigation options은&amp;nbsp;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;사용자 경험, 인체공학 및 접근성을 향상시킵니다. &lt;span style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot;&gt;Material navigation  컴포넌트&lt;/span&gt;에 대한 자세한 내용은 적응형 컴포넌트 작성 코드랩에서 확인할 수 있습니다. (&lt;a style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; href=&quot;https://codelabs.developers.google.com/jetpack-compose-adaptability&quot;&gt;Compose adaptive codelab&lt;/a&gt;&lt;span style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot;&gt;.&lt;/span&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-text=&quot;Customize a component's theming&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-text=&quot;Customize a component's theming&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 id=&quot;customizing-components&quot; data-text=&quot;Customize a component's theming&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Customize a component's theming&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;M3는 개인화 및 유연성을 장려합니다. 모든 컴포넌트에는 기본 색상이 적용되어 있지만 필요한 경우 색상을 사용자 지정할 수 있는 유연한 API를 제공합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;카드 및 버튼과 같은 대부분의 컴포넌트는 색상과 높낮이를 노출하는 기본 개체 인터페이스를 제공하며, 이를 수정하여 컴포넌트를 사용자 지정할 수 있습니다:&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;pre class=&quot;stylus&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_material3_card_theming&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/designsystems/Material3Snippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_material3_card_theming&quot;&gt;&lt;code&gt;val customCardColors = CardDefaults.cardColors(
&amp;nbsp; &amp;nbsp; contentColor = MaterialTheme.colorScheme.primary,
&amp;nbsp; &amp;nbsp; containerColor = MaterialTheme.colorScheme.primaryContainer,
&amp;nbsp; &amp;nbsp; disabledContentColor = MaterialTheme.colorScheme.surface,
&amp;nbsp; &amp;nbsp; disabledContainerColor = MaterialTheme.colorScheme.onSurface,
)
val customCardElevation = CardDefaults.cardElevation(
&amp;nbsp; &amp;nbsp; defaultElevation = 8.dp,
&amp;nbsp; &amp;nbsp; pressedElevation = 2.dp,
&amp;nbsp; &amp;nbsp; focusedElevation = 4.dp
)
Card(
&amp;nbsp; &amp;nbsp; colors = customCardColors,
&amp;nbsp; &amp;nbsp; elevation = customCardElevation
) {
&amp;nbsp; &amp;nbsp; // m3 card content
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://m3.material.io/foundations/customization&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;머티리얼 3 커스터마이징에 대한 자세한 내용은 여기를 참조하세요.&lt;/span&gt;&lt;br /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 data-text=&quot;System UI&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-text=&quot;System UI&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 id=&quot;system-ui&quot; data-text=&quot;System UI&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;System UI&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;머티리얼 유는 Android 12 이상에서 새로운 시각적 스타일과 시스템 UI를 제공합니다. 변경된 두 가지 주요 영역은 리플과 오버스크롤입니다. 이러한 변경 사항을 구현하기 위해 추가 작업이 필요하지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 id=&quot;ripple&quot; data-text=&quot;Ripple&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Ripple&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Ripple now uses a subtle sparkle to illuminate surfaces when pressed.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://developer.android.com/reference/kotlin/androidx/compose/material/ripple/package-summary&quot;&gt;Compose Material Ripple&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;uses a platform RippleDrawable under the hood on Android, so sparkle ripple is available on Android 12 and above for all Material components.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;640&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zDJtq/btsHpdxHztq/ZHBtQc4kgwUVc8oPgkpL5K/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zDJtq/btsHpdxHztq/ZHBtQc4kgwUVc8oPgkpL5K/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zDJtq/btsHpdxHztq/ZHBtQc4kgwUVc8oPgkpL5K/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/zDJtq/btsHpdxHztq/ZHBtQc4kgwUVc8oPgkpL5K/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;640&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;640&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
Ripple in M2 versus M3
&lt;h3 data-text=&quot;Overscroll&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 id=&quot;overscroll&quot; data-text=&quot;Overscroll&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Overscroll&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;오버스크롤은 이제 스크롤 컨테이너의 가장자리에 스트레치 효과를 사용합니다. 스트레치 오버스크롤은 API 레벨에 관계없이 Compose Foundation 1.1.0 이상에서 스크롤 컨테이너 컴포저블(예: LazyColumn, LazyRow, LazyVerticalGrid)에서 기본적으로 켜져 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;173&quot; data-origin-height=&quot;374&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/J8R8i/btsHquSu94S/gVrLccrI4hCkFhUwDT8QaK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/J8R8i/btsHquSu94S/gVrLccrI4hCkFhUwDT8QaK/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/J8R8i/btsHquSu94S/gVrLccrI4hCkFhUwDT8QaK/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/J8R8i/btsHquSu94S/gVrLccrI4hCkFhUwDT8QaK/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;173&quot; height=&quot;374&quot; data-origin-width=&quot;173&quot; data-origin-height=&quot;374&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;컨테이너 가장자리에서 스트레치 효과를 사용하여 오버스크롤하기&lt;/span&gt;&lt;br /&gt;
&lt;h2 data-text=&quot;Accessibility&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 id=&quot;accessibility&quot; data-text=&quot;Accessibility&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;Accessibility&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;머티리얼 컴포넌트에 내장된 접근성 표준은 포용적인 제품 설계를 위한 기반을 제공하도록 설계되었습니다. 제품의 접근성을 이해하면 저시력, 시각 장애, 청각 장애, 인지 장애, 운동 장애 또는 상황적 장애(예: 팔 부러짐)를 가진 사용자를 포함한 모든 사용자의 사용성을 향상시킬 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-text=&quot;Color accessibility&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 id=&quot;color-accessibility&quot; data-text=&quot;Color accessibility&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Color accessibility&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;동적 색상은 색상 대비에 대한 접근성 표준을 충족하도록 설계되었습니다. 색조 팔레트 시스템은 기본적으로 모든 색 구성표에 액세스할 수 있도록 하는 데 매우 중요합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;머티리얼의 색상 시스템은 접근 가능한 명암비를 충족하는 데 사용할 수 있는 표준 톤 값과 측정값을 제공합니다.&lt;/span&gt;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;760&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tfSTx/btsHp987MPb/LPaQ2Cq9SlZQKvkLFHkcS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tfSTx/btsHp987MPb/LPaQ2Cq9SlZQKvkLFHkcS0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tfSTx/btsHp987MPb/LPaQ2Cq9SlZQKvkLFHkcS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtfSTx%2FbtsHp987MPb%2FLPaQ2Cq9SlZQKvkLFHkcS0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;760&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;760&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;샘플 앱: 기본, 보조 및 3차 색조 팔레트(위쪽에서 아래쪽)&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;color: #202124; text-align: start;&quot;&gt;&lt;br /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;모든 머티리얼 컴포넌트와 동적 테마는 접근성 요구 사항을 충족하도록 선택된 색조 팔레트 세트에서 위의 색상 역할을 이미 사용하고 있습니다. 그러나 컴포넌트를 사용자 지정하는 경우 적절한 색상 역할을 사용하여 불일치를 피해야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;기본 위에 기본을, 기본 컨테이너 위에 기본 컨테이너를 사용하고 다른 강조 색상과 중성 색상도 동일하게 사용하여 사용자가 쉽게 대비를 확인할 수 있도록 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;1차 컨테이너 위에 3차 컨테이너를 사용하면 사용자에게 대비가 좋지 않은 버튼을 제공합니다:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;jboss-cli&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_material3_button_contrast_example&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/designsystems/Material3Snippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_material3_button_contrast_example&quot;&gt;&lt;code&gt;// ✅ Button with sufficient contrast ratio
Button(
&amp;nbsp; &amp;nbsp; onClick = { },
&amp;nbsp; &amp;nbsp; colors = ButtonDefaults.buttonColors(
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; containerColor = MaterialTheme.colorScheme.primary,
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; contentColor = MaterialTheme.colorScheme.onPrimary
&amp;nbsp; &amp;nbsp; )
) {
}

// ❌ Button with poor contrast ratio
Button(
&amp;nbsp; &amp;nbsp; onClick = { },
&amp;nbsp; &amp;nbsp; colors = ButtonDefaults.buttonColors(
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; containerColor = MaterialTheme.colorScheme.tertiaryContainer,
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; contentColor = MaterialTheme.colorScheme.primaryContainer
&amp;nbsp; &amp;nbsp; )
) {
}&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;670&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMImYa/btsHpw4PkNI/7sagJhl6kxZmZTisl1A2jK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMImYa/btsHpw4PkNI/7sagJhl6kxZmZTisl1A2jK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMImYa/btsHpw4PkNI/7sagJhl6kxZmZTisl1A2jK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMImYa%2FbtsHpw4PkNI%2F7sagJhl6kxZmZTisl1A2jK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;670&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;670&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;충분한 대비(왼쪽)와 낮은 대비(오른쪽) 비교&lt;/span&gt;&lt;br /&gt;
&lt;h3 data-text=&quot;Typography accessibility&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 id=&quot;typography-accessibility&quot; data-text=&quot;Typography accessibility&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Typography accessibility&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;M3 유형 스케일은 정적 유형 램프와 값을 업데이트하여 여러 디바이스에서 확장 가능한 단순하지만 동적인 크기 카테고리의 프레임워크를 제공합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;예를 들어, M3에서는 휴대폰이나 태블릿 등 디바이스 상황에 따라 '작게 표시'에 다른 값을 지정할 수 있습니다&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;large-screens&quot; data-text=&quot;Large screens&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;Large screens&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;Material은 적응형 레이아웃과 폴더블에 대한 지침을 제공하여 앱의 접근성을 높이고 대형 기기를 사용하는 사용자의 인체공학적 환경을 개선할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;Material은 대형 디바이스에서 더 나은 사용자 경험을 제공할 수 있도록 다양한 종류의 Navigation 기능을 제공합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;Android 대화면 &lt;a href=&quot;https://developer.android.com/docs/quality-guidelines/large-screen-app-quality&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;앱 품질 가이드라인&lt;/a&gt;에 대해 자세히 알아보고 적응형 및 접근성 디자인에 대한 응답 샘플을 참조하세요.&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고 : &lt;a href=&quot;https://developer.android.com/develop/ui/compose/compiler&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://developer.android.com/develop/ui/compose/compiler&lt;/a&gt;&lt;/p&gt;</description>
      <category>안드로이드/Compose</category>
      <category>Android</category>
      <category>compose</category>
      <category>안드로이드</category>
      <category>컴포즈</category>
      <author>헬창코딩</author>
      <guid isPermaLink="true">https://healthcoding.tistory.com/69</guid>
      <comments>https://healthcoding.tistory.com/69#entry69comment</comments>
      <pubDate>Sat, 18 May 2024 17:54:04 +0900</pubDate>
    </item>
    <item>
      <title>Compose 공식문서정리(3) - Thinking in Compose</title>
      <link>https://healthcoding.tistory.com/68</link>
      <description>&lt;p style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #202124; font-size: 1.62em; letter-spacing: -1px; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif;&quot;&gt;선언적 프로그래밍 패러다임&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;지금까지 안드로이드 뷰 계층 구조는 UI 위젯의 트리로 표현할 수 있었습니다. 사용자 상호작용 등으로 인해 앱의 상태가 변경되면 현재 데이터를 표시하기 위해 UI 계층구조를 업데이트해야 합니다. UI를 업데이트하는 가장 일반적인 방법은 findViewById()와 같은 함수를 사용하여 트리를 탐색하고 button.setText(String), container.addChild(View) 또는 img.setImageBitmap(Bitmap) 같은 메서드를 호출하여 노드를 변경하는 것입니다. 이러한 메서드는 위젯의 내부 상태를 변경합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;뷰를 수동으로 조작하면 오류가 발생할 가능성이 높아집니다. 데이터가 여러 곳에 렌더링되는 경우 데이터를 표시하는 뷰 중 하나를 업데이트하는 것을 잊어버리기 쉽습니다. 또한 두 업데이트가 예기치 않은 방식으로 충돌하는 경우 잘못된 상태가 발생하기 쉽습니다. 예를 들어, 업데이트가 UI에서 방금 제거된 노드의 값을 설정하려고 시도할 수 있습니다. 일반적으로 소프트웨어 유지 관리의 복잡성은 업데이트가 필요한 뷰의 수에 따라 증가합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;지난 몇 년 동안 업계 전체가 선언적 UI 모델로 전환하기 시작하면서 사용자 인터페이스 구축 및 업데이트와 관련된 엔지니어링이 크게 간소화되었습니다. 이 기술은 전체 화면을 개념적으로 처음부터 다시 생성한 다음 필요한 변경 사항만 적용하는 방식으로 작동합니다. 이 접근 방식은 상태 저장 뷰 계층 구조를 수동으로 업데이트하는 복잡성을 피할 수 있습니다. Compose는 선언적 UI 프레임워크입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;전체 화면을 재생성할 때 한 가지 문제점은 시간, 컴퓨팅 파워, 배터리 사용량 측면에서 비용이 많이 든다는 점입니다. 이러한 비용을 줄이기 위해 Compose는 특정 시점에 다시 그려야 하는 UI 부분을 지능적으로 선택합니다. 이는 ReComposition에서 설명한 대로 UI 컴포넌트를 디자인하는 방식에 몇 가지 영향을 미칩니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-text=&quot;A simple composable function&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 id=&quot;simple-example&quot; style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-text=&quot;A simple composable function&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;간단한 컴포저블 기능&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;컴포즈를 사용하면 데이터를 받아 UI 요소를 출력하는 컴포저블 함수 집합을 정의하여 사용자 인터페이스를 구축할 수 있습니다. 간단한 예로 문자열을 받아 인사말 메시지를 표시하는 텍스트 위젯을 출력하는 Greeting 위젯을 들 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baAgbE/btsHq7JeZw8/s0h5kGrmIRY0InH6bkMMh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baAgbE/btsHq7JeZw8/s0h5kGrmIRY0InH6bkMMh0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baAgbE/btsHq7JeZw8/s0h5kGrmIRY0InH6bkMMh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaAgbE%2FbtsHq7JeZw8%2Fs0h5kGrmIRY0InH6bkMMh0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;위 그림은 데이터를 전달받아 이를 사용하여 화면에 텍스트 위젯을 렌더링하는 간단한 컴포저블 함수입니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;@Composable&lt;span style=&quot;background-color: #ffffff; color: #202124; text-align: left;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&amp;nbsp;어노테이션으로 함수에 주석을 달았습니다. 모든 컴포저블 함수에는 이 어노테이션이 있어야 하며, 이 어노테이션은 컴포저 컴파일러에 이 함수가 데이터를 UI로 변환하기 위한 것임을 알려줍니다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;함수는 데이터를 받습니다. 컴포저블 함수는 앱 로직이 UI를 설명할 수 있도록 매개변수를 받아들일 수 있습니다. 이 경우 위젯은 문자열을 받아 이름으로 사용자를 맞이할 수 있습니다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;이 함수는 UI에 텍스트를 표시합니다. 이 함수는 실제로 텍스트 UI 요소를 생성하는 Text() 컴포저블 함수를 호출하여 텍스트를 표시합니다. 컴포저블 함수는 다른 컴포저블 함수를 호출하여 UI 계층구조를 생성합니다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;이 함수는 아무 것도 반환하지 않습니다. UI를 출력하는 컴포짓 함수는 UI 위젯을 구성하는 대신 원하는 화면 상태를 설명하기 때문에 아무 것도 반환할 필요가 없습니다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;이 기능은 빠르고 무력하며 side-effects가 없습니다.&lt;/span&gt;&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이 함수는 동일한 인수로 여러 번 호출해도 동일한 방식으로 동작하며, 전역 변수나 random() 호출과 같은 다른 값을 사용하지 않습니다.&lt;/li&gt;
&lt;li&gt;이 함수는 프로퍼티나 전역 변수를 수정하는 등의 side-effects 없이 UI를 설명합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;paradigm&quot; style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-text=&quot;The declarative paradigm shift&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;선언적 패러다임의 전환&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;많은 필수 객체 지향 UI 툴킷을 사용하면 위젯 트리를 인스턴스화하여 UI를 초기화합니다. 이 작업은 종종 XML 레이아웃 파일을 인플레이트하여 수행합니다. 각 위젯은 자체 내부 상태를 유지하며 앱 로직이 위젯과 상호 작용할 수 있도록 하는 게터 및 세터 메서드를 노출합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;컴포즈의 선언적 접근 방식에서 위젯은 상대적으로 상태가 없으며 세터나 게터 함수를 노출하지 않습니다. 실제로 위젯은 객체로 노출되지 않습니다. 다른 인수를 사용하여 동일한 컴포저블 함수를 호출하여 UI를 업데이트합니다. 이렇게 하면 앱 아키텍처 가이드에 설명된 대로 뷰모델과 같은 아키텍처 패턴에 상태를 쉽게 제공할 수 있습니다. 그러면 컴포저블은 관찰 가능한 데이터가 업데이트될 때마다 현재 애플리케이션 상태를 UI로 변환하는 작업을 담당합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cm8TLj/btsHpyBAfP9/YVrkhRcz3pczOskWA6ckN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cm8TLj/btsHpyBAfP9/YVrkhRcz3pczOskWA6ckN0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cm8TLj/btsHpyBAfP9/YVrkhRcz3pczOskWA6ckN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcm8TLj%2FbtsHpyBAfP9%2FYVrkhRcz3pczOskWA6ckN0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;위 그림은 앱 로직은 최상위 컴포저블 함수에 데이터를 제공합니다. 이 함수는 데이터를 사용하여 다른 컴포저블을 호출하여 UI를 설명하고, 해당 컴포저블에 적절한 데이터를 전달하고 계층 구조를 따라 내려갑니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;사용자가 UI와 상호 작용하면 UI는 onClick과 같은 이벤트를 발생시킵니다. 이러한 이벤트는 앱 로직에 알림을 보내면 앱의 상태를 변경할 수 있습니다. 상태가 변경되면 컴포저블 함수가 새 데이터로 다시 호출됩니다. 이렇게 하면 UI 요소가 다시 그려지는데, 이 과정을 &lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot;&gt;recomposition&lt;/span&gt;&lt;/b&gt;이라고 합니다&lt;/span&gt;.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FQg0W/btsHqb6Y2eq/oN4zUNsqSFxv1gF38LUgmk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FQg0W/btsHqb6Y2eq/oN4zUNsqSFxv1gF38LUgmk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FQg0W/btsHqb6Y2eq/oN4zUNsqSFxv1gF38LUgmk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFQg0W%2FbtsHqb6Y2eq%2FoN4zUNsqSFxv1gF38LUgmk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;위 그림은사용자가 UI 요소와 상호 작용하여 이벤트가 트리거되었습니다. 앱 로직이 이벤트에 응답하면 필요한 경우 컴포저블 함수가 새 매개변수를 사용하여 자동으로 다시 호출됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;dynamic&quot; style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-text=&quot;Dynamic content&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;동적 컨텐츠&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;컴포저블 함수는 XML 대신 Kotlin으로 작성되므로 다른 Kotlin 코드와 마찬가지로 동적으로 작성할 수 있습니다. 예를 들어 사용자 목록을 맞이하는 UI를 빌드한다고 가정해 보겠습니다:&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;pre class=&quot;kotlin&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_thinking_in_compose_dynamic_content&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/mentalmodel/ThinkingInComposeSnippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_thinking_in_compose_dynamic_content&quot;&gt;&lt;code&gt;@Composable
fun Greeting(names: List&amp;lt;String&amp;gt;) {
&amp;nbsp; &amp;nbsp; for (name in names) {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Text(&quot;Hello $name&quot;)
&amp;nbsp; &amp;nbsp; }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;이 함수는 이름 목록을 받아 각 사용자에 대한 인사말을 생성합니다. 컴포저블 함수는 상당히 정교할 수 있습니다. if 문을 사용하여 특정 UI 요소를 표시할지 여부를 결정할 수 있습니다. 루프를 사용할 수 있습니다. 헬퍼 함수를 호출할 수 있습니다. 기본 언어의 모든 유연성을 활용할 수 있습니다. 이러한 강력한 성능과 유연성은 Jetpack Compose의 주요 장점 중 하나입니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;recomposition&quot; style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-text=&quot;Recomposition&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;Recomposition&lt;/span&gt;(재구성)&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;명령형 UI 모델에서 위젯을 변경하려면 위젯의 설정자를 호출하여 내부 상태를 변경합니다. Compose에서는 새 데이터를 사용하여 컴포저블 함수를 다시 호출합니다. 이렇게 하면 함수가 재구성되고, 필요한 경우 함수에 의해 방출된 위젯이 새 데이터로 다시 그려집니다. 작성 프레임워크는 변경된 컴포넌트만 지능적으로 &lt;span style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot;&gt;recompose &lt;/span&gt;할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;예를 들어 버튼을 표시하는 이 컴포저블 함수를 생각해 보겠습니다:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;kotlin&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_thinking_in_compose_recomposition&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/mentalmodel/ThinkingInComposeSnippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_thinking_in_compose_recomposition&quot;&gt;&lt;code&gt;@Composable
fun ClickCounter(clicks: Int, onClick: () -&amp;gt; Unit) {
&amp;nbsp; &amp;nbsp; Button(onClick = onClick) {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Text(&quot;I've been clicked $clicks times&quot;)
&amp;nbsp; &amp;nbsp; }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;버튼을 클릭할 때마다 호출자는 클릭 수 값을 업데이트합니다. Compose는 새 값을 표시하기 위해 Text 함수로 람다를 다시 호출하며, 이 과정을 recomposition이라고 합니다. 값에 의존하지 않는 다른 함수는 재구성되지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;앞서 설명한 것처럼 전체 UI 트리를 재구성하는 작업은 컴퓨팅 성능과 배터리 수명을 소모하는 계산 비용이 많이 들 수 있습니다. 컴포즈는 이 지능형 &lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;recomposition&lt;/span&gt; 통해 이 문제를 해결합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Recomposition 은&amp;nbsp;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;입력이 변경될 때 컴포저블 함수를 다시 호출하는 프로세스입니다. 이는 함수의 입력이 변경될 때 발생합니다. 컴포즈는 새로운 입력에 따라 재작성할 때 변경되었을 수 있는 함수나 람다만 호출하고 나머지는 건너뜁니다. 매개변수가 변경되지 않은 함수나 람다를 모두 건너뛰면 컴포즈는 효율적으로 재구성할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;함수의 재구성을 건너뛸 수 있으므로 컴포저블 함수 실행으로 인한 부작용에 의존해서는 안 됩니다. 그렇게 하면 사용자가 앱에서 이상하고 예측할 수 없는 동작을 경험할 수 있습니다. 부작용이란 앱의 나머지 부분에 표시되는 모든 변경 사항을 말합니다. 예를 들어 이러한 동작은 모두 위험한 부작용입니다:&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;공유 개체의 프로퍼티에 쓰기&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;ViewModel에서 관찰 가능 항목 업데이트하기&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;공유 환경 설정 업데이트하기&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;컴포저블 함수는 애니메이션이 렌더링될 때와 같이 매 프레임마다 자주 다시 실행될 수 있습니다. 컴포저블 함수는 애니메이션 중 끊김 현상을 방지하려면 속도가 빨라야 합니다. 공유 환경설정에서 읽는 것과 같이 비용이 많이 드는 연산을 수행해야 하는 경우 백그라운드 코루틴에서 수행하고 값 결과를 컴포저블 함수에 매개변수로 전달하세요.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;예를 들어, 이 코드는 공유 환경설정의 값을 업데이트하는 컴포저블을 생성합니다. 컴포저블은 공유 환경설정 자체에서 읽거나 쓰지 않아야 합니다. 대신 이 코드는 백그라운드 코루틴에서 읽기 및 쓰기를 뷰모델로 이동합니다. 앱 로직은 콜백을 통해 현재 값을 전달하여 업데이트를 트리거합니다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;pre class=&quot;kotlin&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_thinking_in_compose_recomposition_logic&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/mentalmodel/ThinkingInComposeSnippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_thinking_in_compose_recomposition_logic&quot;&gt;&lt;code&gt;@Composable
fun SharedPrefsToggle(
&amp;nbsp; &amp;nbsp; text: String,
&amp;nbsp; &amp;nbsp; value: Boolean,
&amp;nbsp; &amp;nbsp; onValueChanged: (Boolean) -&amp;gt; Unit
) {
&amp;nbsp; &amp;nbsp; Row {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Text(text)
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Checkbox(checked = value, onCheckedChange = onValueChanged)
&amp;nbsp; &amp;nbsp; }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;작성 기능을 사용할 때 주의해야 할 여러 가지 사항에 대해 설명합니다:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;컴포저블 함수는 어떤 순서로든 실행할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;컴포저블 함수는 병렬로 실행할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Recomposition 은&amp;nbsp;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;가능한 한 많은 컴포저블 함수와 람다를 건너뜁니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Recomposition &lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;낙관적이며 취소될 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;컴포저블 함수는 애니메이션의 모든 프레임만큼 자주 실행될 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-text=&quot;Composable functions can execute in any order&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;&lt;br /&gt;컴포저블 함수는 어떤 순서로든 실행할 수 있습니다.&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;컴포저블 함수의 코드를 보면 코드가 표시된 순서대로 실행된다고 생각할 수 있습니다. 하지만 반드시 그렇지는 않습니다. 컴포저블 함수에 다른 컴포저블 함수에 대한 호출이 포함된 경우 해당 함수는 어떤 순서로든 실행될 수 있습니다. 컴포즈에는 일부 UI 요소가 다른 요소보다 우선순위가 높다는 것을 인식하여 먼저 그리는 옵션이 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;예를 들어 탭 레이아웃에 세 개의 화면을 그리는 다음과 같은 코드가 있다고 가정해 보겠습니다:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;kotlin&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_thinking_in_compose_order&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/mentalmodel/ThinkingInComposeSnippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_thinking_in_compose_order&quot;&gt;&lt;code&gt;@Composable
fun ButtonRow() {
&amp;nbsp; &amp;nbsp; MyFancyNavigation {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; StartScreen()
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; MiddleScreen()
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; EndScreen()
&amp;nbsp; &amp;nbsp; }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;StartScreen, MiddleScreen, EndScreen 호출은 어떤 순서로든 발생할 수 있습니다. 즉, 예를 들어 StartScreen()이 전역 변수를 설정하고( side-effects) MiddleScreen()이 그 변경 사항을 활용하도록 할 수 없습니다. 대신 각 함수는 독립적으로 사용해야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-text=&quot;Composable functions can run in parallel&quot; data-ke-size=&quot;size23&quot;&gt;컴포저블 함수를 병렬로 실행할 수 있습니다.&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;컴포즈는 컴포지션 가능한 함수를 병렬로 실행하여 재구성을 최적화할 수 있습니다. 이를 통해 Compose는 여러 코어를 활용하고 화면에 표시되지 않는 컴포지션 가능한 함수는 우선순위를 낮춰 실행할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;이 최적화는 컴포저블 함수가 백그라운드 스레드 풀 내에서 실행될 수 있음을 의미합니다. 컴포저블 함수가 뷰모델의 함수를 호출하는 경우, 컴포즈는 여러 스레드에서 동시에 해당 함수를 호출할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;애플리케이션이 올바르게 동작하도록 하려면 컴포저블 함수에 부작용이 없어야 합니다. 대신 항상 UI 스레드에서 실행되는 onClick과 같은 콜백에서 부작용을 트리거하세요.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;컴포저블 함수가 호출될 때 호출자가 아닌 다른 스레드에서 호출이 발생할 수 있습니다. 즉, 컴포저블 람다의 변수를 수정하는 코드는 스레드 안전하지 않으며 컴포저블 람다의 허용되지 않는 부작용이기 때문에 피해야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;다음은 목록과 그 개수를 표시하는 컴포저블을 보여주는 예시입니다:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;kotlin&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_thinking_in_compose_parallel&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/mentalmodel/ThinkingInComposeSnippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_thinking_in_compose_parallel&quot;&gt;&lt;code&gt;@Composable
fun ListComposable(myList: List&amp;lt;String&amp;gt;) {
&amp;nbsp; &amp;nbsp; Row(horizontalArrangement = Arrangement.SpaceBetween) {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Column {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; for (item in myList) {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Text(&quot;Item: $item&quot;)
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Text(&quot;Count: ${myList.size}&quot;)
&amp;nbsp; &amp;nbsp; }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;이 코드는 부작용이 없으며 입력 목록을 UI로 변환합니다. 작은 목록을 표시하는 데 좋은 코드입니다. 그러나 함수가 로컬 변수에 쓰는 경우 이 코드는 스레드 안전하지 않거나 올바르지 않습니다:&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;pre class=&quot;kotlin&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_thinking_in_compose_incorrect&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/mentalmodel/ThinkingInComposeSnippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_thinking_in_compose_incorrect&quot;&gt;&lt;code&gt;@Composable
@Deprecated(&quot;Example with bug&quot;)
fun ListWithBug(myList: List&amp;lt;String&amp;gt;) {
&amp;nbsp; &amp;nbsp; var items = 0

&amp;nbsp; &amp;nbsp; Row(horizontalArrangement = Arrangement.SpaceBetween) {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Column {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; for (item in myList) {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Text(&quot;Item: $item&quot;)
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; items++ // Avoid! Side-effect of the column recomposing.
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Text(&quot;Count: $items&quot;)
&amp;nbsp; &amp;nbsp; }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;이 예제에서는 항목이 재구성될 때마다 수정됩니다. 애니메이션의 모든 프레임이 될 수도 있고 목록이 업데이트될 수도 있습니다. 어느 쪽이든 UI에 잘못된 개수가 표시됩니다. 따라서 이와 같은 쓰기는 컴포즈에서 지원되지 않으며, 이러한 쓰기를 금지함으로써 프레임워크가 스레드를 변경하여 컴포즈 가능한 람다를 실행할 수 있도록 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-text=&quot;Recomposition skips as much as possible&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;가능한 한 &lt;/span&gt;&lt;span&gt;Recomposition 건너뛰기&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;UI의 일부가 유효하지 않은 경우, 컴포즈는 업데이트가 필요한 부분만 재구성하기 위해 최선을 다합니다. 즉, UI 트리에서 위나 아래에 있는 컴포저블을 실행하지 않고 단일 버튼의 컴포저블을 다시 실행하는 것으로 건너뛸 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;모든 컴포저블 함수와 람다는 자체적으로 재구성할 수 있습니다. 다음은 목록을 렌더링할 때 재구성을 통해 일부 요소를 건너뛰는 방법을 보여주는 예시입니다:&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;pre class=&quot;kotlin&quot; style=&quot;color: #000000; text-align: left;&quot; data-region-tag=&quot;android_compose_thinking_in_compose_skips&quot; data-github-path=&quot;android/snippets/compose/snippets/src/main/java/com/example/compose/snippets/mentalmodel/ThinkingInComposeSnippets.kt&quot; data-code-snippet=&quot;true&quot; data-scope=&quot;android_compose_thinking_in_compose_skips&quot;&gt;&lt;code&gt;/**
&amp;nbsp;* Display a list of names the user can click with a header
&amp;nbsp;*/
@Composable
fun NamePicker(
&amp;nbsp; &amp;nbsp; header: String,
&amp;nbsp; &amp;nbsp; names: List&amp;lt;String&amp;gt;,
&amp;nbsp; &amp;nbsp; onNameClicked: (String) -&amp;gt; Unit
) {
&amp;nbsp; &amp;nbsp; Column {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // this will recompose when [header] changes, but not when [names] changes
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Text(header, style = MaterialTheme.typography.bodyLarge)
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Divider()

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // LazyColumn is the Compose version of a RecyclerView.
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // The lambda passed to items() is similar to a RecyclerView.ViewHolder.
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; LazyColumn {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; items(names) { name -&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // When an item's [name] updates, the adapter for that item
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // will recompose. This will not recompose when [header] changes
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; NamePickerItem(name, onNameClicked)
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&amp;nbsp; &amp;nbsp; }
}

/**
&amp;nbsp;* Display a single name the user can click.
&amp;nbsp;*/
@Composable
private fun NamePickerItem(name: String, onClicked: (String) -&amp;gt; Unit) {
&amp;nbsp; &amp;nbsp; Text(name, Modifier.clickable(onClick = { onClicked(name) }))
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;이러한 각 범위는 재구성 중에 실행할 유일한 것일 수 있습니다. 머리글이 변경될 때 Compose는 부모를 실행하지 않고 Column 람다로 건너뛸 수 있습니다. 그리고 Column을 실행할 때 이름이 변경되지 않은 경우 Compose는 LazyColumn의 항목을 건너뛰도록 선택할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;다시 말하지만, 모든 컴포저블 함수나 람다를 실행할 때는 부작용이 없어야 합니다. 부작용을 수행해야 하는 경우 콜백에서 트리거하세요.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-text=&quot;Recomposition is optimistic&quot; data-ke-size=&quot;size23&quot;&gt;재구성은 낙관적입니다.&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;Recomposition 은 컴포저블의 파라미터가 변경되었을 수 있다고 Compose가 판단할 때마다 시작됩니다. 재구성은 낙관적이기 때문에 컴포즈는 파라미터가 다시 변경되기 전에 재구성을 완료할 것으로 예상합니다. 재구성이 완료되기 전에 매개변수가 변경되면 컴포즈는 재구성을 취소하고 새 매개변수로 다시 시작할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;재구성을 취소하면 컴포지션은 재구성에서 UI 트리를 삭제합니다. 표시되는 UI에 따라 달라지는 부작용이 있는 경우 컴포지션이 취소되더라도 부작용이 적용됩니다. 이로 인해 앱 상태가 일관되지 않을 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;모든 컴포지션 가능한 함수와 람다가 비활성 상태이고 부작용이 없는지 확인하여 낙관적인 재구성을 처리합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-text=&quot;Composable functions might run quite frequently&quot; data-ke-size=&quot;size23&quot;&gt;컴포저블 함수는 꽤 자주 실행될 수 있습니다.&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;경우에 따라 UI 애니메이션의 모든 프레임에 대해 컴포저블 함수가 실행될 수 있습니다. 함수가 디바이스 스토리지에서 읽는 것과 같이 비용이 많이 드는 작업을 수행하는 경우, 이 함수로 인해 UI가 끊길 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;예를 들어 위젯이 디바이스 설정을 읽으려고 하면 1초에 수백 번씩 해당 설정을 읽게 되어 앱 성능에 치명적인 영향을 미칠 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;컴포저블 함수에 데이터가 필요한 경우 데이터에 대한 매개변수를 정의해야 합니다. 그런 다음 비용이 많이 드는 작업을 컴포저블 외부의 다른 스레드로 옮기고 mutableStateOf 또는 LiveData를 사용하여 데이터를 Compose에 전달할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고 : &lt;a href=&quot;https://developer.android.com/develop/ui/compose/compiler&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://developer.android.com/develop/ui/compose/compiler&lt;/a&gt;&lt;/p&gt;</description>
      <category>안드로이드/Compose</category>
      <category>Android</category>
      <category>compose</category>
      <category>안드로이드</category>
      <category>컴포즈</category>
      <author>헬창코딩</author>
      <guid isPermaLink="true">https://healthcoding.tistory.com/68</guid>
      <comments>https://healthcoding.tistory.com/68#entry68comment</comments>
      <pubDate>Fri, 17 May 2024 16:14:06 +0900</pubDate>
    </item>
    <item>
      <title>Compose 공식문서정리(2) - Set up Compose for an existing app(컴포즈 사용하기)</title>
      <link>https://healthcoding.tistory.com/67</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;컴포즈 gradle 설정&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;Compose를 사용하려면 먼저 프로젝트에 몇 가지 빌드 구성을 추가해야 합니다. 앱의 &lt;b&gt;build.gradle&lt;/b&gt; 파일에 다음 정의를 추가합니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;kotlin&quot; style=&quot;color: #000000; text-align: left;&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;android {
&amp;nbsp; &amp;nbsp; buildFeatures {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; compose = true
&amp;nbsp; &amp;nbsp; }

&amp;nbsp; &amp;nbsp; composeOptions {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; kotlinCompilerExtensionVersion = &quot;1.5.13&quot;
&amp;nbsp; &amp;nbsp; }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;몇 가지 주의해야 할 사항&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;1. Android BuildFeatures 블록 내에서 compose 플래그를 true로 설정하면 컴파일 기능이 활성화됩니다.&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;2. ComposeOptions 블록에 정의된 Kotlin 컴파일러 확장 버전 관리는 Kotlin 버전 관리와 연동됩니다. 호환성 맵을 참조하여 프로젝트의 Kotlin 버전과 일치하는 라이브러리 버전을 선택해야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;아래 블록에서 필요한 Compose BOM 및 Compose 라이브러리 종속성의 하위 집합을 종속성에 추가합니다&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;isbl&quot; style=&quot;color: #000000; text-align: left;&quot;&gt;&lt;code&gt;dependencies {

&amp;nbsp; &amp;nbsp; val composeBom = platform(&quot;androidx.compose:compose-bom:2024.05.00&quot;)
&amp;nbsp; &amp;nbsp; implementation(composeBom)
&amp;nbsp; &amp;nbsp; androidTestImplementation(composeBom)

&amp;nbsp; &amp;nbsp; // Choose one of the following:
&amp;nbsp; &amp;nbsp; // Material Design 3
&amp;nbsp; &amp;nbsp; implementation(&quot;androidx.compose.material3:material3&quot;)
&amp;nbsp; &amp;nbsp; // or Material Design 2
&amp;nbsp; &amp;nbsp; implementation(&quot;androidx.compose.material:material&quot;)
&amp;nbsp; &amp;nbsp; // or skip Material Design and build directly on top of foundational components
&amp;nbsp; &amp;nbsp; implementation(&quot;androidx.compose.foundation:foundation&quot;)
&amp;nbsp; &amp;nbsp; // or only import the main APIs for the underlying toolkit systems,
&amp;nbsp; &amp;nbsp; // such as input and measurement/layout
&amp;nbsp; &amp;nbsp; implementation(&quot;androidx.compose.ui:ui&quot;)

&amp;nbsp; &amp;nbsp; // Android Studio Preview support
&amp;nbsp; &amp;nbsp; implementation(&quot;androidx.compose.ui:ui-tooling-preview&quot;)
&amp;nbsp; &amp;nbsp; debugImplementation(&quot;androidx.compose.ui:ui-tooling&quot;)

&amp;nbsp; &amp;nbsp; // UI Tests
&amp;nbsp; &amp;nbsp; androidTestImplementation(&quot;androidx.compose.ui:ui-test-junit4&quot;)
&amp;nbsp; &amp;nbsp; debugImplementation(&quot;androidx.compose.ui:ui-test-manifest&quot;)

&amp;nbsp; &amp;nbsp; // Optional - Included automatically by material, only add when you need
&amp;nbsp; &amp;nbsp; // the icons but not the material library (e.g. when using Material3 or a
&amp;nbsp; &amp;nbsp; // custom design system based on Foundation)
&amp;nbsp; &amp;nbsp; implementation(&quot;androidx.compose.material:material-icons-core&quot;)
&amp;nbsp; &amp;nbsp; // Optional - Add full set of material icons
&amp;nbsp; &amp;nbsp; implementation(&quot;androidx.compose.material:material-icons-extended&quot;)
&amp;nbsp; &amp;nbsp; // Optional - Add window size utils
&amp;nbsp; &amp;nbsp; implementation(&quot;androidx.compose.material3:material3-window-size-class&quot;)

&amp;nbsp; &amp;nbsp; // Optional - Integration with activities
&amp;nbsp; &amp;nbsp; implementation(&quot;androidx.activity:activity-compose:1.9.0&quot;)
&amp;nbsp; &amp;nbsp; // Optional - Integration with ViewModels
&amp;nbsp; &amp;nbsp; implementation(&quot;androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1&quot;)
&amp;nbsp; &amp;nbsp; // Optional - Integration with LiveData
&amp;nbsp; &amp;nbsp; implementation(&quot;androidx.compose.runtime:runtime-livedata&quot;)
&amp;nbsp; &amp;nbsp; // Optional - Integration with RxJava
&amp;nbsp; &amp;nbsp; implementation(&quot;androidx.compose.runtime:runtime-rxjava2&quot;)

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;참고: Jetpack Compose는 모든 라이브러리 그룹의 버전을 동기화하기 위해 BOM(Bill of Materials)을 사용하여 제공됩니다. 자세한 내용은 부품 명세서 페이지에서 확인하세요.&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;컴파일 그래들 플러그인 작성&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;Gradle 사용자의 경우 Compose 컴파일러 Gradle 플러그인을 사용하면 Compose를 더 쉽게 설정하고 구성할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;참고: Compose 컴파일러 그래들 플러그인은 Kotlin 2.0 이상에서만 사용할 수 있습니다. 마이그레이션 지침은 &quot;Jetpack Compose 컴파일러를 Kotlin 리포지토리로 이동하기&quot;를 참조하세요. 마이그레이션 예제는 샘플 작성에서 샘플 작성 PR을 참조하세요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;Gradle 버전 카탈로그로 설정&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;1. &lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;libs.versions.toml 파일에서 Compose 컴파일러에 대한 참조를 제거합니다.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;2. &lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;플러그인 섹션에서 다음과 같은 새 종속성을 추가합니다.&lt;/span&gt;
&lt;div style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;nix&quot; style=&quot;color: #000000; text-align: left;&quot;&gt;&lt;code&gt;[versions]
kotlin = &quot;2.0.0&quot;

[plugins]
org-jetbrains-kotlin-android = { id = &quot;org.jetbrains.kotlin.android&quot;, version.ref = &quot;kotlin&quot; }

// Add this line
compose-compiler = { id = &quot;org.jetbrains.kotlin.plugin.compose&quot;, version.ref = &quot;kotlin&quot; }&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;프로젝트 루트 build.gradle.kts 파일에서 플러그인 섹션에 다음을 추가합니다:&lt;/div&gt;
&lt;pre class=&quot;cs&quot; style=&quot;color: #000000; text-align: left;&quot;&gt;&lt;code&gt;plugins {
&amp;nbsp; &amp;nbsp;// Existing plugins
&amp;nbsp; &amp;nbsp;alias(libs.plugins.compose.compiler) apply false
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;작성 기능을 사용하는 각 모듈에서 플러그인을 적용합니다:&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;stylus&quot; style=&quot;color: #000000; text-align: left;&quot;&gt;&lt;code&gt;plugins {
&amp;nbsp; &amp;nbsp;// Existing plugins
&amp;nbsp; &amp;nbsp;alias(libs.plugins.compose.compiler)
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;이제 기본 설정을 사용하는 경우 앱이 빌드 및 컴파일됩니다. 컴파일 컴파일러에서 사용자 지정 옵션을 구성한 경우 다음 섹션을 참조하세요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;Gradle 버전 카탈로그 없이 설정&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;버전 카탈로그 없이 컴파일러 Gradle 플러그인을 설정하려면 컴파일을 사용하는 모듈과 연결된 build.gradle.kts 파일에 다음 플러그인을 추가하세요:&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;crmsh&quot; style=&quot;color: #000000; text-align: left;&quot;&gt;&lt;code&gt;plugins {
&amp;nbsp; &amp;nbsp; id(&quot;org.jetbrains.kotlin.plugin.compose&quot;) version &quot;2.0.0&quot; // this version matches your Kotlin version
}
&lt;/code&gt;&lt;/pre&gt;
&lt;div style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;컴파일러 작성 그래들 플러그인을 사용한 구성 옵션&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;Gradle 플러그인을 사용하여 Compose 컴파일러를 구성하려면 모듈의 build.gradle.kts 파일 최상위 레벨에 composeCompiler 블록을 추가합니다.&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;nix&quot; style=&quot;color: #000000; text-align: left;&quot;&gt;&lt;code&gt;android { &amp;hellip; }

composeCompiler {
&amp;nbsp; &amp;nbsp; enableStrongSkippingMode = true

&amp;nbsp; &amp;nbsp; reportsDestination = layout.buildDirectory.dir(&quot;compose_compiler&quot;)
&amp;nbsp; &amp;nbsp; stabilityConfigurationFile = rootProject.layout.projectDirectory.file(&quot;stability_config.conf&quot;)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고 : &lt;a href=&quot;https://developer.android.com/develop/ui/compose/compiler&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://developer.android.com/develop/ui/compose/compiler&lt;/a&gt;&lt;/p&gt;</description>
      <category>안드로이드/Compose</category>
      <category>Android</category>
      <category>compose</category>
      <category>안드로이드</category>
      <category>컴포즈</category>
      <author>헬창코딩</author>
      <guid isPermaLink="true">https://healthcoding.tistory.com/67</guid>
      <comments>https://healthcoding.tistory.com/67#entry67comment</comments>
      <pubDate>Thu, 16 May 2024 15:33:01 +0900</pubDate>
    </item>
    <item>
      <title>Compose 공식문서정리(1) - Introduction</title>
      <link>https://healthcoding.tistory.com/66</link>
      <description>&lt;h2 style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Compose를 도입해야 하는 이유&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;Jetpack Compose는 네이티브 UI를 빌드하기 위한 Android의 최신 툴킷입니다. 더 적은 코드, 강력한 도구, 직관적인 Kotlin API로 앱에 생명을 불어넣어 Android에서 UI 개발을 간소화 및 가속화합니다. 안드로이드 UI를 더 빠르고 쉽게 빌드할 수 있습니다. Compose를 개발하는 동안 다양한 파트너와 협력하여 이러한 모든 이점을 직접 경험하고 몇 가지 핵심 사항을 공유했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;less-code&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-text=&quot;Less code&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Less code&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;코드를 적게 작성하면 개발의 모든 단계에 영향을 미칩니다. 작성자는 테스트 및 디버깅할 코드가 줄어들어 당면한 문제에 집중할 수 있고 버그 발생 가능성이 줄어들며, 검토자나 관리자는 읽고, 이해하고, 검토하고, 유지 관리해야 할 코드가 줄어듭니다.&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;작성 기능을 사용하면 Android 보기 시스템을 사용할 때보다 더 적은 코드로 더 많은 작업을 수행할 수 있습니다: 버튼, 목록, 애니메이션 등 무엇을 만들든 이제 작성해야 하는 코드가 줄어듭니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;intuitive&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-text=&quot;Intuitive&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Intuitive&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;Compose는 선언적 API를 사용하므로 사용자는 UI를 설명하기만 하면 나머지는 Compose가 알아서 처리합니다. API는 직관적이어서 쉽게 찾고 사용할 수 있습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;accelerate-development&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-text=&quot;Accelerate development&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Accelerate development&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;작성은 모든 기존 코드와 호환되므로 보기에서 작성 코드를 호출하고 작성에서 보기를 호출할 수 있습니다. Navigation, ViewModel 및 Kotlin 코루틴과 같은 대부분의 일반적인 라이브러리가 Compose와 함께 작동하므로 원하는 시기와 장소에서 도입을 시작할 수 있습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;powerful&quot; style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-text=&quot;Powerful&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Powerful&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;Compose를 사용하면 Android 플랫폼 API에 직접 액세스하고 머티리얼 디자인, 어두운 테마, 애니메이션 등을 기본으로 지원하여 멋진 앱을 만들 수 있습니다 &lt;span style=&quot;background-color: #ffffff; color: #242b34; text-align: start;&quot;&gt;Compose는 선언적인 UI를 넘어 접근성 API, 레이아웃 등 모든 종류의 문제를 해결했습니다. 만들고 싶은 것과 실제로 만드는 것 사이의 단계가 줄어듭니다&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>안드로이드/Compose</category>
      <category>Android</category>
      <category>compose</category>
      <category>안드로이드</category>
      <category>컴포즈</category>
      <author>헬창코딩</author>
      <guid isPermaLink="true">https://healthcoding.tistory.com/66</guid>
      <comments>https://healthcoding.tistory.com/66#entry66comment</comments>
      <pubDate>Wed, 15 May 2024 15:19:35 +0900</pubDate>
    </item>
    <item>
      <title>[이펙티브 코틀린] 단위 테스트를 만들어라</title>
      <link>https://healthcoding.tistory.com/65</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드는 자바와 코틀린 2가지 언어로 개발을 할 수 있지만 요즘 자바를 사용해서 개발하는 경우는 찾아보기 힘듬니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저또한 코틀린을 사용합니다 하지만 사용하면서 잘 몰랐던 부분도 있고 한번도 써보지않는 편리고 좋은 기능들이 많이 존재합니다 그래서 이번에 복습할겸 이펙티브 코틀린의 내용으로 정리를 하려고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;안정성 - 단위테스트를 만들어라&amp;nbsp;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 안전하게 만드는 다양한 방법이 있지만 가장 궁극적인 방법은 다양한 종류를 &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;테스트&lt;/span&gt; &lt;/b&gt;하는 것이다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 비즈니스적인 관점의 테스트는 개발자 관점에서 애플리케이션 내부적으로 올바르게 작동하는지 확인하는 것이 아니라, 사용자의 관점에서 애플리케이션 외부적으로 제대로 동작하는지 확인하는 것이 목표이다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇기 때문에 개발자에게 유용하지만 충분하지는 않다. 이러한 문제를 해결하려면 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;단위 테스트(Unit test)&lt;/b&gt;&lt;/span&gt; 가 필요하다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;단위테스트로 확인하는 것&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;일반적인 유스케이스 : 요소가 사용될 것이라고 예상되는 일반적인 방법&lt;/li&gt;
&lt;li&gt;일반적인 오류 케이스와 잠재적인 문제 : 제대로 동작하지 않을 거라고 예상되는 일반적인 부분, 과거에 발생했던 부분&lt;/li&gt;
&lt;li&gt;에지케이스와 잘못된 아규먼트&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;단위테스트의 장점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;테스트가 잘된 요소는 신뢰할 수 있다 그렇기에 해당 요소를 활용한 작업에 자신감이 생긴다&lt;/li&gt;
&lt;li&gt;테스트가 잘 만들어져 있다면 리펙터링하는 것이 두렵지 않음&lt;/li&gt;
&lt;li&gt;수동으로 테스트하는 것 보다 단위테스트로 하는 것이 훨씬 빠르다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;단위테스트의 단점&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;단위테스트를 작성하는 데 시간이 많이 걸린다(장기적으로 봤을때는 시간을 줄여줌)&lt;/li&gt;
&lt;li&gt;테스트를 활용할 수 있게 코드를 조정해야한다(이러한 변경이 어렵지만 변경을 통한 훌륭한 아키텍처 정립가능)&lt;/li&gt;
&lt;li&gt;좋은 단위테스트를 만드는 것은 다양한 경험이 필요하고 어렵다 잘못만들어진 테스트는 득보다 실이 크다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;개발자로써 단위테스트를 할 줄 알아야 하는 부분&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;복잡한 부분&lt;/li&gt;
&lt;li&gt;계속해서 수정이 일어나고 리펙터링이 일어날 수 있는 부분&amp;nbsp;&lt;/li&gt;
&lt;li&gt;비즈니스 로직 부분&lt;/li&gt;
&lt;li&gt;공용 API 부분&lt;/li&gt;
&lt;li&gt;문제가 자주 발생하는 부분&lt;/li&gt;
&lt;li&gt;수정해야 하는 프로덕션 버그&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고 : 이펙티브 코틀린&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;a href=&quot;https://www.yes24.com/Product/Goods/106225986?pid=123487&amp;amp;cosemkid=go16425707805513414&amp;amp;gclid=Cj0KCQjwkqSlBhDaARIsAFJANkhCQTUD9TDNQIc0Vtl8O9OL8NFCy7dvHa-SLpewyWlUTlfoadfvjD0aAirIEALw_wcB&quot;&gt;https://www.yes24.com/Product/Goods/106225986?pid=123487&amp;amp;cosemkid=go16425707805513414&amp;amp;gclid=Cj0KCQjwkqSlBhDaARIsAFJANkhCQTUD9TDNQIc0Vtl8O9OL8NFCy7dvHa-SLpewyWlUTlfoadfvjD0aAirIEALw_wcB&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>안드로이드/Kotlin</category>
      <category>Kotlin</category>
      <category>test</category>
      <category>UnitTest</category>
      <category>단위테스트</category>
      <category>테스트의 장점</category>
      <author>헬창코딩</author>
      <guid isPermaLink="true">https://healthcoding.tistory.com/65</guid>
      <comments>https://healthcoding.tistory.com/65#entry65comment</comments>
      <pubDate>Thu, 20 Jul 2023 00:22:03 +0900</pubDate>
    </item>
    <item>
      <title>[이펙티브 코틀린] 코틀린의 안정성 - use를 사용하여 리소스를 닫아라</title>
      <link>https://healthcoding.tistory.com/64</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드는 자바와 코틀린 2가지 언어로 개발을 할 수 있지만 요즘 자바를 사용해서 개발하는 경우는 찾아보기 힘듬니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저또한 코틀린을 사용합니다 하지만 사용하면서 잘 몰랐던 부분도 있고 한번도 써보지않는 편리고 좋은 기능들이 많이 존재합니다 그래서 이번에 복습할겸 이펙티브 코틀린의 내용으로 정리를 하려고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;안정성 -&amp;nbsp; use 를 사용하여 리소스를 닫아라&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더 이상 필요하지 않을 때 close 메서드를 사용해서 명시적으로 닫아야하는 리소스가 있다 예를 들어&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- InputStream, OutputStream&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- java.sql.Connection&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- soket, Scanner 등등&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 리소스들은 AutoCloseable 을 상속받는 Closeable 인터페이스를 구현하고 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 모든 리소스들은 최종적으로 리소스에 대한 래퍼런스가 없어질 때, 가비지 컬렉터가 처리하지만 굉장히 느리며 그 동안 리소스를 유지하는데 많은 비용이 발생&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 필요하지 않을때 명시적으로 close 메서드를 호출해주는 것이 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;use 를 사용하면 Closeable/AutoCloseable 을 구현한 객체를 쉽고 안전하게 처리 할 수 있다 또한 파일을 처리할 때는 파일을 한 줄씩 읽어 드리는 useLines 를 사용하는 것이 좋다&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고 : 이펙티브 코틀린&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;a href=&quot;https://www.yes24.com/Product/Goods/106225986?pid=123487&amp;amp;cosemkid=go16425707805513414&amp;amp;gclid=Cj0KCQjwkqSlBhDaARIsAFJANkhCQTUD9TDNQIc0Vtl8O9OL8NFCy7dvHa-SLpewyWlUTlfoadfvjD0aAirIEALw_wcB&quot;&gt;https://www.yes24.com/Product/Goods/106225986?pid=123487&amp;amp;cosemkid=go16425707805513414&amp;amp;gclid=Cj0KCQjwkqSlBhDaARIsAFJANkhCQTUD9TDNQIc0Vtl8O9OL8NFCy7dvHa-SLpewyWlUTlfoadfvjD0aAirIEALw_wcB&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>안드로이드/Kotlin</category>
      <category>Kotlin</category>
      <category>Use</category>
      <author>헬창코딩</author>
      <guid isPermaLink="true">https://healthcoding.tistory.com/64</guid>
      <comments>https://healthcoding.tistory.com/64#entry64comment</comments>
      <pubDate>Wed, 19 Jul 2023 22:00:43 +0900</pubDate>
    </item>
    <item>
      <title>[이펙티브 코틀린] 코틀린의 안정성 - 적절하게 null 을 처리하라</title>
      <link>https://healthcoding.tistory.com/63</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드는 자바와 코틀린 2가지 언어로 개발을 할 수 있지만 요즘 자바를 사용해서 개발하는 경우는 찾아보기 힘듬니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저또한 코틀린을 사용합니다 하지만 사용하면서 잘 몰랐던 부분도 있고 한번도 써보지않는 편리고 좋은 기능들이 많이 존재합니다 그래서 이번에 복습할겸 이펙티브 코틀린의 내용으로 정리를 하려고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;안정성 -&amp;nbsp; 적절하게&amp;nbsp;null&amp;nbsp;을&amp;nbsp;처리하라&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 nullable 타입은 세 가지 방법으로 처리한다&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;?., 스마트 캐스팅, Elvis 연산자 등을 활용해서 안전하게 처리한다.&lt;/li&gt;
&lt;li&gt;오류를 throw 한다&lt;/li&gt;
&lt;li&gt;함수 또는 프로퍼티를 리펙터링해서 nullable 타입이 나오지 않게 바꾼다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; &lt;/b&gt;null 을 처리할때 가장 좋은 방법은 스마트캐스팅이나 elvis 연산자를 사용해서 처리하는게 가장 좋지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;require, check 등 공격적프로그래밍 방식으로 개발자에게 처리를 맡겨야 할때도 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;공격적프로그래밍, 방어적프로그램&lt;/b&gt;이란 : &lt;a href=&quot;https://healthcoding.tistory.com/62&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://healthcoding.tistory.com/62&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 가끔은 not - null assertion (!!) 을 이용해서 처리를 하기도 하는데 이것을 지양하자!&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;미래에 코드는 어떻게 변화할지 아무도 알 수 없다. !!연산자를 사용하거나 명시적으로 예외를 발생시키는 형태로 설계하면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;미래의 어느시점에서 해당 코드가 오류를 발생 시킬 수 있다는 것을 염두해야 한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;!! 를 피하자&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2. 의미 없는 nullability 를 피하자&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;nullability 는 어떻게는 적절하게 처리해야 하므로, 추가비용이 발생, 필요한 경우가 아니면 nullability 자체를 피하자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;nullability 를 피할때 사용할 수 있는 방법&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;클래스에서 nullability 에 따라 여러 함수를 만들어서 제공할 수 있음(ex. list&amp;lt;T&amp;gt; 의 get, getNull 함수 등)&lt;/li&gt;
&lt;li&gt;어떤 값이 클래스 생성 이후에 확실하게 설정된다는 보장이 있다면 lateinit 프로퍼티와 notnull 델리게이트를 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. lateinit 프로퍼티 와 nonNull 델리케이트를 사용하자&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;lateinit 의 장점&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;!! 연산자로 언팩하지 않아도 됨&lt;/li&gt;
&lt;li&gt;이후에 어떤 의미를 나타내기 위해서 null을 사용하고 싶을 때 nullable로 만들 수 있음&lt;/li&gt;
&lt;li&gt;프로퍼티가 초기화된 이후에는 초기화되지 않은 상태로 돌아갈 수 없음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고 : 이펙티브 코틀린&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;a href=&quot;https://www.yes24.com/Product/Goods/106225986?pid=123487&amp;amp;cosemkid=go16425707805513414&amp;amp;gclid=Cj0KCQjwkqSlBhDaARIsAFJANkhCQTUD9TDNQIc0Vtl8O9OL8NFCy7dvHa-SLpewyWlUTlfoadfvjD0aAirIEALw_wcB&quot;&gt;https://www.yes24.com/Product/Goods/106225986?pid=123487&amp;amp;cosemkid=go16425707805513414&amp;amp;gclid=Cj0KCQjwkqSlBhDaARIsAFJANkhCQTUD9TDNQIc0Vtl8O9OL8NFCy7dvHa-SLpewyWlUTlfoadfvjD0aAirIEALw_wcB&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>안드로이드/Kotlin</category>
      <category>Kotlin</category>
      <category>lateinit</category>
      <category>NULL</category>
      <category>null처리</category>
      <author>헬창코딩</author>
      <guid isPermaLink="true">https://healthcoding.tistory.com/63</guid>
      <comments>https://healthcoding.tistory.com/63#entry63comment</comments>
      <pubDate>Tue, 18 Jul 2023 23:11:32 +0900</pubDate>
    </item>
    <item>
      <title>[이펙티브 코틀린] 방어적 프로그래밍 vs 공격적 프로그래밍</title>
      <link>https://healthcoding.tistory.com/62</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;방어적 프로그래밍&amp;nbsp;&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모든 가능성을 올바른 방식으로 처리하는 것(예를 들어 null일때는 출력하지 않기 등)&lt;/li&gt;
&lt;li&gt;방어적 프로그래밍은 코드가 프로덕션 환경으로 들어갔을때 발생할 수 있는 수많은 것들로부터 프로그램을 방어해서 안정성을 높히는 방법을 나타내는 굉장히 포괄적인 용어&lt;/li&gt;
&lt;li&gt;상황을 처리할 수 있는 올바른 방법이 있을때 굉장히 좋다&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;공격적&amp;nbsp; 프로그래밍&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모든 상황을 안전하게 처리하는 것은 불가능하기 때문에 등장&lt;/li&gt;
&lt;li&gt;예상하지 못한 상황이 발생했을때, 이러한 문제를 개발자에게 알려서 수정하게 만드는 것&lt;/li&gt;
&lt;li&gt;require, check, assert 가 공격적 프로그래밍을 하기 위한 도구&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;--&amp;gt; 둘은 충돌되는 것처럼 보이지만, 둘다 안전을 위해 모두 필요하기 때문에 적절하게 사용해야한다&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고 : 이펙티브 코틀린&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;a href=&quot;https://www.yes24.com/Product/Goods/106225986?pid=123487&amp;amp;cosemkid=go16425707805513414&amp;amp;gclid=Cj0KCQjwkqSlBhDaARIsAFJANkhCQTUD9TDNQIc0Vtl8O9OL8NFCy7dvHa-SLpewyWlUTlfoadfvjD0aAirIEALw_wcB&quot;&gt;https://www.yes24.com/Product/Goods/106225986?pid=123487&amp;amp;cosemkid=go16425707805513414&amp;amp;gclid=Cj0KCQjwkqSlBhDaARIsAFJANkhCQTUD9TDNQIc0Vtl8O9OL8NFCy7dvHa-SLpewyWlUTlfoadfvjD0aAirIEALw_wcB&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>안드로이드/Kotlin</category>
      <category>Kotlin</category>
      <category>공격적 프로그래밍</category>
      <category>방어적 프로그래밍</category>
      <category>코틀린</category>
      <author>헬창코딩</author>
      <guid isPermaLink="true">https://healthcoding.tistory.com/62</guid>
      <comments>https://healthcoding.tistory.com/62#entry62comment</comments>
      <pubDate>Mon, 17 Jul 2023 20:13:40 +0900</pubDate>
    </item>
    <item>
      <title>[이펙티브 코틀린] 결과 부족이 발생할 경우 null과 failure를 사용하라</title>
      <link>https://healthcoding.tistory.com/61</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드는 자바와 코틀린 2가지 언어로 개발을 할 수 있지만 요즘 자바를 사용해서 개발하는 경우는 찾아보기 힘듬니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저또한 코틀린을 사용합니다 하지만 사용하면서 잘 몰랐던 부분도 있고 한번도 써보지않는 편리고 좋은 기능들이 많이 존재합니다 그래서 이번에 복습할겸 이펙티브 코틀린의 내용으로 정리를 하려고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;안정성 - 결과&amp;nbsp;부족이&amp;nbsp;발생할&amp;nbsp;경우&amp;nbsp;null과&amp;nbsp;failure를&amp;nbsp;사용하라&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수가 원하지않는 경과랄 만들어내는 경우에 이를 처리하는 2가지 매커니즘&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. null 또는 실패를 나타내는 sealdclass(failure 등) 리턴&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;2. 예외를 throw 한다 -&amp;gt; 지양해야하는 경우&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;예외는 정보를 전달하는 방법으로 사용해서는 안된다&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt; 많은 개발자가 예외가 전파되는 과정을 제대로 추적하지 못한다&lt;/li&gt;
&lt;li&gt;코틀린의 모든 예외는 &lt;b&gt;unchecked&lt;/b&gt; 예외 이다, 따라서 사용자가 예외를 처리하지 않을 수 있다&lt;/li&gt;
&lt;li&gt;예외는 예외적인 상황을 처리하기 위해서 만들어졌으므로 명시적인 테스트만큼 빠르게 동작하지 않는다&lt;/li&gt;
&lt;li&gt;try - catch 블록 내부에 코드를 배치하면, 컴파일러가 할 수 있는 최적화가 제한 된다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Failure 같은 seald 클래스를 사용하면 예외를 다루기 쉽고 놓치기 어렵다. &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;null 을 처리해야 한다면, 사용자는 안전호출 또는 elvis 연산자 같은 다양한 널 안정성 기능을 활용한다&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1689407844312&quot; class=&quot;ebnf&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;val age = useText.readObjectOrNull&amp;lt;Person&amp;gt;()?.age ?: -1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;result 와 같은 공용체를 리턴하기로 했다면, when 표현식을 사용해서 이를 처리하면 좋다&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1689407973564&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;val person = useText.readObjectOfNull&amp;lt;Person&amp;gt;()
val age = when(person){
    is Success -&amp;gt; person.age
    is Failure -&amp;gt; -1
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;checked&amp;nbsp; 예외 : 사용자가 반드시 처리하게 강제되는 예외를&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;&lt;b&gt;unchecked&lt;/b&gt;&amp;nbsp; 예외 : 처리하지 않아도 실행에 문제가 없는 예외&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고 : 이펙티브 코틀린&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;a href=&quot;https://www.yes24.com/Product/Goods/106225986?pid=123487&amp;amp;cosemkid=go16425707805513414&amp;amp;gclid=Cj0KCQjwkqSlBhDaARIsAFJANkhCQTUD9TDNQIc0Vtl8O9OL8NFCy7dvHa-SLpewyWlUTlfoadfvjD0aAirIEALw_wcB&quot;&gt;https://www.yes24.com/Product/Goods/106225986?pid=123487&amp;amp;cosemkid=go16425707805513414&amp;amp;gclid=Cj0KCQjwkqSlBhDaARIsAFJANkhCQTUD9TDNQIc0Vtl8O9OL8NFCy7dvHa-SLpewyWlUTlfoadfvjD0aAirIEALw_wcB&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>안드로이드/Kotlin</category>
      <category>Failure</category>
      <category>Kotlin</category>
      <category>return</category>
      <category>에러</category>
      <category>에러처리</category>
      <author>헬창코딩</author>
      <guid isPermaLink="true">https://healthcoding.tistory.com/61</guid>
      <comments>https://healthcoding.tistory.com/61#entry61comment</comments>
      <pubDate>Sun, 16 Jul 2023 18:01:14 +0900</pubDate>
    </item>
    <item>
      <title>[이펙티브 코틀린] 코틀린의 안정성 -  사용자 정의 오류보다는 표준 오류를 사용하라</title>
      <link>https://healthcoding.tistory.com/60</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드는 자바와 코틀린 2가지 언어로 개발을 할 수 있지만 요즘 자바를 사용해서 개발하는 경우는 찾아보기 힘듬니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저또한 코틀린을 사용합니다 하지만 사용하면서 잘 몰랐던 부분도 있고 한번도 써보지않는 편리고 좋은 기능들이 많이 존재합니다 그래서 이번에 복습할겸 이펙티브 코틀린의 내용으로 정리를 하려고 합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;안정성 - 사용자&amp;nbsp;정의&amp;nbsp;오류보다는&amp;nbsp;표준&amp;nbsp;오류를&amp;nbsp;사용하라&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;표준라이브러리의 오류는 대부분의 개발자들이 알고 있으므로 이를 재사용하는 것이 좋다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘 만들어진 규약을 가진 널리 알려진 요소를 재사용하면, 다른 사람들이 API를 더 쉽게 배우고 이해할 수 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;일반적으로 사용되는 예외&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;IlegalArgumentException, IllegalStateException&lt;/b&gt; : require, check를 이용해 throw를 던질 수 있는 예외&lt;/li&gt;
&lt;li&gt;&lt;b&gt;IndexOutOfBoundsException&lt;/b&gt; : 인덱스 파라미터 값이 범위를 벗어났다는 것, 일반적으로 컬렉션이나 배열과 함께 사용&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;ConcurrentModificationException&lt;/b&gt; : 동시 수정을 금지했는데, 발생해 버렸을때&lt;/li&gt;
&lt;li&gt;&lt;b&gt;UnsupportedOperationException&lt;/b&gt; : 사용자가 사용하려면 메서드가 현재 객체에는 사용할 수 없음을 나타냄&lt;/li&gt;
&lt;li&gt;&lt;b&gt;NoSuchElementException&lt;/b&gt; : 사용자가 사용하려고 했던 요소가 존재하지 않음을 나타냄&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고 : 이펙티브 코틀린&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.yes24.com/Product/Goods/106225986?pid=123487&amp;amp;cosemkid=go16425707805513414&amp;amp;gclid=Cj0KCQjwkqSlBhDaARIsAFJANkhCQTUD9TDNQIc0Vtl8O9OL8NFCy7dvHa-SLpewyWlUTlfoadfvjD0aAirIEALw_wcB&quot;&gt;https://www.yes24.com/Product/Goods/106225986?pid=123487&amp;amp;cosemkid=go16425707805513414&amp;amp;gclid=Cj0KCQjwkqSlBhDaARIsAFJANkhCQTUD9TDNQIc0Vtl8O9OL8NFCy7dvHa-SLpewyWlUTlfoadfvjD0aAirIEALw_wcB&lt;/a&gt;&lt;/p&gt;</description>
      <category>안드로이드/Kotlin</category>
      <category>Kotlin</category>
      <category>제한함수</category>
      <category>코틀린</category>
      <author>헬창코딩</author>
      <guid isPermaLink="true">https://healthcoding.tistory.com/60</guid>
      <comments>https://healthcoding.tistory.com/60#entry60comment</comments>
      <pubDate>Sat, 15 Jul 2023 16:43:46 +0900</pubDate>
    </item>
  </channel>
</rss>