Fragment beim Neuladen aktualisieren

110

In einer Android - Anwendung ich ein Datum aus einer Db in Laden im TableViewInnern ein Fragment. Aber wenn ich das neu lade Fragment, werden die vorherigen Daten angezeigt. Kann ich die Fragmentmit aktuellen Daten anstelle der vorherigen Daten neu füllen?

Samantha Withanage
quelle
Zeigen Sie uns bitte einen Code. Wo laden Sie Ihre Daten, wo starten Sie Ihr Fragment, wo speichern Sie Ihre Werte?
AS
Dies sollte Ihr porly beschriebenes Problem lösen: stackoverflow.com/questions/6503189/…
Benjamin W.
bitte weitere Informationen-Code - Schnipsel zur Verfügung stellen
nikvs
Versuchen Sie, Swipe-to-Refresh To Your App zu verwenden. Siehe stackoverflow.com/questions/41469040/fragment-refresh/…
Imtiaz Mamun

Antworten:

207

Ich denke, Sie möchten den Fragmentinhalt beim Datenbank-Update aktualisieren

Wenn ja, nehmen Sie das Fragment ab und bringen Sie es wieder an

// Reload current fragment
Fragment frg = null;
frg = getSupportFragmentManager().findFragmentByTag("Your_Fragment_TAG");
final FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.detach(frg);
ft.attach(frg);
ft.commit();

Your_Fragment_TAG ist der Name, den Sie Ihrem Fragment beim Erstellen gegeben haben

Dieser Code ist für die Support-Bibliothek.

Wenn Sie ältere Geräte nicht unterstützen, verwenden Sie einfach getFragmentManager anstelle von getSupportFragmentManager

[BEARBEITEN]

Für diese Methode muss das Fragment ein Tag haben.
Falls Sie es nicht haben, dann ist die Methode von @ Hammer genau das, was Sie brauchen.

Phantômaxx
quelle
3
Dies führt zu folgendem Fehler: java.lang.RuntimeException: Fehler beim Übermitteln des Ergebnisses ResultInfo {who = null, request = 2, result = 3, data = null} an die Aktivität {xont.virtusel.v4.controller / xont.virtusel.v4.controller .sale.InvocieBrandActivity}: java.lang.IllegalStateException: Kann diese Aktion nach onSaveInstanceState
Samantha Withanage
1
@ Elizabeth stellen Sie sicher, dass Ihr Fragment ein Tag richtig gesetzt hat
Phantômaxx
1
@ Rotwang Danke für Ihre Antwort Ich habe nur eine Abkürzung genommen, anstatt den langen Code zu machen, aber das hat den Weg geebnet :)
Si8
1
Diese Lösung funktioniert in der neuen Version der support-v4-Bibliothek (25.1.0) nicht mehr. Erklärung hier: stackoverflow.com/questions/41270858/…
Brahim Bouaboud
1
Warnung: Dieser Trick funktioniert auf Oreo nur, wenn Sie Support-Fragmente verwenden!
Rennen
146

Dadurch wird das aktuelle Fragment aktualisiert:

FragmentTransaction ft = getFragmentManager().beginTransaction();
if (Build.VERSION.SDK_INT >= 26) {
   ft.setReorderingAllowed(false);
}
ft.detach(this).attach(this).commit();
Mbengue Assane
quelle
1
Wo soll dieser Code abgelegt werden? innere Aktivität oder Fragment selbst?
Narendra Singh
2
Sie legen es in das Fragment, das aktualisiert werden muss.
Mbengue Assane
1
@SagarChavada wo hast du den Code abgelegt? Sie müssen es in ein einmaliges Ereignis einfügen, beispielsweise wenn Daten aktualisiert werden.
Mbengue Assane
5
Rekursion, Rekursion, endlose Anrufe
Zulkarnain Shah
2
Wenn Sie dies verwenden, wird in onResume im Fragment eine Schleife erstellt. Wie kann dies vermieden werden?
Seele
32

Falls Sie das Fragment-Tag nicht haben, funktioniert der folgende Code gut für mich.

Fragment currentFragment = getActivity().getFragmentManager().findFragmentById(R.id.fragment_container);
if (currentFragment instanceof "NAME OF YOUR FRAGMENT CLASS") {
 FragmentTransaction fragTransaction =   (getActivity()).getFragmentManager().beginTransaction();
 fragTransaction.detach(currentFragment);
 fragTransaction.attach(currentFragment);
 fragTransaction.commit();}
}
Hammer
quelle
1
Was wird die Fragment-ID sein? Ich habe nirgendwo eine Fragment-ID deklariert. Wie und wo soll es deklariert werden?
Narendra Singh
Kann nicht getActivity()in meiner Aktivität verwendet werden. Soll ich verwenden Activity.this...?
Si8
@NarendraJi Es ist nur die FrameLayout-ID, in der Sie Ihre Fragmente in einen Container legen.
Lokesh
Bitte entfernen Sie diese zusätzliche Klammer. Es hat mir viel Ärger gemacht.
Abhishek
9

Sie können Ihr Fragment aktualisieren, wenn es für den Benutzer sichtbar ist. Fügen Sie diesen Code einfach in Ihr Fragment ein. Dadurch wird Ihr Fragment aktualisiert, wenn es sichtbar ist.

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser) {
        // Refresh your fragment here          
  getFragmentManager().beginTransaction().detach(this).attach(this).commit();
        Log.i("IsRefresh", "Yes");
    }
}
Kaushik Khambhadiya
quelle
so langsam, dass es 3 Sekunden dauert, bis es wieder geladen wird
Omar Boshra
Dies scheint gut mit Viewpager-Adapter zu funktionieren
DragonFire
2
setUserVisibleHint ist veraltet
Sai Aditya
Arbeitete für mich, danke für die Lösung.
Hetsgandhi
7

