Compose components 1

박채빈·2024년 1월 24일
0

AndroidStudy

목록 보기
2/19
post-thumbnail

Text

Default

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

Color

@Composable
fun Greeting(name: String) {
  Text(color = Color.Red, text = "Hello $name")
}

Color2

@Composable
fun Greeting(name: String) {
  Text(color = Color(0xffff9944), text = "Hello $name")
}

Font size

@Composable
fun Greeting(name: String) {
  Text(color = Color(0xffff9944), text = "Hello $name", fontSize = 30.sp)
}

Font weight

@Composable
fun Greeting(name: String) {
  Text(color = Color(0xffff9944), text = "Hello $name", fontSize = 30.sp, fontWeight = FontWeight.Bold)
}

Font family

@Composable
fun Greeting(name: String) {
  Text(
    color = Color(0xffff9944),
    text = "Hello $name",
    fontSize = 30.sp,
    fontWeight = FontWeight.Bold,
    fontFamily = FontFamily.Cursive
  )
}

Letter spacing

@Composable
fun Greeting(name: String) {
  Text(
    color = Color(0xffff9944),
    text = "Hello $name",
    fontSize = 30.sp,
    fontWeight = FontWeight.Bold,
    fontFamily = FontFamily.Cursive,
    letterSpacing = 2.sp
  )
}

Max lines

@Composable
fun Greeting(name: String) {
  Text(
    color = Color(0xffff9944),
    text = "Hello $name\nHello $name\nHello $name",
    fontSize = 30.sp,
    fontWeight = FontWeight.Bold,
    fontFamily = FontFamily.Cursive,
    letterSpacing = 2.sp,
    maxLines = 2
  )
}

Text decoration

@Composable
fun Greeting(name: String) {
  Text(
    color = Color(0xffff9944),
    text = "Hello $name\nHello $name\nHello $name",
    fontSize = 30.sp,
    fontWeight = FontWeight.Bold,
    fontFamily = FontFamily.Cursive,
    letterSpacing = 2.sp,
    maxLines = 2,
    textDecoration = TextDecoration.Underline
  )
}

Text align, modifier

@Composable
fun Greeting(name: String) {
  Text(
    modifier = Modifier.width(300.dp),
    color = Color(0xffff9944),
    text = "Hello $name\nHello $name\nHello $name",
    fontSize = 30.sp,
    fontWeight = FontWeight.Bold,
    fontFamily = FontFamily.Cursive,
    letterSpacing = 2.sp,
    maxLines = 2,
    textDecoration = TextDecoration.Underline,
    textAlign = TextAlign.Center
  )
}

Button

Default

@Composable
fun ButtonExample(onButtonClicked: () -> Unit) {
  Button(onClick = onButtonClicked) {
    Text(text = "Send")
  }
}

Click event toast

class MainActivity : ComponentActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
      ComposePracticeTheme {
        ButtonExample {
          Toast.makeText(this, "show toast", Toast.LENGTH_SHORT).show() // 여기에서 버튼 이벤트 정의
        }
      }
    }
  }
}

@Composable
fun ButtonExample(onButtonClicked: () -> Unit) {
  Button(onClick = {}) {
    Text(text = "Send")
  }
}

Icon 추가

@Composable
fun ButtonExample(onButtonClicked: () -> Unit) {
  Button(onClick = onButtonClicked) {
    Icon(
      imageVector = Icons.Filled.Send,    // 이미지
      contentDescription = "something send"  // 벡터 이미지 설명
    )
    Text(text = "Send")
  }
}

Icon, Text 사이에 Spacer 추가

@Composable
fun ButtonExample(onButtonClicked: () -> Unit) {
  Button(onClick = onButtonClicked) {
    Icon(
      imageVector = Icons.Filled.Send,    // 이미지
      contentDescription = "something send"  // 벡터 이미지 설명
    )
    Spacer(modifier = Modifier.size(ButtonDefaults.IconSpacing))
//    Spacer(modifier = Modifier.size(30.dp))
    Text(text = "Send")
  }
}

Enabled 속성

