Fragment간 에 데이터전달
위 강의에 이어서 진행합니다.
이번시간에는 저번시간에 이어 Fragment에 데이터를 전달해보겠습니다
엑티비티간에 데이터를 전송할때 Intent를 사용했었는데요
Fragment는 Bundle이라는 것을 사용하여 데이터를 전송합니다.
Intent와 비슷하므로 Intent를 잘 모르신다면 먼저 학습하시는것을 추천합니다.
https://brunch.co.kr/@henen/16
안드로이드 스튜디오에서 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로 하도록하겠습니다.
이제 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();
이제 준비가 다 되었습니다 애뮬레이터를 실행하여 확인해봅시다.
다음과 같이 로그가 정상적으로 출력되는것을 확인할수있습니다.