이 게시물은 다음 링크를 참조하여 학습했습니다.
공부를 계속 하면서 최근에 코틀린을 공부하기 시작했다.
코틀린을 사용하면서, 기존에 사용했던 MVC패턴에서 디자인 패턴을 MVVM패턴으로 바꾸려고 공부를 하고 있는데,
뭐부터 공부해야 할지 감을 못잡다가 최근에 감을 잡아서 그 내용들을 작성하고자 한다.
뷰 바인딩은 MVVM에 관련된 첫 게시물이다.
1. 뷰 바인딩?
일반적으로 안드로이드를 처음 접할 때, 아래와 같은 방법으로 많이 했을 것이다.
1
2
3
4
5
6
7
8
9
10
11
12
|
public class MainActivity extends AppCompatActivity {
private TextView tv_test;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_test = findViewById(R.id.tv_test);
}
}
|
cs |
뷰 바인딩에 대해 몰랐을 때는 당연하기도 했고, id와 TextView 클래스를 연결하는 코드가 직관적이라고 생각했다.
하지만 한 화면에서 많은 양의 뷰를 담고 있을 때를 생각해보자.
예를 들어, 한 화면에 100개의 TextView가 있다면 우리는 findViewById를 100번을 입력해주어야 할 것이다.
View Binding은 이러한 findViewById 를 대체할 수 있다.
그렇다면 왜 View Binding을 사용할까?
Android 공식문서에서 설명하는 View Binding과 findViewByID의 차이점은 다음과 같다.
1. Null 안정성 : 사용자가 유효하지 않은 ID, 즉 findViewByID에 null 값이 들어갈 때의 오류를 피할 수 있다.
2. Type 안정성 : 사용자가 잘못된 클래스를 ID와 연결했을 때의 오류를 피할 수 있다.
2. 사용법
2-1. gradle 추가
모듈 수준 gradle( build.gradle(Module: 프로젝트명) )에서 다음 항목을 추가 시켜준다.
안드로이드 버전이 4.0 이상일 때
1
2
3
4
5
6
|
android {
...
buildFeatures {
viewBinding = true
}
}
|
cs |
안드로이드 버전이 3.6 ~ 4.0 일때
1
2
3
4
5
6
|
android {
...
viewBinding {
enabled = true
}
}
|
cs |
2-2. Activity에서의 사용
뷰 바인딩을 할 때 자동적으로 생성되는 클래스의 이름은 xml파일의 이름을 카멜 표기법으로 바꾸고 끝에 Binding을 붙힌 것과 같다.
예를 들어 레이아웃 파일 이름이 result_profile.xml일 때 다음과 같다.
1
2
3
4
5
6
7
|
<LinearLayout ... >
<TextView android:id="@+id/name" />
<ImageView android:cropToPadding="true" />
<Button android:id="@+id/button"
android:background="@drawable/rounded_button" />
</LinearLayout>
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
|
private lateinit var binding: ResultProfileBinding
override fun onCreate(savedInstanceState: Bundle) {
super.onCreate(savedInstanceState)
binding = ResultProfileBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
binding.name.text = viewModel.name
binding.button.setOnClickListener { viewModel.userClicked() }
}
|
cs |
1. 생성된 바인딩 클래스에 inflate()메서드를 호출한다. -> 액티비티에서 사용할 바인딩 클래스 인스턴스 생성(xml의 뷰 객체화)
2. getRoot() 메서드를 호출하거나 Kotlin 속성 구문 root를 사용하여 루트 뷰를 가져온다.
3. setContentView()를 이용해 루트 뷰를 넘겨준다.
4. 생성한 바인딩 클래스의 뷰를 사용한다.
2-3. Fragment에서의 사용
1
2
3
4
5
6
7
|
<LinearLayout ... >
<TextView android:id="@+id/name" />
<ImageView android:cropToPadding="true" />
<Button android:id="@+id/button"
android:background="@drawable/rounded_button" />
</LinearLayout>
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
private var _binding: ResultProfileBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
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 onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.name.text = viewModel.name
binding.button.setOnClickListener { viewModel.userClicked() }
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
|
cs |
1. 생성된 바인딩 클래스에 inflate()메서드를 호출한다. -> 프레그먼트에서 사용할 바인딩 클래스 인스턴스 생성(xml의 뷰 객체화)
2. getRoot() 메서드를 호출하거나 Kotlin 속성 구문 root를 사용하여 루트 뷰를 가져온다.
3. setContentView()를 이용해 루트 뷰를 넘겨준다.
4. 생성한 바인딩 클래스의 뷰를 사용한다.
이때 프래그먼트는 뷰보다 오래 지속되므로 onDestroyView() 메서드에서 인스턴스를 정리해줘야 한다.
사실 프래그먼트가 뷰보다 오래 지속된다고 왜 인스턴스를 정리해줘야 되는지 잘 모르겠는데 더 찾아보고 확실히 이해되면 내용을 추가해야겠다.
3. viewBindingIgnore
이 내용은 데이터바인딩과 관련된 내용인것 같다.
뷰바인딩의 경우 gradle에서 뷰바인딩을 설정하면 모든 xml에 적용되는데, 뷰를 건드릴 일이 없을 때(즉, 뷰바인딩이 필요 없을 때) 아래와 같이 입력하면 된다.
1
2
3
4
5
6
|
<LinearLayout
...
tools:viewBindingIgnore="true" >
...
</LinearLayout>
|
cs |
'Legacy' 카테고리의 다른 글
[안드로이드 스튜디오 정리#15] View Model, Live Data (0) | 2022.01.21 |
---|---|
[안드로이드 스튜디오 정리#14] Data Binding (0) | 2022.01.19 |
[안드로이드 스튜디오 독학#45] SAFE HIP_홈화면(Home) (0) | 2021.12.24 |
[안드로이드 스튜디오 독학#44] SAFE HIP_메인화면(Main) (0) | 2021.12.24 |
[안드로이드 스튜디오 독학#43] SAFE HIP (0) | 2021.12.21 |