@Composable
fun ButtonExample(onButtonClicked: () -> Unit) {
  Button(
    onClick = onButtonClicked,
    enabled = false
  ) {
    Icon(
      imageVector = Icons.Filled.Send,    // 이미지
      contentDescription = "something send"  // 벡터 이미지 설명
    )
    Spacer(modifier = Modifier.size(ButtonDefaults.IconSpacing))
//    Spacer(modifier = Modifier.size(30.dp))
    Text(text = "Send")
  }
}

Border stroke

@Composable
fun ButtonExample(onButtonClicked: () -> Unit) {
  Button(
    onClick = onButtonClicked,
    enabled = true,
    border = BorderStroke(10.dp, Color.Magenta)
  ) {
    Icon(
      imageVector = Icons.Filled.Send,    // 이미지
      contentDescription = "something send"  // 벡터 이미지 설명
    )
    Spacer(modifier = Modifier.size(ButtonDefaults.IconSpacing))
//    Spacer(modifier = Modifier.size(30.dp))
    Text(text = "Send")
  }
}

CircleShape

@Composable
fun ButtonExample(onButtonClicked: () -> Unit) {
  Button(
    onClick = onButtonClicked,
    enabled = true,
    border = BorderStroke(10.dp, Color.Magenta),
    // shape = RoundedCornerShape(10.dp)
    shape = CircleShape
  ) {
    Icon(
      imageVector = Icons.Filled.Send,    // 이미지
      contentDescription = "something send"  // 벡터 이미지 설명
    )
    Spacer(modifier = Modifier.size(ButtonDefaults.IconSpacing))
//    Spacer(modifier = Modifier.size(30.dp))
    Text(text = "Send")
  }
}

Content Padding

@Composable
fun ButtonExample(onButtonClicked: () -> Unit) {
  Button(
    onClick = onButtonClicked,
    enabled = true,
    border = BorderStroke(10.dp, Color.Magenta),
    // shape = RoundedCornerShape(10.dp)
    shape = CircleShape,
    contentPadding = PaddingValues(20.dp)
  ) {
    Icon(
      imageVector = Icons.Filled.Send,    // 이미지
      contentDescription = "something send"  // 벡터 이미지 설명
    )
    Spacer(modifier = Modifier.size(ButtonDefaults.IconSpacing))
//    Spacer(modifier = Modifier.size(30.dp))
    Text(text = "Send")
  }
}

Modifier

Default

@Composable
fun ModifierEx() {
  Button(onClick = {}) {
    Icon(
      imageVector = Icons.Filled.Search,
      contentDescription = "something search"
    )
    Spacer(modifier = Modifier.size(ButtonDefaults.IconSpacing))
    Text(text = "Search")
  }
}

Modifier fillMaxSize

@Composable
fun ModifierEx() {
  Button(
    onClick = {},
    modifier = Modifier.fillMaxSize()
  ) {
    Icon(
      imageVector = Icons.Filled.Search,
      contentDescription = "something search"
    )
    Spacer(modifier = Modifier.size(ButtonDefaults.IconSpacing))
    Text(text = "Search")
  }
}

Modifier height

@Composable
fun ModifierEx() {
  Button(
    onClick = {},
    modifier = Modifier.height(100.dp)
  ) {
    Icon(
      imageVector = Icons.Filled.Search,
      contentDescription = "something search"
    )
    Spacer(modifier = Modifier.size(ButtonDefaults.IconSpacing))
    Text(text = "Search")
  }
}

Modifier height with width

@Composable
fun ModifierEx() {
  Button(
    onClick = {},
    modifier = Modifier
      .height(100.dp)
      .width(200.dp)
  ) {
    Icon(
      imageVector = Icons.Filled.Search,
      contentDescription = "something search"
    )
    Spacer(modifier = Modifier.size(ButtonDefaults.IconSpacing))
    Text(text = "Search")
  }
}

Modifier size

