webentwicklung-frage-antwort-db.com.de

ViewPager-Update-Fragment beim Wischen

ich habe ein Problem, mit dem ich in den letzten 2 Tagen zu kämpfen hatte.

Ich erstelle eine App, die ActionBar, ViewPager & FragmentPagerAdapter verwendet. Der Code für Activity, Fragments & FragmentPagerAdapter entspricht genau den im Beispiel Android= unter http://developer.Android.com/reference/Android/support/v4 /view/ViewPager.html

Das Problem, dem ich gegenüberstehe, ist - vorausgesetzt, ich habe nur 2 Fragmente im viewPager. Beim Umschalten/Wischen zwischen den beiden werden die Fragmente nicht aktualisiert. onResume wird nicht aufgerufen, da der viewPager mindestens 1 Fragment zu beiden Seiten des angezeigten Fragments zwischenspeichert.

Ich habe versucht, mithilfe von onTabSelected zu erkennen, wann ein Fragment ausgewählt ist, und dann mithilfe einer Schnittstelle eine Methode von diesem Fragment aus zu starten (Code unten).

public void onTabSelected(Tab tab, FragmentTransaction ft) {
    TabInfo tag = (TabInfo)tab.getTag();
    for (int i=0; i<mTabs.size(); i++) {
        if (mTabs.get(i) == tag) {
            mViewPager.setCurrentItem(i);
        }
    }
    ((IStartStop)getItem(tab.getPosition())).Start();
}

Bei Verwendung der Start-Methode wird jedoch eine NullPointerException ausgelöst, wenn versucht wird, eine Textansicht zu aktualisieren. Der Code der Startmethode lautet:

public void Start() {
    TextView tv = _view.findViewById(R.id.text);
    tv.setText("test");
}

Die Ausnahme wird in folgender Zeile ausgelöst:

TextView tv = _view.findViewById(R.id.text);

Die IStartStop-Oberfläche ist ganz einfach:

public interface IStartStop {
    public void Start();
    public void Stop();
}

Ich möchte notifyDataSetChanged () nicht verwenden. mit POSITION_NONE, da jedes Mal, wenn ich zu einem neuen Fragment wische, das Laden der Fragmente einige Sekunden dauert

Zu diesem Zeitpunkt enthalten die Fragmente nur eine Textansicht, in Zukunft werden sie eine Animation haben, daher ist es wichtig:

1- Führen Sie eine Animation nur aus, wenn das Fragment ausgewählt ist und nicht, wenn das Fragment daneben ausgewählt ist (wie ViewPager Fragmente zwischenspeichert und fortsetzt).

2- Stoppen Sie die Animation, wenn das Fragment nicht mehr ausgewählt ist, um eine Verschwendung von Ressourcen zu vermeiden.

Ja, ich habe bereits alles im Internet überprüft, aber nichts scheint bei mir zu funktionieren.

Vielen Dank für Ihre Hilfe!

27
Steve

Überraschenderweise macht das ViewPager (unter anderem) nicht "nativ". Aber nicht alles ist verloren.

Zuerst müssen Sie Ihre Fragmente so ändern, dass sie die Animation nur ausführen, wenn Sie ihnen mitteilen, dass sie in Ordnung sind, und nicht, wenn sie instanziiert werden. Auf diese Weise können Sie mit dem Versatz des Viewpagers (Standard = 3) spielen und 2-3 Fragmente vorinstallieren, aber nicht animieren.

Der zweite Schritt besteht darin, eine Schnittstelle oder Ähnliches zu erstellen, die definiert, wann das "Fragment sichtbar geworden ist".

Der dritte Schritt wäre, einen neuen OnPageScrollListener an Ihren Viewpager anzuhängen.

Code folgt (in semi-ungetestetem Code):

1) Hängen Sie den Listener an:

mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(final int i, final float v, final int i2) {
            }
            @Override
            public void onPageSelected(final int i) {
                YourFragmentInterface fragment = (YourFragmentInterface) mPagerAdapter.instantiateItem(mViewPager, i);
                if (fragment != null) {
                    fragment.fragmentBecameVisible();
                } 
            }
            @Override
            public void onPageScrollStateChanged(final int i) {
            }
        });

2) Dies ist Ihre Schnittstelle:

public interface YourFragmentInterface {
    void fragmentBecameVisible();
}

3) Ändern Sie Ihre Fragmente so, dass sie dies implementieren:

public class YourLovelyFragment extends Fragment implements YourFragmentInterface {

4) Implementieren Sie die Schnittstelle im Fragment

@Override
public void fragmentBecameVisible() {
    // You can do your animation here because we are visible! (make sure onViewCreated has been called too and the Layout has been laid. Source for another question but you get the idea.
}

Wohin soll es von hier aus gehen?

Möglicherweise möchten Sie eine Methode/einen Listener implementieren, um die "anderen" Fragmente zu benachrichtigen, dass sie nicht mehr sichtbar sind (d. H., Wenn eines sichtbar ist, sind die anderen nicht sichtbar). Dies ist jedoch möglicherweise nicht erforderlich.

55

Dies wirkt sich auf die Änderungen von einer Seite auf eine andere Seite im Ansichts-Pager aus.

OnPageChangeListener  pagechangelistener =new OnPageChangeListener() {

                @Override
                public void onPageSelected(int arg0) {
                    Logger.logMessage("Called first");

                    pageAdapter.notifyDataSetChanged();
                    indicator.setCurrentItem(arg0);
                }

                @Override
                public void onPageScrolled(int arg0, float arg1, int arg2) {

                    Logger.logMessage("Called second");

                }

                @Override
                public void onPageScrollStateChanged(int arg0) {

                    Logger.logMessage("Called third");

                }
            };
            myViewPager.setOnPageChangeListener(pagechangelistener);

Verwenden Sie dies in Ihrem Seitenadapter.

@Override
    public int getItemPosition(Object object) {

        return POSITION_NONE;
    }
4
Dinesh IT

setOnPageChangeListener ist veraltet. Verwenden Sie stattdessen addOnPageChangeListener.

mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(final int i, final float v, final int i2) {
        }
        @Override
        public void onPageSelected(final int i) {
            YourFragmentInterface fragment = (YourFragmentInterface) mPagerAdapter.instantiateItem(mViewPager, i);
            if (fragment != null) {
                fragment.fragmentBecameVisible();
            } 
        }
        @Override
        public void onPageScrollStateChanged(final int i) {
        }
    });
2
A. Vin