Android App 개발을 하는데 Fragment는 특정 UI 들을 하나로 묶고, 다양한 UI 구현에 엄청난 효자 노릇을 한다.
(Fragment를 잘 사용함으로, 반복된 UI 구현을 줄일 수 있고, 좀 더 다양하고 깔끔하게 정리된 UI 개발을 할 수 있다.)
하지만 단순한 앱을 개발하는데, Fragment를 자유자제로 사용 할 능력이 없다면 그냥 사용하지 않고 개발하는 것을 권한다.
(Fragment 사용으로 발생하는 Side effects 들을 감당하기 어려울 수 있기 때문이다)
Android개발에서 Fragment를 사용 할 경우에 Activity와 Fragment 간에 데이터를 전달이 필요한 경우가 많이 생긴다.
Activity <-> Fragment간의 데이터 전달 방법에 대해서 알아보겠다.
1. Fragment 에서 Activity로 데이터를 전달 하는 방법
Fragment 에서 특정 interface callback 을 정의하여 Activity 로 Fragment에서 Runtime 으로 운용되는 데이터를 전달 할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | public class MyFragment extends Fragment{ public interface OnMyListener{ void onReceivedData(Object data); } private OnMyListener mOnMyListener; @Override public void onAttach(Context context) { super.onAttach(context); if(getActivity() != null && getActivity() instanceof OnMyListener){ mOnMyListener = (OnMyListener) getActivity(); } } ...... //데이터 혹은 특정 Callback { if(mOnMyListener != null){ mOnMyListener.onReceivedData(obj); } } } | cs |
이 부분을 적용하기위해서는 먼저 Activity에 Fragment에 정의한 Interface 를 구현해야 한다.
1 2 3 4 5 6 7 8 | public class MyActivity extends Activity implements OnMyListener{ .... public void onReceivedData(Object data){ } } | cs |
위 방법은 Google Developer 사이트에서도 설명하는 방법이다.
* Support Library에 에 있는 v4 Fragmnet를 사용한다면 onAttatch(Context context)가 호출 되지만, Android Framework 의 기본 Fragment를 사용한다면,
이미 Deprecated된 onAttatch(Activity activity) 가 호출 될 수 있다.
2. Activity 에서 Fragment로 데이터를 전달 하는 방법
Fragment가 Activity에 부착되는 시점에서 특정 Activity의 객체를 받아와 Fragment에서 불러와 사용한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 | public class MyFragment extends Fragment{ private Object mMyData; @Override public void onAttach(Context context) { super.onAttach(context); if(getActivity() != null && getActivity() instanceof MyActivity){ mMyData = ((MyActivity)getActivity()).getData(); } } } | cs |
이것 또한 부모가되는 Activity에 관련 Method 혹은 변수가 선언되어있어야 한다.
1 2 3 4 5 6 7 8 | public class MyActivity extends Activity implements OnMyListener{ .... public Object getData(){ return obj; } } | cs |
이 부분이 가장 편리하긴 하지만, Fragment를 서로 다른 Activity에서 사용하기가 어려워 지며, 코드가 복잡해 질 수 있다.
3. Parcelable객체를 Fragment Argument로 전달 하는 방법
Activity에서 Fragment로 데이터를 전달 할 경우 Parcelable이 구현된 Class의 객체를 Argument로 전달하는 것을 추천한다.
우선 Parcelable 이 구현된 객체가 필요하다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | public class MyData implements Parcelable{ public String name; public String address; protected MyData(Parcel in) { name = in.readString(); address = in.readString(); } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(name); dest.writeString(address); } @Override public int describeContents() { return 0; } public static final Creator<MyData> CREATOR = new Creator<MyData>() { @Override public MyData createFromParcel(Parcel in) { return new MyData(in); } @Override public MyData[] newArray(int size) { return new MyData[size]; } }; } | cs |
MyData란 Class를 만들었다 그리고 Fragment argument에 넣어 Activity에서 Fragment 생성 시 원하는 객체를 전달해 준다.
1 2 3 4 5 6 7 8 9 10 11 | public class MyFragment extends Fragment{ public static Fragment newInstance(MyData data) { Fragment f = new MyFragment(); Bundle b = new Bundle(); b.putParcelable(MyData.class.getName(), data); f.setArguments(b); return f; } } | cs |
Parcelable은 Android에서 대표적으로 사용되는 Mashalling 방법이다.
보통 ContextWrapper간에 Mashaling을 이용하여 객체를 전달하면, 특정 객체가 단순히 복사되어 전달된다.
하지만 Fragment는 독립적으로 이용 될 수 없는 특성이 있기 떄문에 항상 Activity위에 존재 해야한다.
그렇기 때문에 조금만 더 생각해보면, Fragment로 전달되는 Parcelable 객체는 과연 CallByValue 인가 CallByReference인가 궁금증을 갖는 게 좋다.
Activity에서 Fragment에 전달하는 객체들은 CallByReference로 전달 된다.
즉 Observer와 같은 기법을 사용한다면, Fragment 내에서 객체가 변경되었을 때, 같은 객체를 참조하는 Activity는 충분히 변경된 객체를 통해 UI 를 업데이트 할 수 있다.
이 부분은 직접 확인하길 바란다.
'개발 > 안드로이드' 카테고리의 다른 글
에드센스 컨텐츠 불충분 / Adsense / 블로그 광고 (0) | 2016.12.02 |
---|---|
Android WebView 캐시 모드 (0) | 2016.12.01 |
개발 맥북 macOS Sierra 업데이트 시 주의 사항 (0) | 2016.12.01 |
안드로이드 에러 처리 (Java try - catch - finally) (0) | 2016.12.01 |
Mac book macOS Sierra! 업그레이드 완료! (0) | 2016.12.01 |