@Composable
fun ModifierEx() {
  Button(
    onClick = {},
    modifier = Modifier.size(200.dp, 100.dp) // size(width, height)
  ) {
    Icon(
      imageVector = Icons.Filled.Search,
      contentDescription = "something search"
    )
    Spacer(modifier = Modifier.size(ButtonDefaults.IconSpacing))
    Text(text = "Search")
  }
}

Background Color

@Composable
fun ModifierEx() {
  Button(
    onClick = {},
    modifier = Modifier
                .size(200.dp, 100.dp)
                .background(Color.Red) // Failed case: Button에서는 background 동작안함
  ) {
    Icon(
      imageVector = Icons.Filled.Search,
      contentDescription = "something search"
    )
    Spacer(modifier = Modifier.size(ButtonDefaults.IconSpacing))
    Text(text = "Search")
  }
}

Button Color

@Composable
fun ModifierEx() {
  Button(
    colors = ButtonDefaults.buttonColors(
      Color.Magenta,  // Button 자체 색상
      contentColor = Color.Cyan  // Button 내부 content 색상
    ),
    onClick = {},
    modifier = Modifier.padding(100.dp)
  ) {
    Icon(
      imageVector = Icons.Filled.Search,
      contentDescription = "something search"
    )
    Spacer(modifier = Modifier.size(ButtonDefaults.IconSpacing))
    Text(text = "Search")
  }
}

Modifier padding

@Composable
fun ModifierEx() {
  Button(
    colors = ButtonDefaults.buttonColors(
      Color.Magenta,
      contentColor = Color.Cyan
    ),
    onClick = {},
    modifier = Modifier.padding(100.dp)
  ) {
    Icon(
      imageVector = Icons.Filled.Search,
      contentDescription = "something search"
    )
    Spacer(modifier = Modifier.size(ButtonDefaults.IconSpacing))
    Text(text = "Search")
  }
}

Click 범위 설정

@Composable
fun ModifierEx() {
  Button(
    colors = ButtonDefaults.buttonColors(
      Color.Magenta,
      contentColor = Color.Cyan
    ),
    onClick = {},
    modifier = Modifier.padding(100.dp),
    enabled = false // click 불가
  ) {
    Icon(
      imageVector = Icons.Filled.Search,
      contentDescription = "something search"
    )
    Spacer(modifier = Modifier.size(ButtonDefaults.IconSpacing))
    Text(
      text = "Search",
      modifier = Modifier.clickable {}
    )
  }
}

Offset

@Composable
fun ModifierEx() {
  Button(
    colors = ButtonDefaults.buttonColors(
      Color.Magenta,
      contentColor = Color.Cyan
    ),
    onClick = {},
    modifier = Modifier.padding(100.dp),  
  ) {
    Icon(
      imageVector = Icons.Filled.Search,
      contentDescription = "something search"
    )
    Spacer(modifier = Modifier.size(ButtonDefaults.IconSpacing))
    Text(
      text = "Search",
      modifier = Modifier.offset(x = 10.dp) // offset 설정
    )
  }
}

spacer와 text 사이에 offset이 설정된 모습

Surface

  • 가장 기본적으로 UI를 구축하는 기반.
  • 젯팩은 margin 고려하지 않음.
  • Text에 마진을 가져야 한다면, Text를 포함하는 Surface에 패딩을 설정

Default

@Composable
fun SurfaceEx(name: String) {
  Surface(
    modifier = Modifier.padding(5.dp)
  ) {
    Text(text = "Hello $name!", modifier = Modifier.padding(8.dp))
  }
}

Elevation 설정

@Composable
fun SurfaceEx(name: String) {
  Surface(
    modifier = Modifier.padding(5.dp),
    shadowElevation = 10.dp  // 그림자 생김
  ) {
    Text(text = "Hello $name!", modifier = Modifier.padding(8.dp))
  }
}

Border 설정

@Composable
fun SurfaceEx(name: String) {
  Surface(
    modifier = Modifier.padding(5.dp),
    shadowElevation = 10.dp,
    border = BorderStroke(width = 2.dp, color = Color.Magenta)
  ) {
    Text(text = "Hello $name!", modifier = Modifier.padding(8.dp))
  }
}

Shape 설정

