Ich habe eine App mit a ViewPager
und drei Fragment
s. Ich versuche herauszufinden, wie der aktuelle Wert Fragment
angezeigt wird, damit ich zu seinen Argumenten gelangen kann.
Ich OnPageChangeListener
greife nach dem aktuellen Seitenindex, aber
ViewPager.getChildAt(int position);
gibt a zurück View
. Wie ist die Beziehung zwischen diesem View
und dem Strom Fragment
?
android
android-fragments
android-viewpager
MitchellSalad
quelle
quelle
Ich habe dieses Problem umgekehrt gelöst. Anstatt nach dem Fragment aus der Aktivität zu suchen, registriere ich das Fragment während seiner onAttach () -Methode bei seiner Eigentümeraktivität und hebe die Registrierung in der onStop () -Methode auf. Die Grundidee:
Fragment:
@Override public void onAttach(Activity activity) { super.onAttach(activity); try{ mActivity = (IMyActivity)activity; }catch(ClassCastException e){ throw new ClassCastException(activity.toString() +" must be a IMyActivity"); } mActivity.addFragment(this); } @Override public void onStop() { mActivity.removeFragment(this); super.onStop(); }
IMyActivity:
public interface IFriendActivity { public void addFragment(Fragment f); public void removeFragment(Fragment f); }
Meine Aktivität:
public class MyActivity implements IMyActivity{ [...] @Override public void addFragment(Fragment f) { mFragments.add(f); } @Override public void removeFragment(Fragment f) { mFragments.remove(f); } }
quelle
OnAttach
NICHT aufgerufen wird, wenn Sie Ihre Aktivität reduzieren, während SieOnStop
noch aufgerufen werden.Bearbeiten - Mach das nicht. Wenn Sie versucht sind, lesen Sie die Kommentare, warum es eine schlechte Idee ist.
Bei der Gelegenheit versuchen Sie immer noch, dieses Problem zu lösen:
Verlängern
FragmentPagerAdapter
. Erstellen Sie im Konstruktor die benötigten Fragmente und speichern Sie sie in einer Liste (Array / ArrayList) von Fragmenten.private final int numItems = 3; Fragment[] frags; public SwipeAdapter (FragmentManager fm) { super(fm); //Instantiate the Fragments frags = new Fragment[numItems]; Bundle args = new Bundle(); args.putString("arg1", "foo"); frags[0] = new MyFragment(); frags[1] = new YourFragment(); frags[2] = new OurFragment(); frags[2].setArguments(args); }
Dann
getItem(int position)
können Sie so etwas tunpublic Fragment getItem(int position) { return frags[position]; }
Ich bin mir nicht sicher, ob dies die allgemein akzeptierte Methode ist, aber es hat bei mir funktioniert.
Bearbeiten
Dies ist wirklich kein guter Weg. Wenn Sie vorhaben, Orientierungsänderungen zu verarbeiten oder Ihre App in den Hintergrund zu rücken, wird dies wahrscheinlich Ihren Code beschädigen. Bitte lesen Sie die Kommentare unter dieser Antwort für weitere Informationen. Verwenden Sie lieber die Antwort von @James
quelle
getActivity()
nicht die aktuelle Aktivität zurückgeben, sondern eine frühere Instanz, die zerstört wurdeJa, es ist möglich, wenn Sie verwenden
FragmentStatePagerAdapter
.ViewPager vp; //... YourFragment fragment = (YourFragment) adapter.instantiateItem(vp, vp.getCurrentItem());
quelle
BITTE VERWENDEN SIE DIESES NICHT
Lassen Sie Ihren Adapter die folgende
FragmentStatePagerWithCurrentAdapter
Klasse erweitern und nicht implementierengetItem
denselben Code ingetItemAtIndex
Setzen Sie das
ViewPager
OnPageChangeListener
auf die Instanz des Adapters.Wenn Sie auf das aktuelle Fragment zugreifen müssen, rufen Sie einfach an
adapter.getCurrentItem()
.package your.package; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentStatePagerAdapter; import android.support.v4.view.ViewPager.OnPageChangeListener; import android.util.SparseArray; import android.view.ViewGroup; public abstract class FragmentStatePagerWithCurrentAdapter extends FragmentStatePagerAdapter implements OnPageChangeListener { int currentPage = 0; private SparseArray<Fragment> mPageReferenceMap = new SparseArray<Fragment>(); public FragmentStatePagerWithCurrentAdapter(FragmentManager fm) { super(fm); } @Override public final Fragment getItem(int index) { Fragment myFragment = getItemAtIndex(index); mPageReferenceMap.put(index, myFragment); return myFragment; } public abstract Fragment getItemAtIndex(int index); @Override public void destroyItem(ViewGroup container, int position, Object object) { super.destroyItem(container, position, object); mPageReferenceMap.remove(Integer.valueOf(position)); } public Fragment getCurrentItem() { return mPageReferenceMap.get(currentPage); } @Override public void onPageScrollStateChanged(int arg0) { } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageSelected(int newPageIndex) { currentPage = newPageIndex; } }
Ich habe als Referenz den folgenden Blog-Beitrag verwendet: http://tamsler.blogspot.com/2011/11/android-viewpager-and-fragments-part-ii.html
quelle
Es wurde hier erklärt: http://developer.android.com/guide/topics/fundamentals/fragments.html
In OnCreateView müssen Sie eine Ansicht zurückgeben, um eine Benutzeroberfläche für Ihr Fragment zu zeichnen. Ich denke, das ist die Beziehung.
Auch diese Frage könnte ähnlich sein: Konzentrieren Sie sich auf ViewPager
quelle
getFragmentManager().findFragmentById(R.id.fragment_container);
dann? Sie werden das aktuelle Fragment in diesem Container erhalten, denke ich.Sie haben folgende Möglichkeiten: - Auf der Klassenausdehnung eines Ansichts-Pager-Adapters (wie PagerAdapter, FragmentStatePagerAdapter ...) überschreiben Sie die Methode instantiateItem:
@Override public Object instantiateItem(ViewGroup container, int position) { final Fragment frag = (Fragment) super.instantiateItem(container, position); if(frag instanceof ListNoteOfTypeFragment){ final ListNoteOfTypeFragment listNoteOfTypeFragment = (ListNoteOfTypeFragment) frag; //do whatever you want with your fragment here listNoteOfTypeFragment.setNoteChangeListener(mListener); } return frag; }
quelle
Definitive Antwort, die nahtlos funktioniert (aber kleiner Hack):
irgendwo im Layout des Seitenfragments:
<FrameLayout android:layout_width="0dp" android:layout_height="0dp" android:visibility="gone" android:id="@+id/fragment_reference"> <View android:layout_width="0dp" android:layout_height="0dp" android:visibility="gone"/> </FrameLayout>
in onCreateView () des Fragments:
... View root = inflater.inflate(R.layout.fragment_page, container, false); ViewGroup ref = (ViewGroup)root.findViewById(R.id.fragment_reference); ref.setTag(this); ref.getChildAt(0).setTag("fragment:" + pageIndex); return root;
und Methode zum Zurückgeben von Fragment aus ViewPager, falls vorhanden:
public Fragment getFragment(int pageIndex) { View w = mViewPager.findViewWithTag("fragment:" + pageIndex); if (w == null) return null; View r = (View) w.getParent(); return (Fragment) r.getTag(); }
quelle
Jorge Garcias FragmentStatePagerWithCurrentAdapter ist eine sehr gute Lösung, die jedoch geringfügig verbessert werden muss. Falls die Aktivität als Reaktion auf eine Konfigurationsänderung oder ähnliches zerstört und neu erstellt wird, wird getItem nicht für die Fragmente aufgerufen, die vom Fragmentmanager gespeichert und abgerufen wurden. Daher überschreibe ich getItem normalerweise in meiner Unterklasse und füge Folgendes in den FragmentStatePagerWithCurrentAdapter ein
@Override public Object instantiateItem(ViewGroup container, int position) { Object item = super.instantiateItem(container, position); if ( item instanceof Fragment ) { pageReferenceMap.put(position, (Fragment)item); } return item; }
Das instanziierte Element wird jedes Mal aufgerufen, wenn auf das Fragment an dieser Position zugegriffen wird.
quelle
Oder speichern Sie einfach alle Fragmente in einer Karte:
public class MyFragment extends Fragment implements OnPageChangeListener { private ViewPager viewPager; private FragmentStatePagerAdapter viewAdapter; private View rootView; private Map<Integer, Fragment> fragments = new HashMap<Integer, Fragment>(); @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { rootView = inflater.inflate(R.layout.introdution, container, false); viewPager = (ViewPager) rootView.findViewById(R.id.pager); viewAdapter = new ViewAdapter(getFragmentManager()); viewPager.setAdapter(viewAdapter); viewPager.addOnPageChangeListener(this); return rootView; } private class ViewAdapter extends FragmentStatePagerAdapter { public ViewAdapter(FragmentManager fragmentManager) { super(fragmentManager); } @Override public Fragment getItem(int position) { Fragment result = null; switch (position) { case 0: result = Fragment1.newInstance(); break; case 1: result = Fragment2.newInstance(); break; } if (result != null) fragments.put(position, result); return result; } @Override public int getCount() { return 2; } } @Override public void onPageScrollStateChanged(int arg0) { } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageSelected(int position) { Fragment currentFragment = fragments.get(position); } }
quelle
Ich denke, es gibt den besseren Weg, dies zu nutzen
Log.i(TAG, "getCurrentItem " + mViewPager.getCurrentItem());
Kann die aktuelle Seite des Anzeigefragments abrufen.
quelle