본문 바로가기
Android Studio

[Android 앱개발 숙련] 뷰 바인딩 - 개념, 설정방법 (# 추가하기)

by 젼젼39 2024. 4. 9.

1. view binding 개념

    (+) 뷰와 상호작용하는 코드 쉽게 작성 가능

    - 모듈에서 사용 설정된 뷰 바인딩은모듈에 있는 각 XML 레이아웃 파일의 결합 클래스를 생성함 
    - 바인딩 클래스의 인스턴스에는 상응하는 레이아웃에 ID가 있는 모든 뷰의 직접 참조가 포함됨
    - 대부분의 경우, 뷰 바인딩이 findViewById를 대체함

 

* findViewById와의 차이점

1) Null 안전성 (Null Safety)

    : 앱이 레이아웃의 각 뷰를 직접 참조할 수 있게 해주는 안전한 코드를 자동으로 생성해 null 오류(뷰가 아직 화면에 나타나지 않았는데 해당 뷰를 사용하려고 하는 등의 문제들)을 예방함

    - ex. 아직 null인 것을 안전하게 처리 / 레이아웃의 일부만 뷰가 있을 때 널 가능함을 알려줌

2) 타입 안전성 (Type Safety)

    : XML 레이아웃 파일에서 정의된 뷰의 타입과 자동 생성된 바인딩 클래스의 필드 타입이 항상 일치하기 때문에, 타입이 서로 맞지 않아 발생할 수 있는 오류가 방지됨

    -  ex. 이미지 뷰에 텍스트 설정하려는 오류를 막음

 

 

2. 설정방법

1) 모듈에서 뷰 결합을 사용 설정하기 위해 모듈 수준 build.gradle 파일에서 viewBinding 빌드 옵션을 true로 설정하기
    (뷰 바인딩은 모듈별로 사용 설정됨)

anroid{
    ...
    buildFeatures {
        viewBinding = true
    }
}

    //결합 클래스를 생성하는 동안 레이아웃 파일을 무시하려면 tools:viewBindingIgnore="true" 속성을 레이아웃 파일의 루트 뷰에 추가하기

<LinearLayout
        ...
        tools:viewBindingIgnore="true">
    ...
</LinearLayout>

 

 

3. 사용법

    - 모듈에 뷰 결합을 사용 설정 시 모듈에 포함된 각 XML 레이아웃 파일의 결합 클래스가 생성되고, 각 결합 클래스에는 루트 뷰 및 id가 있는 모든 뷰의 참조가 포함됨

    - 결합 클래스 이름은 XML 파일의 이름을 파스칼 표기법으로 변환 + 끝에 Binding 추가해 생성됨

    - 모든 결합 클래스에는 상응하는 레이아웃 파일(ex. LinearLayout)의 루트 뷰 직접 참조를 제공하는 getRoot() 메서드가 포함됨 

 

1) 액티비티에서 뷰 결합 사용 (생성된 결합 클래스를 액티비티와 프래그먼트에서 사용하는 방법...)

    - 액티비티에 사용할 결합 클래스 인스턴스를 설정하려면 액티비티의 onCreate() 메서드에 아래 단계를 적용하기

(1) 생성된 결합 클래스에 포함된 정적 inflate() 메서드 호출해 액티비티에서 사용할 결합 클래스 인스턴스 생성하기

(2) getRoot() 메서드를 호출하거나 Kotlin 속성 문법...?(val var인듯) 을 사용해 루트 뷰 참조를 가져오기

(3) 루트 뷰를 setContentView() 에 전달해 화면의 활성 뷰로 만들기

private lateinit var binding: ResultProfileBinding

override fun onCreate(savedInstanceState: Bundle?){
    super.onCreate(savedInstanceState)
    binding = ResultProfileBinding.inflate(layoutInflater)
    val view = binding.root
    setContentView(view)
}

    // inflate는 xml에 있는 뷰를 객체화해준다고 생각하면 됨
    //  원래는 R.layout.activity_main을 넘겨주지만 이번에는 생성한 루트 뷰를 넘겨줌

    //결합 클래스 인스턴스를 사용해 뷰 참조하기

binding.name.text = viewModel.name
binding.button.setOnClickListener {viewModel.userClicked()}

    //아래와 같이 binding 된 객체 안에 있는 id에 접근해 사용하면 됨

binding.button1.text = "안녕"
binding.button2.setBackGroundColor(Color.BLACK)

 

@@@@액티비티랑 프래그먼트 차이 정리... 추가하기

 

2) 프래그먼트에서 뷰 결합 사용

    - 프래그먼트와 함께 사용할 결합 클래스 인스턴스를 설정하려면 프래그먼트의 onCreateView() 메소드에 다음 단계 추가하기

(1) 생성된 결합 클래스에 포함된 정적 inflate() 메서드 호출해 프래그먼트에서 사용할 결합 클래스 인스턴스 생성하기

(2) getRoot() 메서드 호출하거나 kotlin 속성 문법(var val?)을 사용해 루트 뷰 참조를 가져오기

(3) onCreateView() 메서드에서 루트 뷰를 반환해 화면의 활성 뷰로 만들기

private var _binding: ResultProfileBinding? = null
//이 프로퍼티는 onCreateView와 onDestroyView 사이에서만 valid
private val binding get() = _binding!!

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    _binding = ResultProfileBinding.inflate(inflater, container, false)
    val view = binding.root
    return view
}

override fun onDestroyView() {
    super.onDestroyView()
    _binding = null
}

    //결합 클래스 인스턴스를 사용해 뷰 참조하기

binding.name.text = viewModel.name
binding.button.setOnClickListener { viewModel.userClicked() }

    //inflate() 메서드 사용하려면 레이아웃 인플레이터를 전달해야함.
    //레이아웃이 이미 확장되어 있다면 결합 클래스의 정적 bind() 메서드를 대신 호출할 수 있음. 

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    val binding = FragmentBlankBinding.bind(view)
    fragmentBlankBinding = binding
    binding.textViewFragment.text = getString(string.hello_from_vb_bindfragment)
}

      //프래그먼트는 뷰보다 오래 지속되기 때문에, 프래그먼트의 onDestroyView() 메서드에서 결합 클래스 인스턴스 참조를 정리해야 함

 

4. 예시

- build.gradle (모듈:앱) 에 viewBinding 옵션 true로 설정

- xml 에 textview를 myTextView, btn id를 myButton 으로 설정한 상태

- MainActivity

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

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

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.myButton.setOnClickListener{ 		//이렇게 연결
            binding.myTextView.text = "바인딩이 잘 되네요!" 	//이렇게 연결
        }
    }
}

(위와 동일한 결과를 내는 코드임)

//class MainActivity : AppCompatActivity() {

//    private lateinit var binding: ActivityMainBinding

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

//        binding = ActivityMainBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)

//        binding.myButton.setOnClickListener{ 		//이렇게 연결
//            binding.myTextView.text = "바인딩이 잘 되네요!" 	//이렇게 연결
//        }
//    }
//}

 

 

뷰 결합  |  Android 개발자  |  Android Developers

 

뷰 결합  |  Android 개발자  |  Android Developers

이 페이지는 Cloud Translation API를 통해 번역되었습니다. 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 뷰 결합은 뷰와 상호작용하는 코드를 더 쉽게 작성할

developer.android.com

여기서부터 다시 공부... 추가하기