Rafraîchir le fragment au rechargement

110

Dans une application Android, je charge les données d'un Db dans un TableViewfichier Fragment. Mais lorsque je recharge le, Fragmentil affiche les données précédentes. Puis-je repeupler le Fragmentavec les données actuelles au lieu des données précédentes?

Samantha Withanage
la source
montrez-nous du code s'il vous plaît. Où chargez-vous vos données, où commencez-vous votre fragment, où stockez-vous vos valeurs?
AS
Cela devrait résoudre le problème que vous venez de décrire: stackoverflow.com/questions/6503189/…
Benjamin W.
s'il vous plaît fournir plus d'extrait de code info
nikvs
Essayez d'utiliser Swipe-to-Refresh vers votre application voir ce stackoverflow.com/questions/41469040/fragment-refresh/…
Imtiaz Mamun

Réponses:

207

Je pense que vous souhaitez actualiser le contenu du fragment lors de la mise à jour de la base de données

Si tel est le cas, détachez le fragment et rattachez-le

// 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 est le nom que vous avez donné à votre fragment lors de sa création

Ce code est pour la bibliothèque de support.

Si vous ne prenez pas en charge les anciens appareils, utilisez simplement getFragmentManager au lieu de getSupportFragmentManager

[ÉDITER]

Cette méthode nécessite que le fragment ait une balise.
Si vous ne l'avez pas, la méthode de @ Hammer est ce dont vous avez besoin.

Phantômaxx
la source
3
Cela donne l'erreur suivante - java.lang.RuntimeException: Échec de la livraison du résultat ResultInfo {who = null, request = 2, result = 3, data = null} à l'activité {xont.virtusel.v4.controller / xont.virtusel.v4.controller .sale.InvocieBrandActivity}: java.lang.IllegalStateException: Impossible d'effectuer cette action après onSaveInstanceState
Samantha Withanage
1
@Elizabeth assurez-vous que votre Fragment a un tag correctement défini
Phantômaxx
1
@Rotwang Merci pour votre réponse J'ai juste pris un raccourci plutôt que de faire le code long, mais cela a aidé à
ouvrir
1
Cette solution ne fonctionne plus dans la nouvelle version de support-v4-library (25.1.0). Explication ici: stackoverflow.com/questions/41270858/…
Brahim Bouaboud
1
Attention: cette astuce ne fonctionne sur Oreo que si vous utilisez des fragments de support!
courses
146

Cela rafraîchira le fragment actuel:

FragmentTransaction ft = getFragmentManager().beginTransaction();
if (Build.VERSION.SDK_INT >= 26) {
   ft.setReorderingAllowed(false);
}
ft.detach(this).attach(this).commit();
Mbengue Assane
la source
1
où mettre ce code? activité intérieure ou fragment lui-même?
Narendra Singh
2
Vous le mettez dans le fragment qui doit être rafraîchi.
Mbengue Assane
1
@SagarChavada où avez-vous mis le code? Vous devez le placer dans un événement ponctuel, comme lorsque les données sont actualisées.
Mbengue Assane
5
Recursion, récursion, appels sans fin
zulkarnain shah
2
L'utilisation de ceci crée dans onResume dans le fragment fait une boucle, comment l'éviter?
Soul
32

Si vous n'avez pas la balise fragment, le code suivant fonctionne bien pour moi.

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();}
}
Marteau
la source
1
quel sera l'identifiant du fragment, je n'ai déclaré nulle part l'identifiant du fragment. Comment et où le déclarer?
Narendra Singh
Je n'arrive pas à l'utiliser getActivity()dans mon activité. Dois-je utiliser Activity.this...?
Si8 du
@NarendraJi, c'est uniquement l'ID FrameLayout qui est l'endroit où vous placez vos fragments dans le conteneur.
Lokesh
Veuillez supprimer cette accolade supplémentaire. Cela m'a causé beaucoup de problèmes.
Abhishek
9

vous pouvez actualiser votre fragment lorsqu'il est visible par l'utilisateur, ajoutez simplement ce code dans votre fragment, cela actualisera votre fragment lorsqu'il sera visible.

@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
la source
si lent que cela prend 3 secondes jusqu'à ce qu'il se recharge
Omar Boshra
Cela semble bien fonctionner avec l'adaptateur
Viewpager
2
setUserVisibleHint est obsolète
Sai Aditya
A travaillé pour moi, merci pour la solution.
hetsgandhi le
7

