본문 바로가기

TIL

[TIL] ViewBinding, you need to use a theme.appcompat theme에러

[오늘 배운 내용]

-1- ViewBinding

  • ViewBinding이란?
    • UI와 상호작용하는 코드를 결합하여서 코드를 더욱 쉽게 작성할 수 있게 해주는 기능.
    • findViewById는 null 안정성이 보장되지 않지만, ViewBinding은 각 Layout.xml 파일에 결합 클래스를 생성하고, 바인딩 클래스의 인스턴스에 상응하는 Layout내의 id가 지정된 모든 view(Layout내의 객체)의 직접 참조가 포함되어 문제 해결가능
    • viewBinding은 연결된 Layout에 존재하는 view만을 가져올 수 있는데, findViewById는 연결되지 않은 Layout의 view를 가져와도 컴파일 상에서는 오류가 발생하지 않지만, 런타임 시 오류가 발생한다.
    • 자동으로 형변환을 해준다.
      • 액티비티.kt
        • activity_test.xml → ActivityTestBinding
      • 뷰의 아이디 가져오기 
        • textview_test → 뷰바인딩객체.textviewTest
  • 적용방법
    • 안드로이드 버전 3.6 이상부터 지원하며, 3.6 ~ 4.0 버전의 설정법과 4.0 이후 버전의 설정법이 상이하니 주의.
    • buildgradle(module :app)의 android{}내부에 Android Studio 버전에 맞는 코드만 기입하면 된다.
android{
	...
    
    // Android 3.6 ~ 4.0
    viewBinding{
    	enabled = true
    }
    
    // Android 4.0 ~
    buildFeatures{
    	viewBinding = true
    }
}

  • builg.gradle.kts(Module : app) 으로 이동 후 각각 버전마다의 코드 추가 후 상단 알림바의 sync now 눌러 적용

 

 

  • 사용방법
    • viewBinding 적용이되면 모듈에 포함된 Layout xml 파일은 모두 Binding 클래스가 생성되며, 해당 클래스를 onCreate 전에 변수 선언해줌으로 액티비티 전역에서 사용할 수 있도록 해주자.
    • 레이아웃 정보가 클래스로 만들어지기 때문에 해당 클래스를 통해서 만들어진 객체를 담을 수 있는 변수를 생성한다. 액티비티별로 다른 viewBinding변수에 xml Activity를 지정해주기 위해서 private lateinit var으로 변수를 생성해 주었다.
class TestActivity : AppCompatActivity() {
    private lateinit var viewBinding : ActivityTestBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        viewBinding = ActivityTestBinding.inflate(layoutInflater)
        val view = viewBinding.root
        setContentView(view)

        viewBinding.textviewTest.text="안녕 코틀린"

    }
}
  • 그다음, 변수로 선언해둔 viewBinding을 inflate로 객체화 시키자
    • Inflate란 xml에 표기된 레이아웃들을 메모리에 로딩한 후 객체화 시키는 과정
    • 이후에 setContentVIew()가 없는 Fragment에서 Inflate에 대해 자세히 다룰 예정이다.
  • 객체화가 된 viewBinding객체는 id가 있는 뷰들과 root 뷰에 대해 각각 타입이 맞는 View 객체를 프로퍼티로 갖고 있게 된다. 따라서 viewBinding 객체를 통해 id가 있는 View들과 root 뷰에 접근이 가능하다
  • viewBinding.root 를 변수에 담아서 해당 변수를 통해 setContentView로 뷰가 보이게끔 작성했다.

 

  • View에 접근하는 방법.
    • viewBinding.id(camelCase로 형변환) 으로 view에 접근할 수 있다

 

 

 

 

 

 


 

[오늘 복습한 내용]

1. 가변인자

