[Jetpack Compose] 1. Compose 기본 사항(2) #Scaffold #Slot API

0

Jetpack Compose

목록 보기
2/11
post-thumbnail
post-custom-banner

[Jetpack Compose] 1. Compose 기본 사항(2)

📌참고자료:

Jetpack Compose basics

📌참고자료:

padding(bottom = extraPadding.coerceAtLeast(0.dp))
  • add @Composable annotation to kotlin function in order to call composable functions inside
  • MainActivity의 onCreate 내부 setContent를 사용해 레이아웃 정의
    -> XML 파일 대신, composable function 호출
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            BasicsCodelabTheme {
                Surface(
                  modifier = Modifier.fillMaxSize(),
                  color = MaterialTheme.colorScheme.background
                ) {
                    Greeting("Android")
                }
            }
        }
    }
}
  • @Preview 애노테이션을 이용하여 미리보기 가능
@Preview(showBackground = true, widthDp = 320, heightDp = 320)
@Preview(
    showBackground = true, widthDp = 320, heightDp = 320,
    uiMode = UI_MODE_NIGHT_YES,
    name = "GreetingPreviewDark"
)
fun GreetingPreview() {
    BasicsCodelabTheme {
        Greeting(name = "Android")
    }
}
  • LazyColumn, LazyRow
    • a performant lazy list
    • renders only the visible items on screen
    • doesn't recycle its children like RecyclerView
      -> emits new Composables, relatively cheaper than initiating Android Views
    • import androidx.compose.foundation.lazy.items
  • 리스트 항목의 펼치기/접기 버튼 클릭 시, 항목 하단 padding 값 변경 애니메이션 적용하기
@Composable
fun Greeting(text: String, modifier: Modifier = Modifier) {
    var expanded: Boolean by rememberSaveable { mutableStateOf(false) }
    
    // bottom padding with no animation
    // val bottomPadding = if (expanded) 50.dp else 2.dp
    
    // bottom padding with animation
    // val bottomPadding by animateDpAsState(if (expanded) 50.dp else 2.dp)
    
    // bottom padding with spring-base animation
    val bottomPadding by animateDpAsState(
        targetValue = if (expanded) 50.dp else 2.dp,
        animationSpec = spring(
            dampingRatio = Spring.DampingRatioMediumBouncy,
            stiffness = Spring.StiffnessLow
        )
    )

    Surface(
        modifier = modifier,
        color = MaterialTheme.colorScheme.secondary,
    ) {
        Row(
            modifier = Modifier
            		.fillMaxWidth()
                    .padding(bottom = bottomPadding.coerceAtLeast(0.dp))
        ) {
            Text(
                modifier = Modifier
                    .weight(1.8F, true)
                    .padding(all = 20.dp),
                text = text
            )
            ElevatedButton(
                modifier = Modifier
                    .weight(1.0F, false)
                    .width(120.dp)
                    .padding(top = 7.dp, end = 4.dp),
                onClick = {expanded = !expanded}
            ) {
                Text(text = if (expanded) "접기" else "펼치기")
            }
        }
    }
}

Compose UI Tool Kit

Scaffold

  • a fundamental material design component
  • a basic layout for arranging material components in common patterns

Surface

  • a central metaphor in Material Design which content sits on
  • color, shape, border, shadowElavation, tonalElavation

Layouts

  • Row composable function: horizontally arrange items
  • Column composable function: vertically arrange items
  • Box composable function: put/stack items on top of another

Modifiers

  • decorate or augment a composable
  • every composable function accepts a modifier as a parameter

Basic layouts in Compose

📌참고자료

  • 행의 개수 2개로 고정가로 방향 스크롤 그리드 구현
    • 항목 사이 여백 설정을 위해 horizontalArrangementverticalArrangement 속성에 Arrangement.spacedBy 사용
    • 스크롤 맨 앞&뒤 여백 설정을 위해 contentPadding 속성 사용
@Composable
fun FavoriteCollectionsGrid(
   modifier: Modifier = Modifier
) {
   LazyHorizontalGrid(
       rows = GridCells.Fixed(2),
       contentPadding = PaddingValues(horizontal = 16.dp), 
       horizontalArrangement = Arrangement.spacedBy(16.dp),
       verticalArrangement = Arrangement.spacedBy(16.dp),
       modifier = modifier.height(168.dp)
   ) {
       items(favoriteCollectionsData) { item ->
           FavoriteCollectionCard(item.drawable, item.text, Modifier.height(80.dp))
       }
   }
}
  • Slot-based layout
    • composable을 매개변수로 받을 때 표현하는 방법: @Composable () -> Unit
@Composable
fun HomeSection(
   @StringRes title: Int,
   modifier: Modifier = Modifier,
   content: @Composable () -> Unit
) {
   Column(modifier) {
       Text(stringResource(title))
       content()
   }
}
  • 화면 위아래 스크롤 구현
    • modifier.verticalScroll(rememberScrollState())
    • 화면 위아래 여백 설정을 위해 높이를 가진 Spacer composable 사용
@Composable
fun HomeScreen(modifier: Modifier = Modifier) {
   Column(
       modifier
           .verticalScroll(rememberScrollState())
   ) {
       Spacer(Modifier.height(16.dp))
       SearchBar(Modifier.padding(horizontal = 16.dp))
       HomeSection(title = R.string.align_your_body) {
           AlignYourBodyRow()
       }
       HomeSection(title = R.string.favorite_collections) {
           FavoriteCollectionsGrid()
       }
       Spacer(Modifier.height(16.dp))
   }
}
  • Bottom Navigation 레이아웃 구현 (네비게이션 아이템 클릭 구현 X)
@Composable
private fun SootheBottomNavigation(modifier: Modifier = Modifier) {
   NavigationBar(
       containerColor = MaterialTheme.colorScheme.surfaceVariant,
       modifier = modifier
   ) {
       NavigationBarItem(
           icon = {
               Icon(
                   imageVector = Icons.Default.Spa,
                   contentDescription = null
               )
           },
           label = {
               Text(stringResource(R.string.bottom_navigation_home))
           },
           selected = true,
           onClick = {}
       )
       NavigationBarItem(
           icon = {
               Icon(
                   imageVector = Icons.Default.AccountCircle,
                   contentDescription = null
               )
           },
           label = {
               Text(stringResource(R.string.bottom_navigation_profile))
           },
           selected = false,
           onClick = {}
       )
   }
}
  • Scaffold로 전체 화면 레이아웃 구현
import androidx.compose.material3.Scaffold

@Composable
fun MySootheAppPortrait() {
   MySootheTheme {
       Scaffold(
           bottomBar = { SootheBottomNavigation() }
       ) { padding ->
           HomeScreen(Modifier.padding(padding))
       }
   }
}
profile
Be able to be vulnerable, in search of truth
post-custom-banner

0개의 댓글