반응형

이전 포스트에 이어서 뷰 바이딘에 대한 4번째 예제를 소개하겠습니다.

이전 버터나이프 포스트에서 소개한 바와 같이 실제 앱을 구현하다보면 액티비티에 직접 뷰들을 배치하여 사용하기 보다 화면의 부분별로 별도의 영역(Fragment)으로 나누어 UI를 작업하는 경우가 더 많습니다. 화면구성이 단순하지 않으면 액티비티에 모든 뷰들을 배치하여 관리하기 어렵고 코드도 복잡하기 때문이지요. 그로인해 Fragment를 사용하는 빈도가 아주 높습니다.

그래서 이번에는 Fragment 에서 뷰 바인딩을 사용하여 뷰들을 제어해보겠습니다. 

 

4) 프레그먼트에 뷰바인딩 실습 [ MyFragment.java ]

예제가 복잡하면 정작 뷰바인딩을 사용하는 방법보다 다른 부분을 이해하는 것에 어려움을 느낄 수도 있기에 이전 ButterKnife 라이브러리 실습에서 소개한 것과 마찬가지로 아주 간단하게 실습을 진행하고자 합니다.

보통 프레그먼트를 액티비티에 추가할때는 자바에서 FragmentManager를 이용하여 add하는 방법이 일반적으로 더 많이 사용되지만 실습의 단순화를 위해 액티비티의 xml에 <fragment>태그로 정적추가 하겠습니다.

 

Fragment를 상속하는 MyFragment클래스를 별도의 .java 파일로 만들어 적용해 보겠습니다.

먼저, MyFragment에서 보여줄 레이아웃 xml 파일을 만들어 보겠습니다. 간단하게 구성하기 위해 TextView 1개와 Button 1개만으로 구성하여 버튼을 글릭했을 때 TextView의 글씨를 변경하도록 만들어 보겠습니다.

 

# res / layout / fragment_my.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/black"
    android:padding="16dp">

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="8dp"
        android:textColor="@color/white"
        android:text="This is MyFragment"
        android:textStyle="bold"/>
    <Button
        android:id="@+id/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/tv"
        android:backgroundTint="@color/teal_200"
        android:text="chnage text"
        android:textAllCaps="false"/>

</RelativeLayout>

뷰 바인딩 사용이 설정되어 있기이 layout 폴더에 xml 파일을 만들면 자동으로 레이아웃 파일명을 기반으로 그에 상응하는 바인딩 클래스가 만들어져 있습니다.

여기서는 fragment_my.xml 이라는 이름의 레이아웃파일이 있기에 자동으로 만들어진 바인딩 클래스의 이름은 FragmentMyBinding으로 됩니다. 액티비티의 바인딩과 크게 다르지 않습니다. 이 바인딩 클래스의 멤버필드에는 레이아웃 xml 파일안에 만든 id가 있는 뷰들을 참조하고 있는 참조변수가 id와 같은 이름으로 만들어져 있습니다. 우리는 이 바인딩 클래스 객체의 멤버필드들을 이용하여 별도의 뷰를 찾아 참조하는 findViewById()작업 없이 뷰들을 제어할 수 있습니다. 

다신 언급하지만 레이아웃파일명과 바인딩 클래스의 명명 규칙만 이해하면 그리 어렵지 않게 뷰 바인딩을 사용하실 수 있게 됩니다.

 

fragment_my.xml    --- >   FragmentMyBinding

fragment_aa.xml.   --- >.  FragmentAABinging

 

 

이제 위 레이아웃파일을 보여주고 제어하는 MyFragment.java 를 만들어 보겠습니다. 레이아웃과 연결된 바인딩 클래스 인스턴스를 만드는 부분을 주의 깊게 보시기 바랍니다. 주석으로 설명하였으니 참고바랍니다.

# MyFragment.java
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import com.mrhi2021.ex98viewbinding.databinding.FragmentMyBinding;

public class MyFragment extends Fragment {

