Android Compose 적용 해보기 2

2022. 7. 5. 16:50Android

반응형

 

https://guguhome.tistory.com/27

 

Android Compose 적용 해보기 1

이번에 포스팅 주제는 Compose 를 실제로 적용해보기입니다. 저번에 Compose 작성 관련해서 포스팅 하였는데 그때는 Compose 란 무엇인가와 Compose 에 대한 저의 생각을 적은 글이였었습니다. 저런 글을

guguhome.tistory.com

 

 

최근에 회사일이 바빠져서 Compose 적용기 2탄을 좀 늦게 올립니다.

 

바로 시작하겠습니다.

 

지난번에 비해 개선 사항으로는 UI들을 다 한곳에 코드를 쓴게아닌 기능이 비슷한 것끼리 묶어서 작성하였습니다.

 

최종적으로 MVVM 까지 적용을 시켜봤습니다.

 

 

@AndroidEntryPoint
class StorageMaterialSettingComposeActivity : ComponentActivity() {

    private val viewModel : StorageMaterialSettingViewModel by viewModels()


    @SuppressLint("CoroutineCreationDuringComposition")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        viewModel.setSeq(intent.getLongExtra("seq",0))

        setContent {
            CookingAssistanceTheme {

                Surface(color = MaterialTheme.colors.background) {
                    View()

                }

            }
        }

    }


}

 

기존 onCreate 애서는 크게 변화는 없습니다.

 

 

@Composable
private fun View(viewModel: StorageMaterialSettingViewModel = viewModel()){

    val activity = (LocalContext.current as Activity)


    Column {
        Header(onSetDeleteDialog = {setDeleteDialog(activity = activity ,onSetDelete = {
            viewModel.setDelete()
        })})
        Body(activity,viewModel)
    }

}

상단에 Heder 와 Body 로 구분하였습니다.

 

 

@SuppressLint("StateFlowValueCalledInComposition")
@Composable
fun Body(activity: Activity , viewModel : StorageMaterialSettingViewModel ){

    val focusManager : FocusManager = LocalFocusManager.current//배경 포커스 잡기

    Column(modifier = Modifier
        .fillMaxHeight()
        .addFocusCleaner(
            focusManager
        )) {

        Name(name = viewModel.storageData.collectAsState().value.name)

        Size(size = viewModel.storageData.collectAsState().value.size.toString() , focusManager = focusManager , onSize = {
            viewModel.setSize(it)
        })

        Date(activity = activity , viewModel = viewModel , date = viewModel.storageData.collectAsState().value.date , type = 0 , focusManager = focusManager)
        Date(activity = activity , viewModel = viewModel , date = viewModel.storageData.collectAsState().value.expiration_date , type = 1 , focusManager = focusManager)


        Note(note = viewModel.storageData.collectAsState().value.note , onNote = {
            viewModel.setNote(it)
        })

        Spacer(modifier = Modifier.weight(1f))

        OkButton(onFinish = { activity.finish() } , onSetData = { viewModel.setData()})
    }

}

 

//재료 이름
@Composable
fun Name(name : String){
    Column(modifier = Modifier.fillMaxWidth() , horizontalAlignment = Alignment.CenterHorizontally) {
        Text(text = name  ,fontSize = 20.sp ,  color = colorResource(id = R.color.color_000000))
    }
}

//재료 갯수
@Composable
fun Size(size : String , focusManager : FocusManager , onSize : (String) -> Unit ){
    Column(modifier = Modifier
        .fillMaxWidth()
        .padding(20.dp, 50.dp, 20.dp, 10.dp)) {

        Row {
            Text(text = "갯수 : " , color = colorResource(id = R.color.color_000000) ,fontSize = 17.sp  , modifier = Modifier
                .align(
                    Alignment.CenterVertically
                )
                .padding(10.dp))

            BasicTextField(
                value = size,
                onValueChange = {
                    onSize(it)
//                    viewModel.setSize(it)
                }  ,
                modifier = Modifier
                    .fillMaxWidth()
                    .align(Alignment.CenterVertically),
                textStyle = TextStyle(fontSize = 17.sp ,color = colorResource(id = R.color.color_000000)) ,
                maxLines = 1 ,
                keyboardOptions = KeyboardOptions(keyboardType= KeyboardType.Number , imeAction = ImeAction.Done),
                keyboardActions = KeyboardActions(onDone = {
                    focusManager.clearFocus()
                }))


        }
    }
}

