카테고리 보관물: Android

Android ROOM in 조건 변수 사용

개요

Android ROOM 사용 시 변수를 넘겨서 조건으로 사용하는 경우가 많습니다. 단순한 조건이나 개수가 많지 않은 경우 and 나 or 연산자로 충분합니다. 그러나 비교해야 하는 대상이 많아지게 되면 or 조건으로 나열하는 것이 쉽지 않습니다. 그래서 in 연산자로 대상을 나열해서 조건식으로 적용하게 됩니다. 이번글에서는 Andorid ROOM in 조건 변수 사용 방법을 알아보도록 하겠습니다.

전달변수

다음 코드와 같이 변수를 넘겨서 조건식에 들어가도록 합니다.

@Query("SELECT * FROM your_table where data_type = :dataType")
fun getYourData(dataType:String): YourClass

그러면 변수를 문자열 형태로 ‘A’, ‘B’, ‘C’ 이렇게 조합해서 전달하면 되지 않을까 생각할 수 있습니다.

@Query("SELECT * FROM your_table where data_type in (:dataTypeCondition)")
fun getYourData(dataTypeCondition:String): YourClass

그러면 최종적으로 다음과 같은 명령어로 해석된다고 예상할 수 있습니다.

SELECT * FROM your_table where data_seq in ('A', 'B', 'C')

그러나 이렇게 하면 원하는 결과가 나타나지 않습니다.

올바른 방법

변수를 하나의 문자열로 생각하지 않고 문자열 배열이나 ArrayList 형태로 전달해야 합니다. 아래코드에서는 ArrayList 형태로 전달했습니다. dataTypeCondition 변수에 원하는 조건을 다음과 같이 add 로 추가한 후 전달하면 됩니다.

dataTypeCondition.add("A")
dataTypeCondition.add("B")
dataTypeCondition.add("C")
@Query("SELECT * FROM your_table where data_type in (:dataTypeCondition)")
fun getYourData(dataTypeCondition:ArrayList<String>): YourClass

위와 같이 변수를 적용하면 in 조건이 적용된 결과가 반환됩니다.

Android DatePicker Spinner 설정 및 버튼 보이지 않는 문제 해결

개요

앱의 기능에 따라서 날짜를 선택해야 하는 경우가 있습니다. DatePicker 를 사용하면 되는데 기본적으로 달력형태로 나타납니다. 과거의 날짜를 선택해야 하는 경우 달력형태는 여러번 이동해야 해서 적합하지 않습니다. Spinner 형태로 변경하는 방법을 알아보겠습니다. 그리고 DatePicker 가 표시되었을 때 버튼이 보이지 않는 문제도 같이 다루어 보도록 하겠습니다.

DatePicker Spinner 형태로 변경

이 글에서는 DatePicker 를 xml 에 추가하는 형태가 아닌 소스코드에 추가한 경우로 한정해서 알아보도록 하겠습니다. 먼저 코드를 보겠습니다.

viewBinding.button.setOnClickListener {
    val dialog = DatePickerDialog(
        this,
        datePickerListener,
        yearForDatePicker,
        monthForDatePicker - 1,
        dayForDatePicker
    )
    dialog.show()
    dialog.datePicker.spinnersShown = true
    
datePickerListener = DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth ->
    yearForDatePicker = year
    monthForDatePicker = monthOfYear + 1
    dayForDatePicker = dayOfMonth
    viewBinding.textViewSettingSelectBirthday.text = setDate(this, yearForDatePicker, monthForDatePicker, dayForDatePicker)
}

10 행의 spinnersShown 메소드가 deprecated 되었다고 메시지가 나타납니다. deprecated 된 메소드를 사용하지 않는 것을 원칙으로 해서 다른 방법으로 spinner 형태로 나타나도록 하겠습니다.

values/theme.xml 파일에 다음과 같이 추가합니다.

<resources xmlns:tools="http://schemas.android.com/tools">
    <style name="Theme.LifeClock" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
        <item name="colorPrimary">@color/primaryColor</item>
        <item name="colorPrimaryDark">@color/primaryDarkColor</item>
        <item name="colorAccent">@color/accentColor</item>
        <item name="colorOnPrimary">@color/primaryTextColor</item>
        <item name="android:datePickerStyle">@style/CustomDatePicker</item>
    </style>
    <style name="CustomDatePicker">
        <item name="android:datePickerMode">spinner</item>
    </style>
</resources>

7, 9~11 행을 추가합니다. 앱을 실행하고 버튼을 터치해보면 Spinner 형태의 달력이 나타나는 것을 확인할 수 있습니다.

Spinner 형태로 나타난 DatePicker

버튼이 보이지 않는 문제

그런데 대화상자의 아래쪽에 공백이 많고 있어야 할 확인, 취소 버튼이 보이지 않는 것을 알 수 있습니다. 테마와 관련해서 나타난 현상인 것으로 추측되는데 글자의 색상이 대화상자의 배경색과 동일해서 보이지 않게 된 것입니다. 대화상자의 아래쪽을 터치해 보면 버튼 자체는 동작한다는 것을 알 수 있습니다.

테마쪽 부분을 변경해 보았으나 버튼이 보이지 않는 문제가 해결되지 않았습니다. 결국 다음의 코드를 추가해서 보이게 되도록 했습니다.

viewBinding.button.setOnClickListener {
    val dialog = DatePickerDialog(
        this,
        datePickerListener,
        yearForDatePicker,
        monthForDatePicker - 1,
        dayForDatePicker
    )
    dialog.show()
    dialog.getButton(DatePickerDialog.BUTTON_NEGATIVE).setTextColor(resources.getColor(R.color.accentColor, theme))
    dialog.getButton(DatePickerDialog.BUTTON_POSITIVE).setTextColor(resources.getColor(R.color.accentColor, theme))
}
CANCEL, OK 버튼이 정상적으로 나타난 모양

10, 11 행 코드를 추가할 때 주의할 사항은 dialog.show() 이후에 추가해야 정상적으로 나타납니다. 대화상자의 긍정, 부정 버튼의 참조를 가져와서 바로 글자 색상을 적용한 것으로 이해하면 됩니다.

이번 글에서는 DatePicker 의 스타일을 Spinner 형태로 변경하고 하단의 버튼이 나타나지 않는 문제에 대해서 다루어 보았습니다.