    //fragment_my.xml 파일과 연결되어 있는 바인딩 클래스 참조변수
    FragmentMyBinding myBinding;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        //프레그먼트가 보여줄 뷰의 레아아웃 파일인 fragment_my.xml 문서와 연결되도록 뷰바인딩에서 자동으로 만들어지는 바인딩 클래스를 통해 뷰객체 생성(inflate)
        // fragment_my.xml  ---> FragmentMyBiding   [ 바인딩클래스 참조변수는 가급적 이 프레그먼트클래스의 멤버변수에 선언 - 어디서든 불러서 사용할 수 있도록]
        myBinding= FragmentMyBinding.inflate(inflater);
        return myBinding.getRoot(); //프레그먼트가 보여줄 뷰로서 바인딩클래스 객체의 최상위 뷰(rootView : fragment_my.xml의 첫번째 레이아웃 뷰 - 이 예제에서는 RelativeLayout)를 리턴
    }

    //onCreateView()메소드를 통해 프레그먼트가 보유줄 뷰가 만들어진 후 자동으로 실행되는 라이프사이클 콜백메소드
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        //이미 바인딩클래스객체의 멤버변수안에 id와 같은 이름을 가진 뷰참조변수들의 연결되어 있으므로 원하는 코드를 바로 작성
        myBinding.btn.setOnClickListener( v -> myBinding.tv.setText("Have a good day.") );
    }

    //*참고*
    //프레그먼트가 보여주는 뷰들이 Destroy(파괴)되어도 프레그먼트 객체가 살아있을 수 있기에 뷰들이 메모리에서 없어질때 바인딩클래스의 인스턴스도 파괴함으로서 메모리누수를 방지할 수 있음.
    @Override
    public void onDestroyView() {
        super.onDestroyView();

        myBinding=null; //바인딩 객체를 GC(Garbage Collector) 가 없애도록 하기 위해 참조를 끊기.
    }
}

각 코드마다 작성한 주석을 보시면 전체 코드를 이해하실 수 있으실 겁니다.

 

이제 마지막 단계로 위 MyFragment를 MainActivity에 정적으로 추가하도록 하겠습니다. activity_main.xml 파일에 <fragment>태그로 추가만 하면 되기에 MainActivity.java는 특별히 수정할 부분이 없습니다. 곧바로 액티비티의 레이아웃 파일만 소개하겠습니다.

# activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    android:padding="16dp"
    tools:context=".MainActivity">

    <!-- 1) 기본 TextView  -->
    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="8dp"
        android:textColor="#FF333333"
        android:text="Hello"/>

    <!-- 2) 버튼 클릭이벤트 처리하기 -->
    <Button
        android:id="@+id/btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="button"/>


    <!-- 3) EditText의 글씨을 얻어와서 TextView에 보이는 예제실습 [뷰참조와 클릭이벤트 종합 simple 예제]-->
    <EditText
        android:id="@+id/et"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="enter text"
        android:inputType="text"
        android:layout_marginTop="24dp"/>
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="입력완료"
        android:onClick="clickBtn2"/>
    <TextView
        android:id="@+id/tv2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="8dp"
        android:textColor="#FF333333"
        android:text="RESULT"/>


    <!-- 4) Fragment에서 ViewBinding 사용하기 예제 실습 [name속성에 적용한 패키지명은 본인앱의 패키지명으로 수정하여 적용하시기 바랍니다.]  -->
    <fragment
        android:id="@+id/frag"
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:name="com.kitesoft.exviewbinding.MyFragment"
        tools:layout="@layout/fragment_my"
        android:layout_marginTop="24dp"/>
    <!-- tools:layout="@layout/fragment_my" 화면의 한 부분을 담당하는 MyFragment의 모양을 이곳에서 미리보기해주는 속성 -->


</LinearLayout>

만들어 보시면 프레그먼트라고 해서 액티비티와 크게 다르지 않다는 것을 알 수 있으실 겁니다.

 

이제 뷰 바인딩의 마지막 실습으로 실제 앱 구현에 아주 많이 사용되는  RecyclerView 에서 뷰 바인딩을 사용하는 예제를 다음 포스트로 소개하겠습니다. 

반응형

+ Recent posts