오늘은 안드로이드 Jetpack Compose에 대해서 알아보고,
기본적인 UI API들에 대해서 정리해 보겠습니다.
1. Android Jetpack Compose
1-1. NoXML, welcome functions
이제 xml 필요없이 kotlin만으로, Android의 UI까지 개발할 수 있게 되었는데요.
만약, 텍스트, 라디오 버튼의로 구성된 UI가 가로로 있다고 가정해 보겠습니다.
이전에는 xml로 UI를 구성하고, 그것의 reference를 Kotlin코드에서 가져와서,
응답이나 반응등을 코드에서 구현하였는데요.
background 이미지를 바꾸거나, 색을 변경해 주었습니다.
이제는 아래와 같은 코드로 UI를 구성하게 되었습니다.
Compose에서는 UI 요소들은 더이상 객체가 아니라 함수입니다.
레퍼런스해서 가져오는 대상이 더이상 아니라는 것이지요.
UI요소들은 state이나 전달된 인자에 의해서 변경됩니다.
가져와서 setText하거나 할 필요도 없습니다.
1-2. Single Activity
Compose를 사용하면 Activity를 하나만 두고도 충분히 앱을 만들 수 있습니다.
물론, 여러 액티비티를 사용하는 것이 제한되는 것은 아니지만,
Fragment없이도 여러 페이지로 Navigation을 이용해서 이동하고,
데이터 전달을 할 수 있습니다.
이 부분에 대해서는 기본 UI에 대한 글을 모두 읽은 후에 아래 Navigation에 대한 글을 참조해 주시면 됩니다.
>> Navigation 과 Bottom Navigation 구현방법 정리 # Jetpack Compose
2. setUp
2-1. 빠른 setup
Jetpack Compose를 경험하기 위해서 여러가지 setup이 필요한데요.
기존 View와는 완전히 새로운 시스템이므로,
여러가지 설정이 필요합니다.
new Project에서 > Empty ComposeActivity 를 선택해 주고, Next를 눌러주면
정말 빠르게 Jetpack Compose를 사용할 수 있도록 도와줍니다.
설정이 끝나고 나서,
안드로이드 스튜디오의 왼쪽네비게이션을 보면, res밑에 그동안 보이던 layout과 xml파일들이 없다는 것을 볼 수 있습니다.
3. setContent 와 Composable 함수
3-1. setContent
Activity에서 UI를 구현할 때,
이전처럼 setContentView()라고 하는 함수를 직접 사용하지 않고,
setContent 라는 함수를 사용하게 됩니다.
setContent함수안에서 Composable함수를 실행해서 UI를 보여주게 되는데요.
아래는 MessageBox()라는 함수가 실행되고 있습니다.
setContent함수의 코드를 보면, 주석에 나와있는 것처럼,
setContent 함수가 ComposeView와함께 setContentView함수를 호출해주고 있다는 것을 알 수 있습니다.
3-2. Composable 함수
아래에서는 Greeting이라는 Composable 함수가 있는데요.
"@Composable" Annotation 부분이 눈에 띕니다.
UI를 담당하는 Composable 함수라는 의미인데요.
함수로 따로 떼어내서 재사용 할 수 있는 UI를 얼마든지 만들 수 있습니다.
Kotlin의 문법을 그대로 따르므로 특별할 것은 없구요.
함수이지만, 대문자로 시작하는 네이밍컨벤션을 따른다는 점이 특이합니다.
위 코드에서 보이는 @Preview 는 안드로이드 스튜디오의 Preview화면에서 보기 위한 부분인데요.
Preview를 위한 코드를 일일히 작성해주어야 합니다.
preview를 위해서 Composable함수를 불러서 사용해 주어야 합니다.
xml보다 바로바로 직관적으로 preview하기가 어려워 졌다는 면이 아무래도 있습니다.
4. Layout Composable
먼저 기본적인 Layout Composable 에 대해서 알아보겠습니다.
Compose는 Row나 Column등 Layout Composable로 감싸주지 않으면,
작성된 Layout요소들(Text, Image 등)을 위에 쌓아 줍니다.
겹쳐보이게 된다는 것 이지요.
그럼 Layout요소들을 알아보도록 하겠습니다.
가장 먼저 Layout을 짤 때 고민하는 것은 가로방향인지, 세로방향인지 인데요.
이것을 결정하는 Column과 Row에 대해서 알아보도록 하겠습니다.
4-1. Column
Column 은 엘리먼트들을 세로로 배열할 때 사용하는 Layout Composable입니다.
먼저 @Composable Annotation을 붙인 Composable 함수를 만들어 줍니다.
세로로 요소들을 배열하는 Column안에 아래와 같이 2개의 Text를 배열해 보겠습니다.
결과는 다음과 같이 나옵니다.
4-2. Row
가로로 배열을 할 때는 Row 라는 Layout Composable을 사용해주면 됩니다.
사용방법도 Column과 같이 감싸주기만 하면 됩니다.
4-3. arrangement 와 alignment
실제로 앱 UI를 하려면 훨씬 더 복잡한 옵션들이 필요한데요.
먼저 Column의 코드를 보겠습니다.
인자로 arrangement, Alignment 그리고 modifier 에 대해서 넣어줄 수 있습니다.
modifier는 아래에서 보도록 하구요.
여기서는 alignment(정렬)와 arrangement를 넣어주도록 하겠습니다.
먼저 Alignment를 보겠습니다.
Androdi Studio의 도움을 받으면 어렵지 않게 선택해서 넣을 수 있습니다.
arrangement도 넣어보겠습니다.
역시 안드로이드스튜디오 도움으로 쉽게 넣을 수 있습니다.
여기서는 Center를 선택하겠습니다.
Arrangement에서는 위에서 선택했던 Center말고도,
SpaceBetween같이 재미있는 요소들도 있는데요.
이들은 Layout안의 요소들의 간격에 관한 것인데 다음과 같은 차이가 있습니다.
- SpaceBetween - 요소들 간격을 최대한으로 벌려놓습니다.
- SpaceEvenly - 요소들간 간격을 동일하게 벌려주구요,
- SpaceAround - Evenly처럼 간격은 동일하게 해주면서도, 끝에 있는 아이템과 Comlum간의 간격은 그 절반으로 해주는 역할을 합니다.
이제 위에서 한 것을 바탕으로,
Column안에 Image와 Row를 넣고,
Row안에 텍스트 2개를 배열해 보겠습니다.
이제 앱을 실행해보면 다음과 같은 모습을 볼 수 있습니다.
추가적으로 Text에는 아래와 같이 다양한 TextStyle을 적용할 수 있으므로,
여러가지를 실험해보면서 적용해보면 좋을 것 같습니다.
Text사이즈를 사용할 때는 sp단위를 사용해주면 좋은데요.
아래와 같이 ".sp"형태로 붙여서 넣어주면 됩니다.
4-3. Modifier - weight, width, height, background, border
위에서 해보았던 간단한 alignment나 arrangement 이외에도,
Modifier를 이용해서 더욱 많은 레이아웃 옵션을 설정할 수 있습니다.
A. weight
Column()과 Row()에는 weight를 사용해서 비율을 정해줄 수 있습니다.
아래와 같이 1:1로 해 준다면, 전체 사이즈의 절반씩 가져가게 될 것이구요.
아래와 같이 3:7로 해서 실행해 보겠습니다.
아래와 같이 3:7 비율로 실행되는 것을 볼 수 있습니다.
B. Width, Height, fillMax
이번에는 Layout의 Row의 가로세로 사이즈에 대해서 설정해 보겠습니다.
아래에서는 fillMaxWidth와 height 그리고 background를 사용하였는데요.
각각 다음과 같은 역할을 해 줍니다.
- fillMaxWidth, fillMaxHeight: 가로 또는 세로의 최대길이를 차지
- width, heigth: 가로와 세로를 dp단위로 지정
- fillMaxSize: 가로와 세로 부모의 사이즈를 최대로 차지
fillMaxWidth를 하면 화면의 100%를 채우겠지만,
인자로 아래와 같이 float값을 주면 그 비율만큼만 차지할수 있습니다.
아래에서 height는 dp로 설정하였는데요.
dp단위를 나타낼 때는 아래와 같이 닷(".")을 이용해 주면 됩니다.
background는 아래와 같이 쉽게 표현할 수 있습니다.
앱을 실행해보면 아래와 같이 렌더링 된 것을 볼 수 있습니다.
border도 적용이 가능한데요.
modifier들은 코드를 작성한 순차적으로 적용이 되구요.
중첩은 되더라도 나중에 쓰여진 것이 위로 쌓이게 됩니다.
이를 이용하면 중첩된 border의 작성도 가능하겠지요.
실행해보면 다음과 같이 중첩되어진 것을 볼 수 있습니다.
C. requireWidth, requireHeight
한가지 더 보고 갈 것이 있는데요.
requireWidth()나 requireHeight() 입니다.
이것은 최소한의 가로 또는 세로인데요.
미니멈값으로 차지하고 있어야 하는 길이를 말합니다.
D. padding
이번에는 modifier로 패딩을 적용해 보겠습니다.
8dp를 Image 주변에 적용하였는데요.
실행해보면 다음과 같이 패딩이 적용된 것을 볼 수 있습니다.
아래와 같은 방식으로, 각 위치별로도 적용할 수 있습니다.
E. offset
Compose에서는 margin이 사라지고, offset이라는 개념만 남았는데요.
margin 을 대체하긴 하였지만 동일한 개념은 아닙니다.
offset은 자신을 특정 요소로부터 멀어지게는 하는데요.
margin처럼 다른 요소를 밀어내지는 못합니다.
즉, 잘못하면 다른 요소와 겹쳐져 버릴 수 있다는 뜻 입니다.
아래와 같이 하나의 요소에 offset을 주었습니다.
실행해보면 뒤로 멀어진 것을 볼 수 있습니다.
참고로 이 요소는 top이나 bottome이 아니라,
x나 y로 가로세로로 범위를 지정해 줍니다.
offset의 코드를 보면 다음과 같습니다.
마이너스 값도 지정할 수 있다고 나와있네요.
4-4. Clickable
Click이벤트가 필요하면 쉽게 이를 활용할 수 있습니다.
clickable은 lambda를 이용해서 아래와 같이 쉽게 작성할 수 있습니다.
참고로 Composable에서는 context를 아래와 같이 "LocalContext.current"에서 얻어와야 합니다.
이외에도 draggable, Scrollable 도 쉽게 적용시킬 수 있습니다.
Scrollable은 State가 필요한데요.
State에 대해 다루는 다음 글 이후에 다루도록 하겠습니다.
4-5. Box
기존에 있었던 FrameLayout과 비슷한 역할을 해주는 Layout입니다.
FrameLayout처럼 이곳에 아이템들을 넣으면 위에 쌓이게 됩니다.
UI위에 UI를 쌓을때는 이 Box를 사용해야 하는 것 이지요.
예를 들어서, 이미지위에 텍스트를 올리려고 할 때 바로 Box를 사용하는 것 이지요.
코드 상 먼저 들어간 element가 아래에 놓이게 됩니다.
Column이나 Rows가 못하는 역할을 해 줄수 있습니다.
LinearLayout이 못하던 것을 FrameLayout이 대신해 주었던 것처럼요.
Box에서 alignment는 Modifier를 사용해 주어야 하는 것이 차이점입니다.
4-6. Card
머티리얼 디자인 요소가 적용된 카드 layout입니다.
shape이나 elevation, border, shadow등을 설정할 수 있습니다.
아래 4에서 실제로 CardUI를 만들어 보면서 좀 더 정리해 보도록 하겠습니다.
4-7. Spacer
빈 공간을 가지고 있는 비어져 있는 요소입니다.
위에서 offset은 밀려나면서 다른 요소를 침범해 겹쳐져 버릴 수 있다고 하였는데요.
이런 Space를 중간에 두면 그런 것에대한 방어가 될 수 있겠지요.
5. Card 와 Box 를 이용한 Card UI
위에서 보았던 Card와 Box를 이용해서 Card UI를 만들어 보도록 하겠습니다.
가장 먼저 할 것은 Composable을 작성하는 것 입니다.
이제 이 함수에 인자로 받아들일 것들을 생각해 봐야 합니다.
ImageCard에 들어갈 string이 필요할 것이구요.
이미지도 불러와야 합니다.
그런데, 이미지를 설정할 때 마다 다르게 해 주어야 하므로,
인자로 받아서 설정해 주어야 합니다.
그렇게 하기위해서, Composable의 Painter타입의 painter도 추가해 줍니다.
구조는 다음과 같이 넣도록 하겠습니다.
Card안에 Column이 들어가고,
세로로 Image와 Text 그리고 Text를 하나 더 배열하는 것 이지요.
Card > Column > Image, Text, Text
먼저 Card 안에 Column을 아래와 같이 배치해 줍니다.
특별한 것은 없구요. Card에 border와 shape을 정해주는데요.
shape을 설정해 줄 때는 RoundedCornerShape형태로 해 줍니다.
이제 Column안에 Image와 Text2개를 연속으로 배열합니다.
이 카드는 50% 비율로 화면에 차지하게 하기 위해서, 아래와 같이 setContent에서 배열해 줍니다.
이것을 실행해 보면 아래와 같은 화면이 나오는 것을 볼 수 있습니다.
이제 저 이미지 위에 텍스트를 오버레이해서 올려보겠습니다.
이미지가 있던 Box안에, 다시 Box를 쌓아올리고, 그 안에 text를 올렸습니다.
실행해보면 다음과 같이 나오는 것을 볼 수 있습니다.
6. Button
6. Custom 컬러 설정
6-1. Hex값의 입력
컬러의 경우 아래와 같이 #대신 0xFF로 대신해서 넣어주면 됩니다.
Color클래스의 companion object를 보면 다음과 같은데요.
Black은 #000000 인데 이것을 0xFF000000 으로 바꿔준 것을 볼 수 있습니다.
아래와 같이 넣어주면 됩니다.
6-2. toColorInt
안드로이드의 Kotlin라이브러리 중 하나인 Core-KTX에서는,
String의 확장함수인 toColorInt()라는 API를 제공해주는데요.
String hex값을 Color클래스가 필요로하는 Int값으로 변환시켜 줍니다.
이를 활용해서 쉽게 String hex값을 적용해 줄 수 있습니다.
6-3. Button 컬러의 변경
버튼 컬러를 변경할 때는 조금 다른 방법을 사용해 주어야 하는데요.
기존의 Button에 보면 아래와 같이 컬러가 정의된 것을 볼 수 있습니다.
colors에 정의하는 컬러 타입이 ButtonColors여야 하는데요.
아래 코드 주석에 나오는 것과 같이,
backgroundColor는 버튼의 배경색이구요.
contentColor는 버튼에 올라오는 컨텐츠의 색깔입니다.
disable되었을 때의 색깔은 disabledBackgroundColor와 disabledContentColor를 설정해주면 됩니다.
아래와 같이 buttonColors 함수를 이용해 주기만 하면 됩니다.
컨텐츠가 있을 경우에는 contentColor를 넣어주면 됩니다.
버튼에 텍스트가 있을 경우 특히 유효하겠지요.
6-4. Icon Color 변경
Icon클래스를 보면 다음과 같이 정의되어 있는데요.
Color타입이기는 하지만 아래와 같이 copy값에 아래와 같이 alpha값을 설정해 주면 됩니다.
Material 벡터 Icon의 컬러를 변경해 주려면 다음과 같이 해주면 됩니다.
6-3. copy함수의 활용
한가지 Color 클래스에는 copy함수가 있는데요.
원래 색깔에서 alpha나 red, green, blue 값을 변경할 수 있습니다.
색보정앱이 아니고서야, alpha정도 변경하는데 도움이 되겠지요.
아래와 같이 적용해 볼 수 있습니다.
여기까지 part1에서 Row, Column, Modifier, Card, Composable Functions, Color 에 대해서 정리해 보았습니다.
'Android Jetpack Compose > Jetpack Compose' 카테고리의 다른 글
Jetpack Compose 화면 하단에 배치하기 (0) | 2023.03.22 |
---|---|
Jetpack Compose 에서 자간 줄이는 방법 # letterSpacing (0) | 2023.03.21 |
Button Selector 구현 방법 # 버튼 눌렸을 때 Interaction Jetpack Compose (0) | 2022.11.28 |
Jetpack Compose 에서 점선 그리는 방법 정리 # Border dashed line (0) | 2022.11.25 |
BottomBar Hide 구현방법 정리 # Android Jetpack Compose (0) | 2022.11.22 |
Jetpack Compose 에서 Activity Result 가져오기 # rememberLauncherForActivityResult (0) | 2022.11.21 |
Scaffold, SnackBar 그리고 FloatingActionButton 정리 # Jetpack Compose UI Part3 (0) | 2022.11.15 |
State 를 이해하고 TextField 구현하기 # Jetpack Compose UI Part2 (0) | 2022.11.14 |
Time Picker 와 Date Picker Compose 로 구현하기 # Android Jetpack Picker (0) | 2022.10.31 |
ConstraintLayout 을 Compose 로 구현하는 방법 # Android (0) | 2022.10.20 |
댓글