빠르게배우는 안드로이드 Fragment-4(Fragment간 에 데이터전달)

위 강의에 이어서 진행하겠습니다.

이번시간에는 저번시간에 이어 Fragment에 데이터를 전달해보겠습니다
엑티비티간에 데이터를 전송할때 Intent를 사용했었는데요
Fragment는 Bundle이라는 것을 사용하여 데이터를 전송합니다.
 Intent와 비슷하므로 Intent를 잘 모르신다면 먼저 학습하시는것을 추천합니다.

안드로이드 스튜디오에서 Activity와 Fragment 등을 만들때 기본적인 템플릿을 지원해주는데 Fragment를 도와주는 Template을 보면 기본적인 Bundle을 이용한 코드가 포함되어있습니다. 이 템플릿을 생성하는것부터 시작하여보겠습니다.

새 프로젝트를 만들겠습니다.

EmptyActivity를 선택하여 진행하도록하겠습니다.

Activity Name은 MainActivity

Layout Name은 activity_main

(둘다 기본적으로 입력되있는상태)

로 Finish를 눌러 프로젝트를 시작하도록하겠습니다.

왼쪽은 Project 탭에서

java파일이있는 패키지를 오른쪽을 눌러 New ->Fragment->Fragment(Blank)를 클릭합니다.

다음과 같은 창이 나옵니다.

Activity를 만들때와 비슷한 창이 나오죠

Fragment Name은 BlankFragment

Layout Name은 fragment_blank 를 사용하겠습니다.

Fragment와 layout이 추가되었을텐데요

BlankFragment java파일로 이동합니다.

다음의 코드가 있을것입니다.

public class BlankFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";

// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;

private OnFragmentInteractionListener mListener;

public BlankFragment() {
// Required empty public constructor
}

/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
*
@param param1 Parameter 1.
*
@param param2 Parameter 2.
*
@return A new instance of fragment BlankFragment.
*/
// TODO: Rename and change types and number of parameters
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);
}
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_blank, container, false);
}

// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}

@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}

@Override
public void onDetach() {
super.onDetach();
mListener = null;
}

/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p/>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}

이 코드에서는 String 2개를 Fragment생성시 전달하는 기능 및 엑티비티에서 Framgent의 상태변화(뒤로가기 클릭)등의 관리를 도와주는 기능을 담고있는데 저희는 여기서 이 부분만을 이용할것입니다.

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);
}
}

newInstance 메소드를 통해서 필요한 파라미터를 전달하고

newInstance안에서 Fragment를 생성하고 intent를 통해서 데이터를 넘겨줍니다.

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;
 }

이렇게 전달된 bundle 데이터는 onCreate에서 getArguments(). 이후에 있는

getString(“key”), getInt(“key”)로 받을수 있습니다.

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}

onCreate에서 getArguments()를 통해서 받아지게됩니다.

다음 두 메소드만있으면 데이터의 전달을 할수있게됩니다.

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);
}
}

이제 불필요한 부분을 제거하여 진행해보도록합시다.

public class BlankFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";

// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
   // private OnFragmentInteractionListener mListener;

public BlankFragment() {
// Required empty public constructor
}

/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
*
@param param1 Parameter 1.
*
@param param2 Parameter 2.
*
@return A new instance of fragment BlankFragment.
*/
// TODO: Rename and change types and number of parameters
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);
getArguments().getInt()
}
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_blank, container, false);
}
}

onCreateView부분에서 전달받은 String ARG_PARAM1과 ARG_PARAM2
를 확인해보도록합시다

onCreateView부분에서 전달받은 String ARG_PARAM1과 ARG_PARAM2를 확인해보도록합시다
public class BlankFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";

// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;

private OnFragmentInteractionListener mListener;

public BlankFragment() {
// Required empty public constructor
}

/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
*
@param param1 Parameter 1.
*
@param param2 Parameter 2.
*
@return A new instance of fragment BlankFragment.
*/
// TODO: Rename and change types and number of parameters
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);
getArguments().getInt()
}
}

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

       //추가함
Log.v("Test","Param1 : "+mParam1 + " Param2 :"+mParam2);
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_blank, container, false);
}

}

이제 Fragment를 호출해야겠죠. 그러기위해서 저번 강의에서 사용했듯이 activity_main.xml에 LinearLayout을 하나 만들고 id를 contents로 하도록하겠습니다.

activity_main.xml

이제 MainActivity.java로 이동하여

Fragment를 호출해보도록합시다.

지난시간에 다음과 같은 코드를 통해서 Fragment를 추가했었습니다.

FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.contents,new MainFragment());
fragmentTransaction.commit();

저희의 Fragment이름이 BlankFragment이므로 MainFragment()를 BlankFragment로 하면되겟지요?

코드를 타이핑하시면

BlankFragment()란에 오류가 생긴것을 알수있습니다.

마우스를 올려보면 다음과 같은 오류를 알려줍니다.

이 오류가 나는이유는 저희가 BlankFragmet에서

newInstance(String ,String) 이 메소드를 추가해주었습니다.

따라서 new BlankFragment()가 아닌 BlankFragment.newInstance(String,String)을 사용해주어야합니다.

수정한코드는 다음과 같습니다.

FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.contents, BlankFragment.newInstance("파라미터1", "파라미터2"));
fragmentTransaction.commit();

이제 준비가 다 되었습니다 애뮬레이터를 실행하여 확인해봅시다.

다음과 같이 로그가 정상적으로 출력되는것을 확인할수있습니다.