72일차(3)/Android App(19) : View Binding
step08viewbinding 모듈 생성
MainActivity
package com.example.step08viewbinding;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
import com.example.step08viewbinding.databinding.ActivityMainBinding;
/*
view binding 사용하는 방법
1. build.gradle 파일에 설정(추가)
buildFeatures {
viewBinding = true
}
2. build.gradle 파일의 우상단 sync now 버튼 눌러서 실제로 반영되도록 한다.
3. layout xml 문서의 이름을 확인해서 자동으로 만드는 클래스명을 예측한다.
예를들어 activity_main.xml 문서이면 ActivityMainBinding 클래스
예를들어 activity_sub.xml 문서이면 ActivitySubBinding 클래스...
*/
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
//ActivityMainBinding 객체의 참조값을 담을 필드
ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main); //바인딩을 사용할때는 이렇게 사용하지 않는다.
//activity_main.xml 문서에 전개된 EditText, Button, TextView의 참조값 얻어오는 방법1
/*EditText editText=findViewById(R.id.editText);
Button button=findViewById(R.id.button);
TextView textView=findViewById(R.id.textView);
*/
//activity_main.xml 문서에 전개된 EditText, Button, TextView의 참조값 얻어오는 방법2
/*ActivityMainBinding binding=ActivityMainBinding.inflate(getLayoutInflater());
EditText editText=binding.editText;
Button button=binding.button;
TextView textView=binding.textView;
*/
/*
예를 들어 EditText에 문자열을 입력하고 버튼을 누르면 입력한 문자열이
TextView로 이동하도록 프로그래밍 한다면 아래와 같은 코딩이 된다.
*/
//바인딩 객체의 참조값을 얻어와서 필드에 저장
binding=ActivityMainBinding.inflate(getLayoutInflater());
//바인딩 객체가 리턴해주는 View를 이용해서 화면 구성하기
setContentView(binding.getRoot());
//버튼에 리스너 등록하기
binding.button.setOnClickListener(this);
}
@Override
public void onClick(View view) {
//EditText 객체에 입력한 문자열 읽어오기
String msg=binding.editText.getText().toString();
//TextView에 출력하기
binding.textView.setText(msg);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<EditText
android:id="@+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="35dp"
android:ems="10"
android:inputType="textPersonName"
android:minHeight="48dp"
android:text="Name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="35dp"
android:text="Button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/editText" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="18dp"
android:layout_marginTop="114dp"
android:text="TextView"
app:layout_constraintStart_toStartOf="@+id/button"
app:layout_constraintTop_toBottomOf="@+id/button" />
</androidx.constraintlayout.widget.ConstraintLayout>
- plaintext, 버튼, textview 추가
- UI의 참조값을 그냥 findViewById() 로 찾아오는 방법을 지금까지 사용했는데
이게 조금... 느리다고 한다.. 느낄 정도는 아니지만..?
- 다른방법을 사용해볼 예정! View binding 사용방법
- build.gradle 파일로 들어가기
- Maven의 pom.xml과 비슷한 파일. 설정/의존 디펜던시를 관리한다.
- 내용 적고 우상단 Sync now 버튼으로 싱크시키기
- 저 버튼을 누르거나 아니면 File-Sync Project 하면 된다.
buildFeatures {
viewBinding = true
}
- 이 내용을 위 이미지의 위치에 넣어준다.
- 그러면 자동으로 ActivityMainBinding 이라는 클래스가 만들어진다.
- 이렇게 ActivityMainBinding 클래스가 자동으로 만들어진 것을 확인할 수 있다.
- 이것을 ViewBinding 타입으로 받는다!
- 각각의 필드에 이렇게 각 요소의 참조값이 들어가있다.
- 좀더 안전하게 UI의 참조값을 얻어오는 방법이다. 안드로이드에서는 이것을 권장하는 쪽!
- 어쨌든 둘다 알고있어야 한다.ㅎㅎ
- 버튼에 리스너등록 → editText 참조값으로 값읽어오기 → textView에 넣어주기
- binding 을 필드로 만들어 두었으므로 그냥 점 찍어서 가져오기
- findViewById로 참조값을 얻어와서 필드에 넣는 대신 이렇게 쓸 수 있다.
- 아래에서 editText, textView 도 그대로 binding에 점찍어서 접근한다.
- run했을때 gradle 설정때문에 오류가 발생한다면...
저번에 했던대로 compileSdk를 32 -> 33 으로 수정하기!
- 이 방식으로 참조값을 얻어올 때는 setContentView는 지운다.
//바인딩 객체의 참조값을 얻어와서 필드에 저장
binding=ActivityMainBinding.inflate(getLayoutInflater());
//바인딩 객체가 리턴해주는 View를 이용해서 화면 구성하기
setContentView(binding.getRoot());
- 이렇게 필드에 값을 저장한 후, getRoot() 메소드로 화면을 구성한다.
- new-fragment로 빈 프래그먼트 추가!
BlankFragment
package com.example.step08viewbinding;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.fragment.app.Fragment;
import com.example.step08viewbinding.databinding.FragmentBlankBinding;
/**
* A simple {@link Fragment} subclass.
* Use the {@link BlankFragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class BlankFragment extends Fragment {
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private String mParam1;
private String mParam2;
public BlankFragment() {
}
public static BlankFragment newInstance(String param1, String param2) {
BlankFragment fragment = new BlankFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
//바인딩 객체를 저장할 필드
FragmentBlankBinding binding;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// view binding을 이용하려면 아래와 같이 코딩해야 한다.
//fragment_black.xml문서 => FragmentBlankBinding 클래스
binding=FragmentBlankBinding.inflate(inflater,container,false);
View view=binding.getRoot();
//만일 fragment_blank.xml 문서에 myTextView라는 아이디를 가지고있는 TextView의 참조값이 필요하다면
TextView a= binding.myTextView; //이렇게 참조하면 된다.
return view;
}
// fragment가 레이아웃으로 가지고있는 뷰가 파괴될때 호출되는 메소드
@Override
public void onDestroyView() {
super.onDestroyView();
//FragmentBlankBinding 객체의 참조를 해제해서 메모리를 효율적으로 사용하도록 한다.
binding=null;
//프래그먼트보다 뷰가 더 오래 살아남기 때문에 프래그먼트는 사용되지 않는데
//뷰만 메모리에 남아있는 것을 방지하는 효과가 된다.
}
}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".BlankFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="hello"
android:id="@+id/myTextView" />
</FrameLayout>
- 이 xml문서를 전개해서 view를 만들어서 view를 리턴해야하는데,
뷰 바인딩을 사용하면 방법이 좀 달라진다.
- fragment_blank.xml 문서 => FragmentBlankBinding 클래스
- xml 문서 하나당 이 클래스가 자동으로 generate 된다.
- inflate를 사용하는 방식. 위, 아래의 작성방법을 비교하기!
- 만약 저 xml문서안에 id가 부여된 UI가 있다면 binding 을 통해서 접근할 수 있다.
→ 필드에 값을 저장할 필요가 있다!
- 마지막에 onDestroyView() 메소드로 binding을 해제해주어야 한다. 메모리를 효율적으로 사용하기 위해!
- 프래그먼트보다 뷰가 더 오래 살아남기 때문에 프래그먼트는 사용되지 않는데,
View 만 메모리에 남아있는 것을 방지하는 효과가 된다.
- 이렇게 binding을 통해 UI의 참조값을 가져올 수 있다.
- 이것은 fragment_blank.xml 에 들어있는 textView인데
만약 이 UI에 접근하고자 한다면 이런식으로 접근하면 된다.
- 이전에 참조값을 얻어오던 방식과 똑같이 작동한다.
'국비교육(22-23)' 카테고리의 다른 글
72일차(5)/Android App(21) : View 로 미니 슈팅게임 만들기(1) (0) | 2023.01.19 |
---|---|
72일차(4)/Android App(20) : Custom View (0) | 2023.01.19 |
72일차(2)/Android App(18) : Fragment(2), Fragment Lifecycle (0) | 2023.01.18 |
72일차(1)/Android App(17) : Kotlin에서 java 클래스 사용, Lambda 표현식 (0) | 2023.01.18 |
71일차(2)/Android App(16) : Fragment(1) (1) | 2023.01.18 |