Pour actualiser le fragment, la réponse acceptée ne fonctionnera pas sur Nougat et la version supérieure. Pour le faire fonctionner sur tous les systèmes d'exploitation, vous pouvez faire ce qui suit.

    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
la source
5

Vous ne pouvez pas recharger le fragment lorsqu'il est attaché à une activité, où vous obtenez une Fragment Already Addedexception " ".

Le fragment doit donc d'abord être détaché de son activité, puis attaché. Tout peut être fait en utilisant l'API fluent sur une seule ligne:

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

Mise à jour: il s'agit d'intégrer les modifications apportées à l'API 26 et au-dessus:

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

Pour plus de description de la mise à jour, veuillez consulter https://stackoverflow.com/a/51327440/4514796

Ali Nem
la source
2
Veuillez fournir votre réponse avec des descriptions claires. N'écrivez pas le code, donnez l'explication sur le code que vous avez partagé, afin que les autres puissent également comprendre et cela sera utile. Je vous demande de lire la section FAQ afin d'utiliser Stack Overflow de manière efficace.
Sankar Ganesh
3
   MyFragment fragment = (MyFragment) getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG);
        getSupportFragmentManager().beginTransaction().detach(fragment).attach(fragment).commit();

cela ne fonctionnera que si vous utilisez FragmentManagerpour initialiser le fragment. Si vous l'avez <fragment ... />en XML, il ne l'appellera onCreateViewplus. J'ai gaspillé mes 30 minutes pour comprendre cela.

Irshu
la source
1

Voici ce que j'ai fait et cela a fonctionné pour moi, j'utilise Firebase et lorsque l'utilisateur se connecte, je voulais d'abord actualiser le fragment actuel, vous devrez d'abord demander le contexte de l'activité car le fragment n'a pas de moyen d'obtenir le contexte à moins que vous ne le définissiez à partir de l'activité ou du contexte ici est le code que j'ai utilisé et travaillé en langage kotlin, je pense que vous pourriez utiliser le même en 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()
        }
    }

}
hardiBSalih
la source
0

Utilisez a ContentProvideret chargez vos données à l'aide d'un 'CursorLoader'. Avec cette architecture, vos données seront automatiquement rechargées lors des changements de base de données. Utilisez des frameworks tiers pour votre ContentProvider- vous ne voulez pas vraiment l'implémenter vous-même ...

artkoenig
la source
0

J'ai eu le même problème mais aucun des éléments ci-dessus n'a fonctionné pour le mien. soit il y avait un problème de backstack (après le chargement lorsque l'utilisateur appuyait, il reviendrait au même fragment) ou il n'a pas appelé leonCreaetView

enfin j'ai fait ceci:

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

le bon point est que vous n'avez pas non plus besoin de la balise ou de l'identifiant du fragment. si vous voulez recharger

Emad
la source
0

Utilisez la méthode onResume ... à la fois sur l'activité du fragment et sur l'activité contenant le fragment.

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

GeneralInfo c'est ma classe Fragment GeneralInfo.java

Je l'ai mis comme méthode dans la classe fragment:

public void Reload(){
    getActivity().getSupportFragmentManager().beginTransaction().replace(LogActivity.this.getId(), new LogActivity()).commit();
}
Brayan Steven Martínez Vanegas
la source
0

Par exemple avec TabLayout: implémentez simplement OnTabSelectedListener. Pour recharger la page, vous pouvez utiliser implémenter SwipeRefreshLayout.OnRefreshListener iepublic class YourFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {

la méthode onRefresh () sera @Override depuis l'interface ie:

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

Voici la mise en page:

<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" />

Code dans votre activité

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) {

        }
    });
Guy JavaEE
la source
-2
protected void onResume() {
        super.onResume();
        viewPagerAdapter.notifyDataSetChanged();
    }

Écrivez viewpagerAdapter.notifyDataSetChanged (); dans onResume () dans MainActivity. Bonne chance :)

Kim pratique
la source
-2

Le moyen le plus simple

créer une méthode statique publique contenant viewpager.setAdapter

rendre l'adaptateur et le viewpager statiques

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

appelez n'importe où, n'importe quelle activité, n'importe quel fragment.

MainActivity.refreshFragments();
ryan christoper lucasan
la source