2011-10-17 2 views
14

J'ai une application simple qui a deux fragments et en mode paysage, les deux fragments sont présentés côte à côte et en portrait, je montre le fragment A, puis si elles choisissent une option, démarrer une activité qui montre le fragment B. Mon problème est quand je suis en mode portrait et en montrant le fragment B, si l'utilisateur sélectionne une option de menu que je veux actualiser ou redessiner la vue qui est associée au fragment B et ne peux pas comprendre comment faire ce travail. J'ai essayé la méthode getView et la méthode getLayoutInflater mais l'écran ne change pas car je pense créer une nouvelle vue. J'ai également essayé d'obtenir une référence au fragment A en pensant que je pourrais appeler sa routine pour construire un nouveau fragment et remplacer le fragment B, mais je ne peux pas y faire référence parce qu'il n'est pas affiché. Ce que j'ai vraiment besoin de faire est de forcer la méthode onCreateView à être appelée à nouveau pour gonfler la nouvelle vue, mais j'ai essayé plusieurs méthodes pour essayer de le faire, mais je ne peux pas faire en sorte que onCreateView soit appelé à nouveau. Des pensées sur comment ça?Android force Fragment à reconstruire Voir

Répondre

1

si l'utilisateur sélectionne une option de menu que je veux rafraîchir ou redessiner la vue qui est associé à Fragment B et ne peut pas comprendre comment faire ce travail

En onOptionsItemSelected(), ont l'appel d'activité une méthode sur le fragment qui l'amène à mettre à jour ses widgets avec le nouveau contenu. Ou, demandez à l'activité d'exécuter un FragmentTransaction pour remplacer le fragment (si le fragment a été initialement configuré via un FragmentTransaction).

9

Vous souhaitez effectuer une FragmentTransaction et utiliser la méthode replace()

Cela ne devrait pas être trop difficile à faire, mais la réponse dépendra de l'endroit où le menu est situé (c.-à-est votre appel onOptionsItemSelected() à l'intérieur de votre activité parentale ou est-ce dans l'un ou l'autre des fragments A/B?). Supposons que, pour des raisons de simplicité, l'implémentation de votre menu et onOptionsItemSelected() se trouve dans l'activité parente et que vous souhaitiez remodeler les fragments si l'option menu_option1 est choisie. Il ressemblerait à quelque chose comme ceci:

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
// Handle item selection 
//... 
switch (item.getItemId()) { 
case R.id.menu_option1: 
    //do something 
    FragmentManager fragmentManager = getFragmentManager(); 
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 
    Fragment newFragment = new YourFragmentClass(); 
    FragmentTransaction transaction = getFragmentManager().beginTransaction(); 
    transaction.replace(R.id.your_fragment_id, newFragment); 
    transaction.addToBackStack(null); 
    transaction.commit(); 
    return true; 
case R.id.menu_option2: 
    //do something else; 
    return true; 
default: 
    return super.onOptionsItemSelected(item); 
} 
} 

Sinon, si votre menu est un enfant d'un de vos fragments (ce qui devrait être pour le bien de plus de code réutilisable), puis une méthode consiste à exiger que l'activité d'accueil implémenter une interface définie par le fragment, qui peut être utilisée comme rappel. Et dans le rappel onOptionsItemSelected() à l'intérieur de votre classe de fragment, vous effectuez simplement un appel à cette méthode de rappel.

Bien que cela ressemble à une bouchée, vous n'avez vraiment besoin de faire quelques choses. Imaginez que cela est votre Fragment classe

public static class FragmentA extends ListFragment { 
OnSelectedListener mListener; 
// Container Activity must implement this interface 
public interface OnSelectedListener { 
    public void onSelected(); 
} 
... 
@Override 
public void onAttach(Activity activity) { 
    super.onAttach(activity); 
    //This is to ensure that the Activity has implemented the interface we set up above 
    try { 
     mListener = (OnSelectedListener) activity; 
    } catch (ClassCastException e) { 
     throw new ClassCastException(activity.toString() + " must implement OnSelectedListener"); 
    } 
} 
@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
// Handle item selection 
//... 
switch (item.getItemId()) { 
case R.id.menu_option1: 
    //do something 
    getActivity().onSelected(); 
    return true; 
case R.id.menu_option2: 
    //do something else; 
    return true; 
default: 
    return super.onOptionsItemSelected(item); 
} 
} 
... 
} 

Puis dans l'activité, vous verrez quelque chose comme:

public class MainActivity extends Activity implements FragmentA.onSelectedListener{ 
... 
public void onSelected(){ 
    FragmentManager fragmentManager = getFragmentManager(); 
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 
    Fragment newFragment = new YourFragmentClass(); 
    FragmentTransaction transaction = getFragmentManager().beginTransaction(); 
    transaction.replace(R.id.your_fragment_id, newFragment); 
    transaction.addToBackStack(null); 
    transaction.commit(); 
} 
} 
+7

Lorsque vous remplacez R.id.your_fragment_id, vous assumez qu'il a été déclaré en XML . Mais que se passe-t-il si mon fragment original a été construit par programmation? –

+1

@IgorGanapolsky ce sera l'identifiant du conteneur de ce fragment – dmSherazi