@Composable
fun SurfaceEx(name: String) {
  Surface(
    modifier = Modifier.padding(5.dp),
    shadowElevation = 10.dp,
    border = BorderStroke(width = 2.dp, color = Color.Magenta),
    shape = CircleShape
  ) {
    Text(text = "Hello $name!", modifier = Modifier.padding(8.dp))
  }
}

Color 설정

@Composable
fun SurfaceEx(name: String) {
  Surface(
    modifier = Modifier.padding(5.dp),
    shadowElevation = 10.dp,
    border = BorderStroke(width = 2.dp, color = Color.Magenta),
    shape = CircleShape,
    color = MaterialTheme.colorScheme.surface // error, primary 등.
  ) {
    Text(text = "Hello $name!", modifier = Modifier.padding(8.dp))
  }
}

Content color를 따로 설정하지 않으면 배경 color에 맞춰 적당한 색으로 바꿔줌.

Box

  • box 자체를 사용하려는 용도
  • frame layout같이 중첩하기 위한 용도

Default

@Composable
fun BoxEx() {
  Box(modifier = Modifier.size(100.dp)) {
    Text(text = "Hello World!", modifier = Modifier.align(Alignment.Center)) // BottomCenter, End 등
  }
}

Text 두 개 배치

@Composable
fun BoxEx() {
  Box(modifier = Modifier.size(100.dp)) {
    Text(text = "Hello World", modifier = Modifier.align(Alignment.BottomEnd))
    Text(text = "Jetpack Compose", modifier = Modifier.align(Alignment.CenterEnd))
  }
}

두 개의 박스를 박스 안에 배치

@Composable
fun BoxEx() {
  Box(modifier = Modifier.size(100.dp)) {
    Box(modifier = Modifier.size(70.dp).background(Color.Cyan).align(Alignment.CenterStart))
    Box(modifier = Modifier.size(70.dp).background(Color.Yellow).align(Alignment.BottomEnd))
  }
}

부모 박스의 modifier 설정 제거

@Composable
fun BoxEx() {
  Box {
    Box(modifier = Modifier.fillMaxSize().background(Color.Cyan).align(Alignment.CenterStart)) // matchParent 설정을 하면, 두 번째 component의 크기에 맞춤.
    Box(modifier = Modifier.size(70.dp).background(Color.Yellow).align(Alignment.BottomEnd))
  }
}

Row

Row는 수평으로 배치하는 것이기 때문에, Alignment는 항상 수직으로 적용된다.

Default

@Composable
fun RowEx() {
  Row(modifier = Modifier.height(40.dp)) {
    Text(text = "fist")
    Text(text = "second")
  }
}

각 text에 align 설정

@Composable
fun RowEx() {
  Row(modifier = Modifier.height(40.dp)) {
    Text(text = "fist", modifier = Modifier.align(Alignment.Top))
    Text(text = "second", modifier = Modifier.align(Alignment.CenterVertically))
    Text(text = "third", modifier = Modifier.align(Alignment.Bottom))
  }
}

Row에 align 설정

@Composable
fun RowEx() {
  Row(
    modifier = Modifier.height(40.dp),
    verticalAlignment = Alignment.CenterVertically
  ) {
    Text(text = "fist")
    Text(text = "second")
    Text(text = "third")
  }
}

전반적으로 vertically alignmet 설정을 하고, 부분적으로 modifier 설정을 하는게 좋음

Row width 설정

@Composable
fun RowEx() {
  Row(
    modifier = Modifier.height(40.dp).width(200.dp),
    verticalAlignment = Alignment.CenterVertically,
    horizontalArrangement = Arrangement.Center // Row가 수평 정렬이기 때문에, 수평 방향 기준으로 정렬.
                                                // SpaceBeetween  : |처음 (공백) 중간 (공백) 맨 끝|
                                                // SpaceAround    : |(공백) 처음 (공백) 중간 (공백) 맨 끝 (공백)|
                                                // SpaceEvenly    : arround랑 같아보임..?
  ) {
    Text(text = "fist")
    Text(text = "second")
    Text(text = "third")
  }
}

