티스토리 뷰
4. 중첩 프래그먼트를 이용하자
프래그먼트안에 프래그먼트를 넣는 중첩 프래그먼트에 대해 알아보자
중첩 프래그먼는 처음에는 지원되지 않았지만 지원 라이브러리쪽에서 대응해 현재는 1.6 이상에서 이용 할 수 있게 되었습니다. 단, 중첩 프래그먼트를 이용하면 코드가
복잡해지고 구현 난이도가 높아 집니다. 가능하면 커스텀 뷰로 대체 등을 검토 해보세요
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
</RelativeLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
private static final String TAG_PARENT = "TAG_PARENT";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fragmentManager = getSupportFragmentManager();
Fragment parentFragment = fragmentManager.findFragmentByTag(TAG_PARENT);
if (parentFragment == null) {
fragmentManager.beginTransaction()
.add(R.id.container, ParentFragment.getInstance(), TAG_PARENT).commit();
}
}
@Override
public void onBackPressed() {
FragmentManager fragmentManager = getSupportFragmentManager();
Fragment parentFragment = fragmentManager.findFragmentByTag(TAG_PARENT);
if (parentFragment != null && parentFragment.getChildFragmentManager().getBackStackEntryCount() > 0) {
parentFragment.getChildFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
}
}
fragment_parent.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/add_button"
android:text="추가"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/remove_button"
android:text="삭제"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
ParentFragment.java
public class ParentFragment extends Fragment {
public static final String TAG_CHILD = "TAG_CHILD";
public static final String KEY_NUMBER = "KEY_NUMBER";
private int mNumber = 0;
private FragmentManager.OnBackStackChangedListener mListener = new FragmentManager.OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
FragmentManager fragmentManager = getChildFragmentManager();
int count = 0;
for (Fragment f : fragmentManager.getFragments()) {
if (f != null) {
count++;
}
}
mNumber = count;
}
};
public static ParentFragment getInstance() {
return new ParentFragment();
}
public ParentFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_parent, null);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.findViewById(R.id.add_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FragmentManager childFragment = getChildFragmentManager();
childFragment.beginTransaction()
.add(R.id.fragment_container, ChildFragment.getInstance(mNumber))
.addToBackStack(null)
.commit();
}
});
view.findViewById(R.id.remove_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mNumber == 0) {
return;
}
FragmentManager childFragmentManager = getChildFragmentManager();
childFragmentManager.popBackStack();
}
});
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.onActivityCreated(savedInstanceState);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null) {
mNumber = savedInstanceState.getInt(KEY_NUMBER, 0);
}
FragmentManager childFragmentManager = getChildFragmentManager();
Fragment fragment = childFragmentManager.findFragmentByTag(TAG_CHILD);
Log.d("ParentFragment", "onActivityCreated childFragment=" + fragment + ", mNumber=" + mNumber);
if (savedInstanceState == null) {
FragmentTransaction transaction = childFragmentManager.beginTransaction();
transaction.add(R.id.fragment_container, ChildFragment.getInstance(mNumber), TAG_CHILD);
transaction.commit();
}
childFragmentManager.addOnBackStackChangedListener(mListener);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.d("ParentFragment", "onSaveInstanceState mNumber=" + mNumber);
outState.putInt(KEY_NUMBER, mNumber);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d("ParentFragment", "onDestroy");
}
}
fragment_child.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ChildFragment">
<TextView
android:id="@+id/text3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="자식 프래그먼트" />
</FrameLayout>
ChildFragment.java
public class ChildFragment extends Fragment {
private static final String ARG_NO = "ARG_NO";
public static ChildFragment getInstance(int no) {
ChildFragment fragment = new ChildFragment();
Bundle bundle = new Bundle();
bundle.putInt(ARG_NO, no);
fragment.setArguments(bundle);
return fragment;
}
public ChildFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_child, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
TextView textView = view.findViewById(R.id.text3);
int no = getArguments().getInt(ARG_NO, 0);
String text = "" + no + " 번째 자식 프래그먼트";
textView.setText(text);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d("ChildFragment", "onDestroy");
}
}
중첩 프래그먼트를 다룰 때는 getSupportFragmentManager() 이 아니라 getChildFragmentManager()를 사용합니다.
중첩된 프래그먼트의 백스택도 중첩되지 않은 프래그먼트처럼 사용할 수 있지만 단 한가지 다른점은 뒤로가기 키의 처리는 해주지 않는다는 점 입니다.
튀로가기 키가 눌렀을 때 부모 프래그먼트이 백스택을 확인하고 백스택이 있으면
popBackStack() 할 필요가 있습니다.
'android' 카테고리의 다른 글
6. BroadcastReceiver로 브로드캐스트 이벤트를 수신하자 (0) | 2018.05.20 |
---|---|
5. UI를 갖지 않는 프래그먼트를 이용하자 (0) | 2018.05.20 |
3. 프래그먼트를 동적으로 추가 및 삭제하기 (0) | 2018.05.03 |
2.프래그먼트를 이해하자 (0) | 2018.05.03 |
1. 커스텀 뷰 만들기 (0) | 2018.05.02 |