Zum Aktualisieren des Fragments funktioniert die akzeptierte Antwort unter Nougat und höher nicht. Damit es auf allen Betriebssystemen funktioniert, können Sie Folgendes tun.

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        fragmentManager.beginTransaction().detach(this).commitNow();
        fragmentManager.beginTransaction().attach(this).commitNow();
    } else {
        fragmentManager.beginTransaction().detach(this).attach(this).commit();
    }
Sachin Jagtap
quelle
5

Sie können das Fragment nicht neu laden, während es an eine Aktivität angehängt ist, bei der die Fragment Already AddedAusnahme " " angezeigt wird.

Das Fragment muss also zuerst von seiner Aktivität gelöst und dann angehängt werden. Alles kann mit der fließenden API in einer Zeile durchgeführt werden:

getFragmentManager().beginTransaction().detach(this).attach(this).commit();

Update: Hiermit werden die an API 26 und höher vorgenommenen Änderungen berücksichtigt:

FragmentTransaction transaction = mActivity.getFragmentManager()
                        .beginTransaction();
                if (Build.VERSION.SDK_INT >= 26) {
                    transaction.setReorderingAllowed(false);
                }
                transaction.detach(this).attach
                        (this).commit();

Weitere Beschreibungen des Updates finden Sie unter https://stackoverflow.com/a/51327440/4514796

Ali Nem
quelle
2
Bitte geben Sie Ihre Antwort mit klaren Beschreibungen. Schreiben Sie den Code nicht, sondern erklären Sie den Code, den Sie freigegeben haben, damit auch andere ihn verstehen können und er hilfreich ist. Ich bitte Sie, den FAQ-Bereich zu lesen, um Stack Overflow effektiv nutzen zu können.
Sankar Ganesh
3
   MyFragment fragment = (MyFragment) getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG);
        getSupportFragmentManager().beginTransaction().detach(fragment).attach(fragment).commit();

Dies funktioniert nur, wenn Sie FragmentManagerdas Fragment initialisieren. Wenn Sie es als <fragment ... />XML haben, wird es nicht erneut aufgerufen onCreateView. Ich habe meine 30 Minuten verschwendet, um das herauszufinden.

Irshu
quelle
1

Hier, was ich getan habe und es für mich funktioniert hat, benutze ich Firebase und wenn der Benutzer angemeldet ist, wollte ich zuerst das aktuelle Fragment aktualisieren. Sie müssen den Kontext aus der Aktivität anfordern, da das Fragment keine Möglichkeit hat, den Kontext abzurufen, es sei denn, Sie legen ihn hier unter Aktivität oder Kontext fest ist der Code, den ich in der Kotlin-Sprache verwendet und gearbeitet habe. Ich denke, Sie könnten ihn auch in der Java-Klasse verwenden

   override fun setUserVisibleHint(isVisibleToUser: Boolean) {
    super.setUserVisibleHint(isVisibleToUser)
    val context = requireActivity()
    if (auth.currentUser != null) {
        if (isVisibleToUser){
            context.supportFragmentManager.beginTransaction().detach(this).attach(this).commit()
        }
    }

}
hardiBSalih
quelle
0

Verwenden Sie a ContentProviderund laden Sie Ihre Daten mit einem 'CursorLoader'. Mit dieser Architektur werden Ihre Daten bei Datenbankänderungen automatisch neu geladen. Verwenden Sie Frameworks von Drittanbietern für Ihre ContentProvider- Sie möchten es nicht wirklich selbst implementieren ...

artkoenig
quelle
0

Ich hatte das gleiche Problem, aber keines der oben genannten Probleme hat bei mir funktioniert. Entweder gab es ein Backstack-Problem (nach dem Laden, wenn der Benutzer zurück drückte, wurde das gleiche Fragment erneut angezeigt) oder es wurde das nicht aufgerufenonCreaetView

endlich habe ich das gemacht:

public void transactFragment(Fragment fragment, boolean reload) {
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
    if (reload) {
        getSupportFragmentManager().popBackStack();
    }
    transaction.replace(R.id.main_activity_frame_layout, fragment);
    transaction.addToBackStack(null);
    transaction.commit();
}

Ein guter Punkt ist, dass Sie weder das Tag noch die ID des Fragments benötigen. wenn Sie neu laden möchten

Emad
quelle
0

Verwenden Sie die onResume-Methode ... sowohl für die Fragmentaktivität als auch für die Aktivität, die das Fragment enthält.

Mwangi Gituathi
quelle
0
getActivity().getSupportFragmentManager().beginTransaction().replace(GeneralInfo.this.getId(), new GeneralInfo()).commit();

GeneralInfo Es ist meine Fragment-Klasse GeneralInfo.java

Ich habe es als Methode in die Fragmentklasse eingefügt:

public void Reload(){
    getActivity().getSupportFragmentManager().beginTransaction().replace(LogActivity.this.getId(), new LogActivity()).commit();
}
Brayan Steven Martínez Vanegas
quelle
-2
protected void onResume() {
        super.onResume();
        viewPagerAdapter.notifyDataSetChanged();
    }

Schreiben Sie viewpagerAdapter.notifyDataSetChanged (); in onResume () in MainActivity. Viel Glück :)

Handy Kim
quelle
-2

Einfachster Weg

Erstellen Sie eine öffentliche statische Methode, die viewpager.setAdapter enthält

Adapter und Viewpager statisch machen

public static void refreshFragments(){
        viewPager.setAdapter(adapter);
    }

Rufen Sie überall, jede Aktivität, jedes Fragment an.

MainActivity.refreshFragments();
Ryan Christoper Lucasan
quelle