각 text에 weight 설정

fun RowEx() {
  Row(
    modifier = Modifier
      .height(40.dp)
      .width(200.dp),
    verticalAlignment = Alignment.CenterVertically,
  ) {
    Text(
      text = "fist",
      modifier = Modifier.weight(3f)
    )
    Text(
      text = "second",
      modifier = Modifier.weight(2f)
    )
    Text(
      text = "third",
      modifier = Modifier.weight(3f)
    )
  }
}

3:2:2 비율로 정렬

text 대신 icon

@Composable
fun RowEx() {
  Row(
    modifier = Modifier
      .height(40.dp)
      .width(200.dp),
    verticalAlignment = Alignment.CenterVertically,
  ) {
    Text(
      text = "fist",
      modifier = Modifier.weight(3f).background(color = Color.Magenta),
      // textAlign = TextAlign.Center // text align 설정도 가능
    )
    Icon(
      imageVector = Icons.Filled.Add,
      contentDescription = "추가",
      modifier = Modifier.weight(1f).background(color = Color.Green)
    )
    Text(
      text = "third",
      modifier = Modifier.weight(3f).background(color = Color.Cyan)
    )
  }
}
<img width="233" alt="스크린샷 2024-01-24 오후 10 56 13" src="https://github.com/Chaebin-Park/Chaebin-Park.github.io/assets/64880435/80f5a9a8-2d9e-498e-961b-6c4ffb15c566">

3:1:2 비율로 정렬


Column

Row 개념과 비슷함.

Default

@Composable
fun ColumnEx() {
  Column(modifier = Modifier.size(100.dp)) {
    Text(text = "first")
    Text(text = "second")
    Text(text = "third")
  }
}

Horizontal alignment

@Composable
fun ColumnEx() {
  Column(
    modifier = Modifier.size(100.dp),
    horizontalAlignment = Alignment.CenterHorizontally
  ) {
    Text(text = "first")
    Text(text = "second")
    Text(text = "third")
  }
}

Vertical arrangement

@Composable
fun ColumnEx() {
  Column(
    modifier = Modifier.size(100.dp),
    horizontalAlignment = Alignment.End, // 여기서는 horizontal vertical 나눠 써야함
    verticalArrangement = Arrangement.SpaceEvenly // 여기서는 그냥 Center (horizontal, vertical)
  ) {
    Text(text = "first")
    Text(text = "second")
    Text(text = "third")
  }
}

개별 text align

@Composable
fun ColumnEx() {
  Column(
    modifier = Modifier.size(100.dp),
    horizontalAlignment = Alignment.End,
    verticalArrangement = Arrangement.SpaceEvenly
  ) {
    Text(
      text = "first",
      modifier = Modifier.align(Alignment.CenterHorizontally)
    )
    Text(text = "second")
    Text(
      text = "third",
      modifier = Modifier.align(Alignment.Start)
    )
  }
}

BoxWithConstraints

Default

@Composable
fun Outer() {
  Column {
    Inner()
  }
}

@Composable
fun Inner() {
  BoxWithConstraints {
    // BoxWithConstaints scope에서는 Box scope에서 추가로
    // constraint, min/max width/height를 알 수 있음
    Text(text = "maxW: $maxWidth maxH: $maxHeight minW: $minWidth minH: $minHeight")
  }
}

Inner 인자로 modifier 전달

@Composable
fun Outer() {
  Column {
    Inner(
      modifier = Modifier
        .widthIn(min = 100.dp, max = 350.dp)
        .heightIn(min = 50.dp, max = 40.dp) // preview 크기에 따라 달라질 수 있으니,
                                            // height, width로 강제 지정해야 할 때가 있음
    )
  }
}

@Composable
fun Inner(modifier: Modifier = Modifier) {
  BoxWithConstraints(modifier) {
    Text(text = "maxW: $maxWidth maxH: $maxHeight minW: $minWidth minH: $minHeight")
  }
}

모든 component는 기본 companion object로 Modifier를 가지고 있음

profile
안드로이드 개발자

0개의 댓글