실제로 스택에 추가 된 최신 조각이 없습니다. 단일 트랜잭션에서 여러 조각 또는 조각을 스택에 추가하거나 새 조각을 추가하지 않고 조각 만 제거 할 수 있기 때문입니다.
정말로 조각 스택을 갖고 스택의 인덱스로 조각에 액세스 할 수 있도록하려면 FragmentManager
및 해당 백 스택에 대한 추상화 계층을 갖는 것이 좋습니다. 방법은 다음과 같습니다.
public class FragmentStackManager {
private final FragmentManager fragmentManager;
private final int containerId;
private final List<Fragment> fragments = new ArrayList<>();
public FragmentStackManager(final FragmentManager fragmentManager,
final int containerId) {
this.fragmentManager = fragmentManager;
this.containerId = containerId;
}
public Parcelable saveState() {
final Bundle state = new Bundle(fragments.size());
for (int i = 0, count = fragments.size(); i < count; ++i) {
fragmentManager.putFragment(state, Integer.toString(i), fragments.get(i));
}
return state;
}
public void restoreState(final Parcelable state) {
if (state instanceof Bundle) {
final Bundle bundle = (Bundle) state;
int index = 0;
while (true) {
final Fragment fragment =
fragmentManager.getFragment(bundle, Integer.toString(index));
if (fragment == null) {
break;
}
fragments.add(fragment);
index += 1;
}
}
}
public void replace(final Fragment fragment) {
fragmentManager.popBackStackImmediate(
null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
fragmentManager.beginTransaction()
.replace(containerId, fragment)
.addToBackStack(null)
.commit();
fragmentManager.executePendingTransactions();
fragments.clear();
fragments.add(fragment);
}
public void push(final Fragment fragment) {
fragmentManager
.beginTransaction()
.replace(containerId, fragment)
.addToBackStack(null)
.commit();
fragmentManager.executePendingTransactions();
fragments.add(fragment);
}
public boolean pop() {
if (isEmpty()) {
return false;
}
fragmentManager.popBackStackImmediate();
fragments.remove(fragments.size() - 1);
return true;
}
public boolean isEmpty() {
return fragments.isEmpty();
}
public int size() {
return fragments.size();
}
public Fragment getFragment(final int index) {
return fragments.get(index);
}
}
이제 다음을 호출하여 조각을 추가하고 제거하는 대신 FragmentManager
직접, 당신은 사용해야합니다 push()
, replace()
그리고 pop()
방법 FragmentStackManager
. 그리고 당신은 호출하여 최상위 조각에 액세스 할 수 있습니다stack.get(stack.size() - 1)
.
하지만 해킹을 좋아한다면 비슷한 일을하는 다른 방법이 필요합니다. 내가 언급해야 할 유일한 것은 이러한 해킹이 지원 조각에서만 작동한다는 것입니다.
첫 번째 해킹은 모든 활성 프래그먼트를 프래그먼트 관리자에 추가하는 것입니다. 조각을 하나씩 교체하고 스택에서 팝하면이 메서드는 최상위 조각을 반환합니다.
public class BackStackHelper {
public static List<Fragment> getTopFragments(
final FragmentManager fragmentManager) {
final List<Fragment> fragments = fragmentManager.getFragments();
final List<Fragment> topFragments = new ArrayList<>();
for (final Fragment fragment : fragments) {
if (fragment != null && fragment.isResumed()) {
topFragments.add(fragment);
}
}
return topFragments;
}
}
두 번째 접근 방식은 이벤트가 좀 더 해키이며 마지막 트랜잭션에서 추가 된 모든 조각을 가져올 수 있습니다. addToBackStack
호출 .
package android.support.v4.app;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class BackStackHelper {
public static List<Fragment> getTopFragments(
final FragmentManager fragmentManager) {
if (fragmentManager.getBackStackEntryCount() == 0) {
return Collections.emptyList();
}
final List<Fragment> fragments = new ArrayList<>();
final int count = fragmentManager.getBackStackEntryCount();
final BackStackRecord record =
(BackStackRecord) fragmentManager.getBackStackEntryAt(count - 1);
BackStackRecord.Op op = record.mHead;
while (op != null) {
switch (op.cmd) {
case BackStackRecord.OP_ADD:
case BackStackRecord.OP_REPLACE:
case BackStackRecord.OP_SHOW:
case BackStackRecord.OP_ATTACH:
fragments.add(op.fragment);
}
op = op.next;
}
return fragments;
}
}
이 경우이 클래스를 android.support.v4.app
패키지 에 넣어야 합니다.
FragmentTransaction.add(int containerViewId, Fragment fragment, String tag)
또는FragmentTransaction.replace(int containerViewId, Fragment fragment, String tag)
문서