Aggiorna frammento alla ricarica


110

In un'applicazione Android sto caricando i dati da un Db in TableViewun file Fragment. Ma quando lo ricarico Fragmentmostra i dati precedenti. Posso ripopolare Fragmentcon i dati attuali invece che con i dati precedenti?


mostraci un codice per favore. Dove carichi i tuoi dati, dove inizi il tuo frammento, dove memorizzi i tuoi valori?
AS

Questo dovrebbe risolvere il problema descritto Porly: stackoverflow.com/questions/6503189/...
Benjamin W.

si prega di fornire più frammento di codice
informativo

Prova a utilizzare Swipe-to-Refresh per la tua app vedi questo stackoverflow.com/questions/41469040/fragment-refresh/…
Imtiaz Mamun

Risposte:


207

Penso che tu voglia aggiornare il contenuto del frammento all'aggiornamento del db

In tal caso, staccare il frammento e ricollegarlo

// 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 è il nome che hai dato al tuo frammento quando lo hai creato

Questo codice è per la libreria di supporto.

Se non stai supportando i dispositivi più vecchi, usa semplicemente getFragmentManager invece di getSupportFragmentManager

[MODIFICARE]

Questo metodo richiede che il frammento abbia un tag.
Nel caso in cui non ce l'hai, il metodo di @ Hammer è ciò di cui hai bisogno.


3
Questo dà il seguente errore - java.lang.RuntimeException: mancata consegna del risultato ResultInfo {who = null, request = 2, result = 3, data = null} all'attività {xont.virtusel.v4.controller / xont.virtusel.v4.controller .sale.InvocieBrandActivity}: java.lang.IllegalStateException: impossibile eseguire questa azione dopo onSaveInstanceState
Samantha Withanage

1
@Elizabeth assicurati che il tuo frammento abbia un tag impostato correttamente
Phantômaxx

1
@Rotwang Grazie per la tua risposta Ho appena preso una scorciatoia piuttosto che fare il codice lungo ma questo ha aiutato ad
aprire

1
Questa soluzione non funziona più nella nuova versione di support-v4-library (25.1.0). Spiegazione qui: stackoverflow.com/questions/41270858/...
Brahim Bouaboud

1
Attenzione: questo trucco funziona su Oreo solo se stai usando frammenti di supporto!
gare il

146

Questo aggiornerà il frammento corrente:

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

1
dove mettere questo codice? all'interno dell'attività o del frammento stesso?
Narendra Singh

2
Lo metti all'interno del frammento che deve essere aggiornato.
Mbengue Assane

1
@SagarChavada dove hai messo il codice? Devi inserirlo in un evento occasionale come quando i dati vengono aggiornati.
Mbengue Assane

5
Ricorsione, ricorsione, chiamate infinite
zulkarnain shah

2
Usando questo crea all'interno di onResume nel frammento si crea un ciclo, come evitarlo?
Soul

32

Nel caso in cui non si disponga del tag fragment, il codice seguente funziona bene per me.

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();}
}

1
quale sarà l'ID del frammento, non ho dichiarato l'ID del frammento da nessuna parte. Come e dove dichiararlo?
Narendra Singh

Non riesco a utilizzarlo getActivity()nella mia attività. Dovrei usare Activity.this...?
Si8

@NarendraJi è solo l'id FrameLayout che è dove metti i tuoi frammenti nel contenitore.
Lokesh

Si prega di rimuovere quel tutore in più. Mi ha causato molti problemi.
Abhishek

9

puoi aggiornare il tuo frammento quando è visibile all'utente, basta aggiungere questo codice nel tuo frammento questo aggiornerà il tuo frammento quando sarà visibile.

@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");
    }
}

così lento ci vogliono 3 secondi fino a quando non si ricarica
Omar Boshra

Questo sembra funzionare bene con l'adattatore
viewpager

2
setUserVisibleHint è deprecato
Sai Aditya

Ha funzionato per me, grazie per la soluzione.
hetsgandhi

7

Per aggiornare il frammento la risposta accettata non funzionerà su Nougat e versioni successive. Per farlo funzionare su tutti i sistemi operativi puoi fare quanto segue.

    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();
    }

5

Non puoi ricaricare il frammento mentre è collegato a un'attività, dove " Fragment Already Added" si ottiene un'eccezione.

