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.