// 가변 인자는 함수를 정의할 때 하나의 입력변수
// 여러 개의 인자를 전달할 수 있는 것
// 가변 인자를 사용하는 방법은 함수를 정의할 때 가변 인자를 사용할 입력 변수앞에 'vararg'키워드
// 가변 인자는 함수 구현부에서 배열처럼 사용할 수 있다.

// ↓ --------------- 에러 ---------------↓
// fun error (a:Int,b:Int,c:Int,d:Int,e:Int)
// 인자는 4개를 넘게 받을 수 없기 때문

fun plusmany(vararg inNum: Int) { // 가변 인자 사용
    var total = 0 // 초기값 설정
    for (num in inNum) { //반복문 for 사용해서 inNum의 모든 값을 total에 더하는 함수
        total += num
    }
    println(total) // 출력
}

fun main() {
    val intArr = intArrayOf(3,4,5) // 배열을 생성하는 함수
    plusmany(inNum = *intArr) // 스프레드 연산자 = 배열을 가별인자로 전달할 때 사용
// print 출력 : 12
}

// + 모든 기본 인자의 값을ㄹ 기존 기본 인자와 다르게 주는 경우가 아니라면,
//   └ 일반 인자 -> 가변 인자 -> 기본 인자 순으로 정의하면 짧은 코드로 사용 가능

 

2. 어제 오류 났던 내용

  • material_dynamic_neutral10~1000 등의 background 시스템 매개변수들은 사용자가 이용하도록 만든 툴이 아니라고 한다...? 그래서 오류가 났던 거였다

 

 


[오류,에러 등등]

1. you need to use a theme.appcompat theme에러 - 앱이 실행되자마자 꺼짐

 

  • 어제도 컴파일 오류 없이 앱이 실행되자마자 꺼지는 현상이 있었는데, 오늘도 앱이 실행되자마자 꺼지는 현상이 나타났다
  • 혼자 장시간 또 붙들고 있었는데 시간이 더 소요될 것 같아서 지난주에 함께 했던 팀원에게 도움을 요청했다. 팀원분과 어제 있었던 오류와 오늘 생긴 오류에 대해서 같이 얘기하고 팀원의 도움덕에 문제를 해결할 수 있었다.
  • 오류 내용 Logcat
    • java.lang.illegalstateexception: you need to use a theme.appcompat theme (or descendant) with this activity.

  • themes 에 오류가 있다고 알려주었는데, themes.xml 에는 별다른 오류가 확인되지 않았다.

  • build.gradle의 dependencies에도 material이 정상적으로 있는 모습

 

  • 해결방법
    • 다른 프로젝트와 themes.xml 을 비교해서 코드를 변경해보았다

  • themes.xml 의 Material.Light.NoActionBar 부분에서 Material3로 바꾸고 실행해보니 정상적으로 실행이 되더라
  • themes.xml 을 건드린 적이 없는데 new project로 생성한 themes.xml과 내용이 달랐고, 컴파일 에러도 없던 부분이 문제였다는 것을 알아내고, 해결하고 나니 기분은 좋았지만 황당했다

 

 


[느낀 점]

1. 벌써부터 오류가 여기저기서 튀어나오는데 오류를 해결하려면 로그캣을 잘 확인해야한다.

 

2. 오류가 있는 것을 모르고 방치하다가 나중에 알게되면 찾기가 더 어려워 질 것 같다 . 예상하지 못한 오류가 많으니까 코딩을 하는 중간중간에 계속 확인하는 습관을 들여야 겠다. 

 

3. 틈틈이 영어 공부해야겠다...

 

 


[Reference]

 

 

https://stackoverflow.com/questions/57117338/how-to-use-view-binding-in-android

https://gus0000123.medium.com/android-databinding-%EC%82%AC%EC%9A%A9%EB%B2%95-9a3480a3bfc7

https://developer.android.com/topic/libraries/view-binding?hl=ko 

https://cbs5295.medium.com/android-view-binding-ea7a8e71087f

https://dev-cini.tistory.com/29