Quindi il frammento deve essere prima staccato dalla sua attività e poi attaccato. Tutto può essere fatto utilizzando l'api fluente in una riga:

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

Aggiornamento: questo per incorporare le modifiche apportate all'API 26 e versioni successive:

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

Per una descrizione più dettagliata dell'aggiornamento, consultare https://stackoverflow.com/a/51327440/4514796


2
Fornisci la tua risposta con descrizioni chiare. Non scrivere il codice, dai la spiegazione del codice che hai condiviso, in modo che anche gli altri possano capire e sarà utile. Ti chiedo di leggere la sezione FAQ per utilizzare Stack Overflow in modo efficace.
Sankar Ganesh,

3
   MyFragment fragment = (MyFragment) getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG);
        getSupportFragmentManager().beginTransaction().detach(fragment).attach(fragment).commit();

questo funzionerà solo se si usa FragmentManagerper inizializzare il frammento. Se lo hai <fragment ... />in XML, non chiamerà di onCreateViewnuovo. Ho sprecato i miei 30 minuti per capirlo.


1

Ecco cosa ho fatto e ha funzionato per me, uso Firebase e quando l'utente effettua l'accesso, volevo aggiornare prima il frammento corrente, dovrai prima richiedere il contesto dall'attività perché il frammento non ha un modo per ottenere il contesto a meno che tu non lo imposti da Attività o contesto qui è il codice che ho usato e lavorato in linguaggio kotlin penso che potresti usare lo stesso nella classe java

   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()
        }
    }

}

0

Usa ContentProviderae carica i tuoi dati usando un 'CursorLoader'. Con questa architettura i tuoi dati verranno ricaricati automaticamente alle modifiche del database. Usa framework di terze parti per il tuo ContentProvider- non vuoi davvero implementarlo da solo ...


0

Ho avuto lo stesso problema ma nessuno dei precedenti ha funzionato per il mio. o si è verificato un problema di backstack (dopo il caricamento, quando l'utente ha premuto indietro, sarebbe andato di nuovo lo stesso frammento) o non ha chiamato ilonCreaetView

finalmente l'ho fatto:

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();
}

il punto positivo è che non hai bisogno del tag o dell'ID del frammento. se vuoi ricaricare


0

Utilizza il metodo onResume ... sia sull'attività del frammento che sull'attività che contiene il frammento.


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

GeneralInfo è la mia classe Frammento GeneralInfo.java

L'ho inserito come metodo nella classe fragment:

public void Reload(){
    getActivity().getSupportFragmentManager().beginTransaction().replace(LogActivity.this.getId(), new LogActivity()).commit();
}

0

Ad esempio con TabLayout: implementa semplicemente OnTabSelectedListener. Per ricaricare la pagina, puoi utilizzare implement SwipeRefreshLayout.OnRefreshListener iepublic class YourFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {

il metodo onRefresh () sarà @Override dall'interfaccia, ovvero:

@Override
public void onRefresh() {
 loadData();
}

Ecco il layout:

<com.google.android.material.tabs.TabLayout
    android:id="@+id/tablayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/colorPrimaryLighter"
    app:tabGravity="fill"
    app:tabIndicatorColor="@color/white"
    app:tabMode="fixed"
    app:tabSelectedTextColor="@color/colorTextPrimary"
    app:tabTextColor="@color/colorTextDisable" />

Codice nella tua attività

TabLayout tabLayout = (TabLayout) findViewById (R.id.tablayout); tabLayout.setupWithViewPager (viewPager);

    tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            if (tab.getPosition() == 0) {
                yourFragment1.onRefresh();
            } else if (tab.getPosition() == 1) {
                yourFragment2.onRefresh();
            }
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    });

-2
protected void onResume() {
        super.onResume();
        viewPagerAdapter.notifyDataSetChanged();
    }

Scrivi viewpagerAdapter.notifyDataSetChanged (); in onResume () in MainActivity. In bocca al lupo :)


-2

Il modo più semplice

crea un metodo statico pubblico contenente viewpager.setAdapter

rendere statici l'adattatore e il viewpager

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

chiama ovunque, qualsiasi attività, qualsiasi frammento.

MainActivity.refreshFragments();
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.