2020년 7월 15일 수요일

안드로이드 프래그먼트로 화면 만들기



* 프래그먼트(Fragment) 로 화면 만들기

프래그먼트를 이용해서 각 버튼을 클릭시 이미지가 변경되도록 해보자.
즉 한 화면에 두 개의 프래그먼트가 들어가게 된다.
하나는 버튼으로만 구성되어 있는 프래그먼트, 다른 하나는 이미지를 볼수 있는 프래그먼트이다.
위쪽 프래그먼트에서 선택한 이미지가 어떤 것인지를 액티비티에 알려준 후 액티비티에서 아래쪽 프래그먼트에 해당 이미지가 보이게 만들어야 한다.


* fragment_list.xml - 버튼들만 가지고 있는 위쪽 레이아웃

버튼 세개를 넣었으며, 각 버튼마다 이미지가 다르게 나타나도록 할 것이다.


* ListFragment.java

화면에서 선택된 버튼에 따라 다른 프래그먼트의 이미지를 바꿔주려면 액티비티 쪽으로 데이터를 전달해야만 한다.


    package org.techtown.fragment;

import android.content.Context;
import android.media.Image;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

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

public class ListFragment extends Fragment {

    /**
     * ImageSelectionCallback 인터페이스를 정의함
     * 메인액티비티가 이 인터페이스를 구현하게 되면 프래그먼트의 각 버튼이 눌릴 때
     * 메인액티비티의 onImageSelected를 호출하게 된다.
     */
    public static interface ImageSelectionCallback{
        public void onImageSelected(int position);
    }
    public ImageSelectionCallback callback;

    /**
     * 프래그먼트가 액티비티 위에 올라오는 시점에 호출되는 메서드
     * @param context : 이 프래그먼트가 올라가는 액티비티를 말한다.
     */
    @Override
    public void onAttach(Context context){
        super.onAttach(context);
        // 메인엑티비티가 ImageSelectionCallback 인터페이스를 구현했으므로
        // context(메인엑티비티) 는 ImageSelectionCallback로 형변환이 가능하다.
        if(context instanceof ImageSelectionCallback){
            callback = (ImageSelectionCallback) context;
        }
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState){

        ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_list, container, false);

        //각각의 버튼을 클릭했을 떄 callback객체의 onImageSelected()메서드를 호출한다.
        Button button = rootView.findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(callback != null){
                    callback.onImageSelected(0);
                }
            }
        });
        Button button2 = rootView.findViewById(R.id.button2);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(callback != null){
                    callback.onImageSelected(1);
                }
            }
        });

        Button button3 = rootView.findViewById(R.id.button3);
        button3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(callback != null){
                    callback.onImageSelected(2);
                }
            }
        });

        return rootView;
    }
}

    



* fragment_viewer.xml - 이미지를 보여주는 아래쪽 레이아웃



ImageView 안드로이드 개발툴 이미지
LinearLayout에 ImageView를 세팅하고 첫번째 이미지를 설정해둔다.


* ViewerFragment.java

ViewerFragment는 이미지를 보이게 하는 프래그먼트이다. 
액티비티에서 이 프래그먼트의 setImage를 하면 해당 이미지로 바뀌게 된다.

package org.techtown.fragment;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

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

public class ViewerFragment extends Fragment {
    ImageView imageView;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        
        ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_viewer, container, false);
        
        imageView = rootView.findViewById(R.id.imageView);
        return rootView;
    }
    
    public void setImage(int resId){
        imageView.setImageResource(resId);
    }
}


* activity_main.xml

메인엑티비티에 아래와 같이 ListFragment와 ViewerFragment를 동일한 화면비중을 차지하도록 설정하도록 만든다.




* MainActivity.java

package org.techtown.fragment;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentManager;

import android.os.Bundle;

//MainActivity는 ListFragment.ImageSelectionCallback를 구현한다.
public class MainActivity extends AppCompatActivity implements ListFragment.ImageSelectionCallback{

    ListFragment listFragment;
    ViewerFragment viewerFragment;

    int[] images = {R.drawable.dream01,R.drawable.dream02,R.drawable.dream03};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //프래그먼트매니저를 이용해 두 개의 프래그먼트 객체들을 변수에 할당한다.
        FragmentManager manager = getSupportFragmentManager();
        listFragment = (ListFragment) manager.findFragmentById(R.id.listFragment);
        viewerFragment = (ViewerFragment) manager.findFragmentById(R.id.viewerFragment);
    }

    /**
     * ListFragment에서 버튼이 클릭될때 메인엑티비티에 구현된 onImageSelected을 호출하게 되고
     * viewerFragment의 setImage를 호출함으로써 프래그먼트의 이미지를 변경하도록 한다.
     * @param position
     */
    @Override
    public void onImageSelected(int position) {
        viewerFragment.setImage(images[position]);
    }
}





* 결과 

실행해보면 버튼을 클릭할 때마다 이미지가 바뀌게 된다.