프래그먼트를 화면에 어떻게 추가하는지 살펴보았습니다.
하지만 한 화면에 여러 개의 프래그먼트를 넣고 프래그먼트들 간에 데이터를 전달하는 과정은 생각보다 복잡하게 느껴질 수 있습니다.
따라서 직접 만들어보는 것이 필요합니다.
왼쪽에 이미지 리스트가 보이고 오른쪽에 이미지가 보이는 화면을 두 개의 프래그먼트로 만들려면 어떻게 해야 할까요?
그리고 왼쪽의 리스트에서 한 아이템을 선택하면 오른쪽에 그 아이템의 이미지가 보이게 하려면 어떻게 할까요?
두 개의 프래그먼트가 들어간 이미지뷰어를 어떻게 만들 수 있는지 알아봅시다.
두 개의 프래그먼트
한 화면에 두 개의 프래그먼트가 들어가 있도록 만들려면 먼저 액티비티의 XML 레이아웃에 <fragment> 태그를 이용해 두 개의 프래그먼트를 넣어줍니다.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<fragment
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:name="org.techtown.fragment.ListFragment"
android:id="@+id/listFragment"
/>
<fragment
android:layout_width="match_parent"
android:layout_height="0dp "
android:layout_weight="1"
android:name="org.techtown.fragment.ViewerFragment"
android:id="@+id/viewerFragment"
/>
</LinearLayout>
이렇게 하면 화면의 위쪽에 하나의 프래그먼트, 아래쪽에 하나의 프래그먼트가 보이게 됩니다.
위쪽에 추가된 프래그먼트는 ListFragment라는 클래스를 가리키고 있으며 ListFragment라는 이름의 프래그먼트는 새로 정의합니다.
그 안에 리스트뷰가 들어가도록 말이죠.
아래쪽에 추가된 프래그먼트는 ViewerFragment 라는 클래스를 가리키고 있으며 이 프래그먼트도 새로 정의합니다.
그 안에는 이미지뷰가 들어가도록 합니다.
프래그먼트에서 액티비티의 메소드 호출
리스트뷰가 들어가 있는 프래그먼트에서 한 아이템을 선택하면 해당 아이템의 이미지를 이미지뷰가 들어가 있는 프래그먼트에 보여주어야 합니다.
그런데 하나의 프래그먼트에서 다른 프래그먼트로 직접 접근할 수 없으므로 시스템 역할을 하는 액티비티를 통해 명령이나 데이터를 전달해야 합니다.
프래그먼트는 메소드 호출 방식을 사용하게 되며 먼저 리스트 프래그먼트에서 액티비티의 메소드를 호출해야 합니다.
액티비티의 메소드를 호출할 때는 프래그먼트가 어떤 액티비티 위에 올라가더라도 프래그먼트의 소스가 변경되지 않도록 인터페이스를 정의하여 사용합니다.
ImageSelectionCallback 인터페이스를 정의했다면 이 인터페이스는 액티비티에서 구현하도록 하고 프래그먼트에서 이 인터페이스에서 정의한 메소드를 호출하도록 합니다.
public class ListFragment extends Fragment {
중략...
public static interface ImageSelectionCallback {
public void onImageSelected(int position);
}
public ImageSelectionCallback callback;
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof ImageSelectionCallback) {
callback = (ImageSelectionCallback) context;
}
}
프래그먼트는 액티비티 위에 올라갈 때 onAttach 메소드가 자동으로 호출되도록 만들어져 있으므로 onAttach 메소드가 호출되는 시점에 액티비티를 참조할 수 있습니다.
이 액티비티가 인터페이스를 구현하고 있다면 액티비티 객체를 변수에 할당합니다.
그리고 필요할 때 호출할 수 있습니다.
액티비티에서 프래그먼트의 메소드 호출
리스트 프래그먼트에서 액티비티의 메소드를 호출하면 액티비티에서는 이미지 프래그먼트의 메소드를 호출할 수 있습니다.
액티비티에 변수를 선언하고 프래그먼트 객체를 할당해두면 리스트 프래그먼트 객체나 이미지 프래그먼트 객체를 항상 참조할 수 있게 되며 액티비티의 메소드가 호출되었을 때 이미지 프래그먼트의 메소드를 호출함으로써 이미지를 변경할 수 있습니다.
public class MainActivity extends AppCompatActivity implements ListFragment.ImageSelectionCallback {
ListFragment listFragment;
ViewerFragment viewerFragment;
중략…
@Override
public void onImageSelected(int position) {
viewerFragment.setImage(images[position]);
}
}
액티비티에서 프래그먼트의 메소드를 호출할 때는 인터페이스를 사용할 필요가 없습니다.
최근댓글