나만의 갤러리 만들어보기
위의 페이지를 참고하여 나만의 갤러리를 만들어보자
개요
지금까지 배운 내용을 바탕으로 조잡하지만 갤러리를 만들어보았다
완성코드
코드는 다음과 같다
package com.example.myartspace
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.myartspace.ui.theme.MyArtSpaceTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyArtSpaceTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
GalleryUI()
}
}
}
}
}
@Composable
fun GalleryUI(){
var page by remember { mutableStateOf(4) }
var theme by remember { mutableStateOf("space") }
var picNum by remember { mutableStateOf(0) }
val setPicNum: (Int) -> Unit = { it -> picNum = it}
val setTheme: (String) -> Unit = { it -> theme = it}
val setPage: (Int) -> Unit = { it -> page = it }
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Top
) {
if(page != 0) {
Button(
modifier = Modifier.padding(25.dp),
onClick = { ifBackButtonClicked(page, theme, setPage, setTheme)
}) { Text("back") }
}
Spacer(modifier = Modifier.height(40.dp))
if (page == 0) {
GalleryHallUI(setTheme, setPage)
} else if (page == 1) {
ThemeGalleryUI("space", setPage, setPicNum)
} else if (page == 2) {
ThemeGalleryUI("flower", setPage, setPicNum)
} else if (page == 3) {
ThemeGalleryUI("car", setPage, setPicNum)
} else {
PaintingUI(theme, picNum, setPicNum)
}
}
}
@Composable
fun GalleryHallUI(setTheme:(String) -> Unit, setPage: (Int) -> Unit) {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceEvenly
){
Text(
"My Art Gallery",
fontSize = 50.sp,
fontWeight = FontWeight.Bold
)
GalleryHallThemeUI(theme = "space", page = 1, setTheme = setTheme , setPage = setPage)
GalleryHallThemeUI(theme = "flower", page = 2, setTheme = setTheme , setPage = setPage)
GalleryHallThemeUI(theme = "car", page = 3, setTheme = setTheme , setPage = setPage)
}
}
@Composable
fun GalleryHallThemeUI(theme: String, page: Int, setTheme:(String) -> Unit, setPage: (Int) -> Unit){
val painter = setPainter(theme)
Column(
modifier = Modifier
.width(200.dp)
.clickable(onClick = {
setPage(page)
setTheme(theme)
}),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Image(
modifier = Modifier.height(150.dp),
painter = painterResource(painter),
contentDescription = null
)
Text(text = theme, fontSize = 24.sp, fontWeight = FontWeight.Bold)
}
}
@Composable
fun ThemeGalleryUI(theme: String, setPage: (Int) -> Unit, setPicNum: (Int) -> Unit){
var paintArray = Array(10, {0})
setPaintArray(paintArray, theme)
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
){
Text(text = theme, fontSize = 40.sp, fontWeight = FontWeight.Bold)
ThemeGalleryRowUI(paintArray, 0, setPage, setPicNum)
ThemeGalleryRowUI(paintArray, 3, setPage, setPicNum)
ThemeGalleryRowUI(paintArray, 6, setPage, setPicNum)
}
}
@Composable
fun PaintingUI(theme: String, picNum: Int, setPicNum: (Int) -> Unit){
var paint = getPaint(theme, picNum)
var paintDescription = getPaintDescription(theme, picNum)
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceEvenly
) {
Column(
modifier = Modifier.height(500.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Image(
modifier = Modifier.width(300.dp),
painter = painterResource(paint), contentDescription = null)
Text(stringResource(paintDescription))
}
Row(
modifier = Modifier
.height(100.dp)
.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceAround,
verticalAlignment = Alignment.CenterVertically
){
Button(onClick = { setPicNum(calculatePicNum(picNum)) }){ Text("previous")}
Button(onClick = { setPicNum((picNum+1)%9) }){ Text("next")}
}
}
}
@Composable
fun ThemeGalleryRowUI(paintArray: Array<Int>, startNum: Int, setPage: (Int) -> Unit, setPicNum: (Int) -> Unit){
Row(
modifier = Modifier
.height(200.dp)
.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceEvenly,
verticalAlignment = Alignment.CenterVertically
) {
ThemeGalleryImage(paint = paintArray[startNum], startNum, setPage, setPicNum)
ThemeGalleryImage(paint = paintArray[startNum+1], startNum+1, setPage, setPicNum)
ThemeGalleryImage(paint = paintArray[startNum+2], startNum+2, setPage, setPicNum)
}
}
@Composable
fun ThemeGalleryImage(paint: Int, picNum: Int, setPage: (Int) -> Unit, setPicNum: (Int) -> Unit){
Image(modifier = Modifier
.height(100.dp)
.width(100.dp)
.clickable(onClick = {
setPage(4)
setPicNum(picNum)
}),
contentScale= ContentScale.Crop,
painter = painterResource(paint),
contentDescription = null)
}
private fun ifBackButtonClicked(page: Int, theme: String, setPage: (Int) -> Unit, setTheme: (String) -> Unit){
if (page in 1..3) {
setPage(0)
setTheme("")
} else if (page == 4) {
when (theme) {
"space" -> setPage(1)
"flower" -> setPage(2)
else -> setPage(3)
}
}
}
private fun setPainter(theme: String): Int{
val painter = when(theme){
"space" -> R.drawable.space0
"flower" -> R.drawable.flower0
else -> R.drawable.car0
}
return painter
}
private fun setPaintArray(paintArray: Array<Int>, theme: String){
when (theme) {
"space" -> {
paintArray[0] = R.drawable.space0
paintArray[1] = R.drawable.space1
paintArray[2] = R.drawable.space2
paintArray[3] = R.drawable.space3
paintArray[4] = R.drawable.space4
paintArray[5] = R.drawable.space5
paintArray[6] = R.drawable.space6
paintArray[7] = R.drawable.space7
paintArray[8] = R.drawable.space8
}
"flower" -> {
paintArray[0] = R.drawable.flower0
paintArray[1] = R.drawable.flower1
paintArray[2] = R.drawable.flower2
paintArray[3] = R.drawable.flower3
paintArray[4] = R.drawable.flower4
paintArray[5] = R.drawable.flower5
paintArray[6] = R.drawable.flower6
paintArray[7] = R.drawable.flower7
paintArray[8] = R.drawable.flower8
}
else -> {
paintArray[0] = R.drawable.car0
paintArray[1] = R.drawable.car1
paintArray[2] = R.drawable.car2
paintArray[3] = R.drawable.car3
paintArray[4] = R.drawable.car4
paintArray[5] = R.drawable.car5
paintArray[6] = R.drawable.car6
paintArray[7] = R.drawable.car7
paintArray[8] = R.drawable.car8
}
}
}
private fun getPaint(theme: String, picNum: Int): Int{
var paint = 0
if(theme == "space"){
paint = when(picNum){
0 -> R.drawable.space0
1 -> R.drawable.space1
2 -> R.drawable.space2
3 -> R.drawable.space3
4 -> R.drawable.space4
5 -> R.drawable.space5
6 -> R.drawable.space6
7 -> R.drawable.space7
else -> R.drawable.space8
}
} else if (theme == "flower"){
paint = when(picNum){
0 -> R.drawable.flower0
1 -> R.drawable.flower1
2 -> R.drawable.flower2
3 -> R.drawable.flower3
4 -> R.drawable.flower4
5 -> R.drawable.flower5
6 -> R.drawable.flower6
7 -> R.drawable.flower7
else -> R.drawable.flower8
}
} else {
paint = when(picNum){
0 -> R.drawable.car0
1 -> R.drawable.car1
2 -> R.drawable.car2
3 -> R.drawable.car3
4 -> R.drawable.car4
5 -> R.drawable.car5
6 -> R.drawable.car6
7 -> R.drawable.car7
else -> R.drawable.car8
}
}
return paint
}
private fun getPaintDescription(theme: String, picNum: Int): Int{
var description = 0
if(theme == "space"){
description = when(picNum) {
1 -> R.string.space0
2 -> R.string.space1
3 -> R.string.space2
4 -> R.string.space3
5 -> R.string.space4
6 -> R.string.space5
7 -> R.string.space6
8 -> R.string.space7
else -> R.string.space8
}
} else if(theme == "flower") {
description = when (picNum) {
1 -> R.string.flower0
2 -> R.string.flower1
3 -> R.string.flower2
4 -> R.string.flower3
5 -> R.string.flower4
6 -> R.string.flower5
7 -> R.string.flower6
8 -> R.string.flower7
else -> R.string.flower8
}
} else {
description = when(picNum) {
1 -> R.string.car0
2 -> R.string.car1
3 -> R.string.car2
4 -> R.string.car3
5 -> R.string.car4
6 -> R.string.car5
7 -> R.string.car6
8 -> R.string.car7
else -> R.string.car8
}
}
return description
}
private fun calculatePicNum(picNum: Int): Int{
var temp = (picNum-1)
var result = 0
if(picNum >= 0){
result = temp%9
} else {
result = ((temp%9)+9)
}
return result
}
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
MyArtSpaceTheme {
GalleryUI()
}
}
코드 설명
페이지 변경을 이런 식으로 구현하는게 일반적인 지는 잘 모르겠지만
내가 생각해본 방법으로 만들었다
가장 메인화면은 GalleryHall
테마별 갤러리 화면은 ThemeGallery
각 그림을 보는 화면은 Painting
이라고 이름 지었고
화면 구성은 UI라는 이름의 composable에
어떤 페이지로 이동하고 어떤 리소스를 출력할지 결정하는 로직은
모두 private 함수에 집어넣었다
getPaintDescription과 같은 로직 함수에서 페이지나 테마, 그림 번호를 가지고
적절한 리소스를 가져오는 부분이 있는데
코드를 좀 더 간략하게 짤 수 있는 방법이 궁금했지만 찾지 못했다
javascript의 eval() 함수와 비슷한 느낌이면 될 거 같은데...
그리고 아직 문법적으로 배우지는 않았지만 배열이 필요해져서 써봤다
관련 문법은 다음에 정리하기로 했다
결과화면
'기타 > 안드로이드' 카테고리의 다른 글
22. Kotlin의 컬렉션 (2) | 2022.10.14 |
---|---|
21. Kotlin의 generic, enum, data class, object, 범위함수 (0) | 2022.10.14 |
Tip Time App - local & instrumentation test (2) | 2022.10.14 |
Tip Time App - Switch, @StringRes, KeyboardOptions (0) | 2022.10.14 |
Tip Time App - remember API, Composable LifeCycle (2) | 2022.10.14 |