Comment changer la vue dans un fragment?

J’ai un fragment qui crée sa vue dans onCreateView comme prévu. Cependant, je veux changer la vue périodiquement.

Mon cas d’utilisation est que le fragment affiche certaines données d’un service Web. Lorsqu’un utilisateur choisit une option dans une liste (un autre fragment), ce fragment doit basculer vers une barre de progression, puis une fois chargé, retournez à la vue des données.

Je pourrais faire deux fragments – le fragment de chargement et le fragment d’affichage, mais il semble que, puisqu’il s’agit d’un événement encapsulé, je préfère tout faire à l’intérieur du fragment.

Fondamentalement, ce que je demande, c’est ce qu’est l’équivalent de setContentView dans un fragment.

Vous pouvez utiliser Fragment.getView() . Cela renvoie la vue du conteneur qui contient le Fragment . Sur cette vue, vous pouvez appeler removeAllViews . Ensuite, créez vos nouvelles vues et ajoutez-les à la vue obtenue à partir de getView() .

http://developer.android.com/reference/android/app/Fragment.html#getView ()

Si, pour une raison quelconque, vous souhaitez modifier la vue entière du fragment (par exemple, une demande d’URL asynchrone qui modifie la vue en cas de succès), vous pouvez utiliser FragmentTransaction dans l’activité parente et créer un nouveau fragment à la volée.

Ou vous pouvez conserver le fragment et appeler une méthode de ce fragment qui se rafraîchira. Exemple: Dans l’activité parent, je List mFragmentList et stocke une liste de fragments List mFragmentList .

Voici la classe RefreshFragment (et tous mes fragments étendent celui-ci dans mon exemple):

 public class RefreshFragment extends Fragment { protected Data data; // here your asynchronously loaded data public void setData(Data data) { this.data = data; // The reload fragment code here ! if (! this.isDetached()) { getFragmentManager().beginTransaction() .detach(this) .attach(this) .commit(); } } } 

Ensuite, dans mon activité, le rappel asynchrone, je peux appeler:

 for (RefreshFragment f : mFragmentList) f.setData(data); 

Ainsi, chaque fragment sera mis à jour avec les données correctes et le fragment actuellement connecté sera mis à jour immédiatement. Vous devez vous fournir votre propre onCreateView dans les fragments bien sûr.

L’important est qu’un fragment puisse se recharger avec getFragmentManager() .

Vous pouvez utiliser un FrameLayout pour basculer entre votre barre de progression et la vue des données, par exemple

      

Dans onViewCreate() vous onViewCreate() alors les deux vues dans des champs d’instance

 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { ... image = (ImageView) container.findViewById(R.id.cover_image); progress = container.findViewById(R.id.cover_progress); ... } 

et chaque fois que vous voulez basculer entre les deux (n’oubliez pas de le faire dans votre interface utilisateur / thread principal), faites simplement quelque chose comme:

 progress.setVisibility(View.INVISIBLE); image.setVisibility(View.VISIBLE); 

Créer une vue par défaut “factice”

    

Gonflez la vue par défaut “factice” dans la méthode onCreateView du fragment et utilisez-la comme espace réservé pour append des vues si nécessaire

 private LayoutInflater mInflater; private ViewGroup mContainer; @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState){ mInflater = inflater; mContainer = container; View v =inflater.inflate(R.layout.home_view,container,false); placeholder = (ViewGroup) v; return placeholder; } 

Pour changer la vue en une nouvelle vue, vous devez d’abord supprimer toutes les vues précédentes, puis gonfler la nouvelle vue et append

 View newView = mInflater.inflate(R.layout.custom_dash, mContainer, false); placeholder.removeAllViews(); placeholder.addView(newView); 

U peut utiliser Transaction remove et add. J’ai utilisé un fragment dans lequel je peux charger n’importe quelle vue. Le constructeur du fragment doit avoir un nombre entier, cet entier est R.layout …. Je retire simplement l’ancien fragment et en met un nouveau. !!! Cela ne fonctionne que si vous faites de ce fragment une dynamic et pas dans la mise en page XML. Il suffit de créer quelque chose comme un LinearLayout R.id.fragment_layout

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.wundlist_fragmente); Log.v("WoundListActivity", "WoundListActivity gestartet..."); Log.v("WoundListActivity", "Liste..."); //dynamisch hinzufügen... wlf=new WoundListFragment(); fm.beginTransaction().add(R.id.fragment_layout,wlf).commit(); } //If Menubutton Clicked change @Override public boolean onOptionsItemSelected(MenuItem item) { if(item.getItemId()==R.id.itemaddwound){ Log.v("List", "neue Wunde Activity"); fm.beginTransaction().remove(wlf).commit(); fm.beginTransaction().add(R.id.fragment_layout, new NewWoundFragment()).commit(); } return super.onOptionsItemSelected(item); } 

En utilisant la réponse de Solostaran14s je le fais maintenant:

Interface:

 public interface FragmentReattachListener { public void reAttach(); } 

Fragment:

 public class MyFragment extends Fragment implements FragmentReattachListener { //... @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { //... App.registerFragmentReattachListener(this); //... } //... @Override public void reAttach() { FragmentManager f = getFragmentManager(); if (f != null) { f.beginTransaction() .detach(this) .attach(this) .commit(); } } } 

à partir de la classe d’application:

 private static void reattachFragments() { if (fragmentReattachListeners.size() > 0) { for (FragmentReattachListener listener : fragmentReattachListeners) { listener.reAttach(); } } } 

Voici une solution plus simple: sauvegardez le composant et le conteneur que vous recevez dans onCreateView et utilisez-les plus tard. Par exemple:

 private LayoutInflater mInflater; private ViewGroup mRootView; public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { mInflater = inflater; mRootView = container; return null; } public void someCallBackLater() { // mRootView.removeAllViews(); // in case you call this callback again... mInflater.inflate(R.layout.my_layout, mRootView); } 

Ce qui a fonctionné pour moi:

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View v = inflater.inflate(R.layout.fragment_recipe, container, false); Button recipeBuyButton = (Button) v.findViewById( R.id.recipe_buy_button); Typeface tf = Typeface.createFromAsset(getActivity().getAssets(), "fonts/GE_SS_Two_Medium.otf"); recipeBuyButton.setTypeface(tf); return v; 

J’ai le même problème, fragment.getView () retourne toujours null, bien que Fragment.onCreateView ait déjà été appelé avant

nous ne pouvons pas modifier le contenu de fragment à l’exécution car mon fragment a été ajouté à ViewPager, alors j’essaie d’utiliser une autre méthode pour obtenir la vue:

  View view = viewPager.getChildAt(0); TextView text = (TextView) (view.findViewById(R.id.textView)); text.setText("12345"); 

Ce problème maintenant a été résolu, j’espère peut vous aider