티스토리 뷰

android

4.중첩 프래그먼트를 이용하자

구름나드리 2018. 5. 9. 10:02

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() 할 필요가 있습니다. 



공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/12   »
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
글 보관함