Viewpager als Fragment "vergisst" die View eines seiner tabfragmente

  • 1 Antworten
  • Letztes Antwortdatum
P

pUiE

Erfahrenes Mitglied
165
Hallo,
Ich habe folgende App struktur in meinem Projekt:
MainAcitivity -enthält-> ein Viewpager Fragment -enthält-> Fragmente für die verschiedenen Tabs.
Die Hauptnavigation finder mittels eines Navigation Drawers statt. Beim Starten der App wird das Fragment geladen in dem der Viewpager ist. Dies funktioniert wunderbar und die verschiedenen Pages des Viewpagers werden korrekt dargestellt.
Wechsel ich jetzt allerdings über den navigation Drawer in ein anderes Fragment (Das Viewpager Fragment wird als durch eine Transaction des FragmentManagers durch ein anderes Fragment ersetzt) und wechsel dann wieder über den Navigation Drawer in das Viewpager Fragment vom Anfang, dann fehlt das Layout der Page im Viewpager. Wechsel ich in den Pages ein paar mal hin und her, dann konnte ich feststellen, dass von den anderen teilweise die View angezeigt wird. Irgendwann werden die Views dann doch wieder hergestellt und sind zu sehen.

Kommt jemandem das Problem bekannt vor? Ich vermute die Views werden aus Speichergründen entfernt. Gibt es eine Methode dies zu verhindern? Oder kann ich die Pages dazu "zwingen" beim aufruf ihres Viewpagers alle Views neu zu erzeugen?

Ich arbeite mit der support.v4 library.

Meine Klasse die den Viewpager enthält sieht folgendermaßen aus:
Code:
public class EchtzeitDatenFragment extends Fragment{
	
	public static final int FRAGMENT_UEBERSICHT = 0;
	public static final int FRAGMENT_FAHRERLEISTUNG = 1;
	public static final int FRAGMENT_AKKULEISTUNG = 2;
	public static final int FRAGMENT_BRENNSTOFFZELLENLEISTUNG = 3;
	
	SectionsPagerAdapter mSectionsPagerAdapter;
	ViewPager mViewPager;
	
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View mView = inflater.inflate(R.layout.fragment_view_pager, container, false);

		mSectionsPagerAdapter = new SectionsPagerAdapter(((MainActivity)getActivity()).getSupportFragmentManager());
		
		
		mViewPager = (ViewPager)mView.findViewById(R.id.pager);
		mViewPager.setAdapter(mSectionsPagerAdapter);
		
		setRetainInstance(true);
		
		return mView;
	}



	private class SectionsPagerAdapter extends FragmentPagerAdapter{

		public SectionsPagerAdapter(FragmentManager fm) {
			super(fm);
		}

		@Override
		public Fragment getItem(int arg0) {
			switch (arg0) {
			case EchtzeitDatenFragment.FRAGMENT_UEBERSICHT:
				Fragment basicFragment = new BasicFragment();
				return basicFragment;
			case EchtzeitDatenFragment.FRAGMENT_FAHRERLEISTUNG:
				Fragment fahrerleistungFragment = new FahrerleistungFragment();
				return fahrerleistungFragment;
			case EchtzeitDatenFragment.FRAGMENT_AKKULEISTUNG:
				Fragment akkuleistungFragment = new AkkuleistungFragment();
				return akkuleistungFragment;
			case EchtzeitDatenFragment.FRAGMENT_BRENNSTOFFZELLENLEISTUNG:
				Fragment brennstoffzellenleistungFragment = new BrennstoffzellenleistungFragment();
				return brennstoffzellenleistungFragment;		

			default:
				break;
			}
			return null;
		}		

		@Override
		public int getCount() {
			
			return 4;
		}

		@Override
		public CharSequence getPageTitle(int position) {
			switch (position) {
			case EchtzeitDatenFragment.FRAGMENT_UEBERSICHT:
				return "Übersicht";
			case EchtzeitDatenFragment.FRAGMENT_FAHRERLEISTUNG:
				return "Fahrerleistung";
			case EchtzeitDatenFragment.FRAGMENT_AKKULEISTUNG:
				return "Akkuleistung";
			case EchtzeitDatenFragment.FRAGMENT_BRENNSTOFFZELLENLEISTUNG:
				return "Brennstoffzellenleistung";

			default:
				return null;
			}
		}
		
	}
}

Ein Unterfragment des Viewpagers enthält lediglich die onCreateView Methode in der das Layout über einen Inflater angelegt wird.

Vielleicht könnt ihr helfen, oder könnt mir sagen dass der Ansatz komplett falsch ist und es eine besere Möglichkeit gibt einen Viewpager selbst als Fragment anzulegen :D

Vielen Dank
Jakob
 
Ich antworte mir mal selber, weil ich habe die Lösung gefunden =)
Der Trick ist innerhalb des Fragmentes nicht den SupportFragmentManager zu verwenden, sondern über "getChildFragmentManager" den ChildFragmentmanager zu nehmen. Allerdings kommt es dann zu einer Reihe vn Fehlern beim ausführen, die muss man folgendermaßen abfangen:
In dem Fragment in dem man den ChildfragmentManager aufgerufen hat muss die "onDetach()" funktion überschrieben werden und mit folgendem Code gefüllt werden:
Code:
@Override
	public void onDetach() {
		super.onDetach();

		try {
			Field childFragmentManager = Fragment.class
					.getDeclaredField("mChildFragmentManager");
			childFragmentManager.setAccessible(true);
			childFragmentManager.set(this, null);

		} catch (NoSuchFieldException e) {
			throw new RuntimeException(e);
		} catch (IllegalAccessException e) {
			throw new RuntimeException(e);
		}
	}
 
Zurück
Oben Unten