//구입한 날짜 or 유통기한
@Composable
fun Date(activity: Activity, date : String , viewModel: StorageMaterialSettingViewModel , type: Int , focusManager: FocusManager ){

    val title = if(type == 0){
        "구매날짜 : "
    }
    else{
        "유통기한 : "
    }
    //type 0:구입한날짜 , 1:유통기한
    Column(modifier = Modifier
        .fillMaxWidth()
        .padding(20.dp, 20.dp, 20.dp, 10.dp)) {

        Row {
            Button(onClick = {
                setDate(activity,viewModel,type)
                focusManager.clearFocus()

            },
                colors =  ButtonDefaults.buttonColors(Color.Transparent) , elevation = ButtonDefaults.elevation(
                    defaultElevation = 0.dp ,
                    pressedElevation = 0.dp ,
                    disabledElevation = 0.dp
                ) , contentPadding = PaddingValues(0.dp)){

                Text(text = title , color = colorResource(id = R.color.color_000000) ,fontSize = 17.sp  , modifier = Modifier
                    .align(
                        Alignment.CenterVertically
                    )
                    .padding(10.dp))

                Text(text = date , color = colorResource(id = R.color.color_000000) ,fontSize = 17.sp  , modifier = Modifier
                    .align(
                        Alignment.CenterVertically
                    )
                    .weight(1f))

                Image(painter = painterResource(id = R.drawable.ic_edit_24), contentDescription = "edit" , colorFilter = ColorFilter.tint(
                    colorResource(id = R.color.color_000000)) , modifier = Modifier.align(Alignment.CenterVertically))

            }

        }
    }
}

//메모
@Composable
fun Note(note : String , onNote : (String) -> Unit){
    Column(modifier = Modifier
        .padding(20.dp, 30.dp, 20.dp, 0.dp)) {

        TextField(value = note,
            onValueChange = {
                onNote(it)
            },
            modifier = Modifier
                .fillMaxWidth()
                .defaultMinSize(minHeight = 300.dp)
                .border(
                    width = 1.dp, shape = RoundedCornerShape(20.dp), color = colorResource(
                        id = R.color.color_DDDDDD
                    )
                )
            , colors = TextFieldDefaults.textFieldColors(focusedIndicatorColor = Color.Transparent  , backgroundColor = Color.Transparent
                , textColor = colorResource(id = R.color.color_000000) , unfocusedIndicatorColor = Color.Transparent) ,

            textStyle = TextStyle(fontSize = 15.sp)
        )

    }
}

//완료버튼
@Composable
fun OkButton(onFinish : ()->Unit , onSetData : ()->Unit){
    Button(onClick = {
        onFinish()
        onSetData()
    } ,
        modifier = Modifier.fillMaxWidth() , colors = ButtonDefaults.buttonColors(backgroundColor = colorResource(
            id = R.color.color_000000)) , elevation = ButtonDefaults.elevation(
            defaultElevation = 0.dp ,
            pressedElevation = 0.dp ,
            disabledElevation = 0.dp
        )) {
        Text(text = "저장" , color = colorResource(id = R.color.color_FFFFFF))

    }
}

 

각 기능을 하는 Composable 를 다 나누었고

 

그 중 비슷 하게 동작하는것들은 묶어놨습니다.

 

확실히 이렇게 보니 xml 보다 전체적으로 코드량은 줄어든게 눈에 띕니다.

 

 

최종적으로 동작하는 모습입니다

 

 

글을 마치며

 

한번 제가 지금 토이프로젝트로 만들고있는곳에 Compose 를 적용을 시켜보았습니다.

 

저도 이것저것 이론적으로 알아본것만 있었지 처음 적용을 해보다보니 생각보다 어려움이 많았습니다.

 

그 중 제일 어려웠던 부분은 아무래도 익숙치 않다보니 각 view 에 어떤 옵션이 있고 어떻게 옵션을 넣는지가 어렵더군요

 

기존xml 방식으로 했다 한다면 저 화면을 만드는데 오랜시간이 안걸렸겟지만 

 

처음 써보는 Compose 로 만들다보니 반나절의 시간정도 소요를 한거 같습니다.

 

그리고 UI 까지 만드는데 성공 했으나 이걸 MVVM 이랑 엮으면서 코드를 작성 하려다 보니 꽤나 힘들더군요

 

기존에 쓰던 DataBinding 과 다르다 보니 여러 글들을 참고해서 저만의 방식으로 만들기는 하였으나 아직 많이 부족한거같더군요

 

그래도 이렇게 한번 고생을 해서 만들다 보니 어느정도 감이 잡히기는 하더군요

 

이 글을 보시는 분들이시라면 직접 작성해보시면서 경험을 하는것도 나쁘지는 않을거같습니다.

 

긴글 읽어주셔서 감사합니다. 

 

(현재로서 전체 소스는 github 에 올릴수는 없고 토이프로젝트가 마무리되는대로 올리겠습니다.)

반응형

'Android' 카테고리의 다른 글

Android Compose GlideImage  (0) 2024.04.23
Android NDK 란?  (0) 2022.08.08
Android Compose 적용 해보기 1  (0) 2022.06.24
Android Compose 관하여  (0) 2022.06.17
Android MVVM 아키텍처 패턴에 관하여 2  (0) 2022.06.14