Aslında yığına eklenen en son parça yoktur, çünkü tek bir işlemde yığına birkaç parça veya parça ekleyebilir veya yeni bir tane eklemeden parçaları kaldırabilirsiniz.
Gerçekten bir parça yığınına sahip olmak ve yığındaki indeksine göre bir parçaya erişebilmek istiyorsanız, arka yığınında bir soyutlama katmanınız olsa iyi FragmentManager
olur. İşte bunu nasıl yapabileceğiniz:
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);
}
}
Yerine ekleme ve arayarak parçaları kaldırma Şimdi FragmentManager
doğrudan, kullanmak gerekir push()
, replace()
vepop()
yöntemleri FragmentStackManager
. Ve sadece arayarak en üstteki parçaya erişebileceksiniz stack.get(stack.size() - 1)
.
Ama korsanlardan hoşlanıyorsanız, benzer şeyler yapmanın başka yollarına ihtiyacım var. Söylemem gereken tek şey, bu korsanların yalnızca destek parçalarıyla çalışacağıdır.
İlk hack, sadece tüm aktif parçaların parça yöneticisine eklenmesini sağlamaktır. Parçaları tek tek değiştirir ve yığından çıkarırsanız, bu yöntem en üstteki parçayı döndürür:
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;
}
}
İkinci yaklaşım, olay daha hack'lidir ve addToBackStack
çağrılan son işlemde eklenen tüm parçaları almanıza izin verir :
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;
}
}
Lütfen bu durumda bu sınıfı android.support.v4.app
pakete koymanız gerektiğini unutmayın .
FragmentTransaction.add(int containerViewId, Fragment fragment, String tag)
veyaFragmentTransaction.replace(int containerViewId, Fragment fragment, String tag)
doc