2015-07-16 1 views
2

Je viens de passer un ancien projet Android d'Eclipse à Android Studio et dans ce processus j'ai mis à jour de l'ancienne version des bibliothèques de support 19.0.1 à 22.2.0. Après cela, je reçois quelques erreurs dans mon code de travail. J'ai téléchargé tous les SDK entre et vérifié où l'erreur est entré en jeu, et il semble être dans la version 21.1.0 et ci-dessus. J'ai regardé dans le release notes pour cette version, mais je n'ai rien trouvé d'intéressant. Mon erreur est que j'obtiens un NullPointerException ici. Notez que cette méthode fait partie de Activity, pas le parent Fragment.Android: NullPointerException en utilisant findFragmentById() après l'amélioration des bibliothèques de support

public synchronized void onRecipesFiltered(ArrayList<Recipe> filteredRecipes) 
{ 
    FilteredRecipesListFragment filteredRecipesListFragment = (FilteredRecipesListFragment) 
     getSupportFragmentManager().findFragmentById(R.id.mm_filtered_recipes_list_fragment); 

    // filteredRecipesListFragment becomes null 
    filteredRecipesListFragment.onRecipesFiltered(filteredRecipes); 
} 

Le Fragment Je reçois ici est un ListFragment qui fait partie d'un fichier XML qui est gonflé au démarrage de l'application. Il semble que ce ListFragment est ajouté à un à l'intérieur le parent Fragment pendant le gonflage. C'est probablement pourquoi je reçois un nullpointer tout en obtenant le FragmentManager du Activity. Ainsi, ma question est:

Comment puis-je obtenir le ListFragment dans le Activity? Est-il nécessaire de garder une référence au parent Fragment pour obtenir le ListFragment à travers son FragmentManager? Le parent Fragment est gonflé en renvoyant new MyFragment() en FragmentPagerAdapter#getItem(), nulle part ailleurs, d'où il est un peu plus difficile d'obtenir la référence correcte dans le Activity.

Il y a encore une chose à noter: J'ai vu quelques messages me disant que je devrais mettre à jour à JDK 1.7, ce que j'ai fait (OpenJDK 1.7). Je ne me souviens pas de ce que j'ai fait, mais sous "Bibliothèques externes", je vois <1.7> (/usr/lib/jvm/java-1.7.0-openjdk-amd64). Je ne sais pas si cela compte.

Répondre

1

je résolu le problème en suivant this réponse. Il semble qu'il n'est pas vraiment possible d'obtenir les Fragment s du ViewPager d'une manière jolie, par conséquent ils doivent être gardés comme références après la création et récupérés si nécessaire. Je copie le code principal de la réponse ici, juste au cas où. L'idée principale est de garder le Fragment dans le SparseArray pour les récupérer si nécessaire. Ils doivent être insérés et retirés après la création/avant le retrait.

public class MyPagerAdapter extends FragmentStatePagerAdapter { 
    SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>(); 

    public MyPagerAdapter(FragmentManager fm) { 
     super(fm); 
    } 

    @Override 
    public int getCount() { 
     return ...; 
    } 

    @Override 
    public Fragment getItem(int position) { 
     return MyFragment.newInstance(...); 
    } 

    @Override 
    public Object instantiateItem(ViewGroup container, int position) { 
     Fragment fragment = (Fragment) super.instantiateItem(container, position); 
     registeredFragments.put(position, fragment); 
     return fragment; 
    } 

    @Override 
    public void destroyItem(ViewGroup container, int position, Object object) { 
     registeredFragments.remove(position); 
     super.destroyItem(container, position, object); 
    } 

    public Fragment getRegisteredFragment(int position) { 
     return registeredFragments.get(position); 
    } 
} 

Après avoir fait cela je pourrais réécrire ma méthode à la suivante, en utilisant getChildFragmentManager() comme indiqué par @Skizo:

public synchronized void onRecipesFiltered(ArrayList<Recipe> filteredRecipes) 
{ 
    MyPagerAdapter myPagerAdapter = (MyPagerAdapter) mMyViewPager.getAdapter(); 
    FilteredRecipesFragment filteredRecipesFragment = (FilteredRecipesFragment) 
      myPagerAdapter.getRegisteredFragment(PagerConstants.PAGE_FILTER_RECIPES); 

    if (filteredRecipesFragment == null) 
    { 
     // Fragments that has not yet been instantiated will be returned as null. Cannot do anything about it. 
     // Should be fairly unlikely. See: 
     // https://stackoverflow.com/a/15261142/1139324 
     return; 
    } 

    FilteredRecipesListFragment listFragment = (FilteredRecipesListFragment) 
      filteredRecipesFragment.getChildFragmentManager().findFragmentById(R.id.mm_filtered_recipes_list_fragment); 
    listFragment.onRecipesFiltered(filteredRecipes); 
} 
0

Essayez de remplacer:

FilteredRecipesListFragment filteredRecipesListFragment = (FilteredRecipesListFragment) 
    getSupportFragmentManager().findFragmentById(R.id.mm_filtered_recipes_list_fragment); 

à:

FilteredRecipesListFragment filteredRecipesListFragment = (FilteredRecipesListFragment) 
    getChildFragmentManager().findFragmentById(R.id.mm_filtered_recipes_list_fragment); 

En savoir plus sur getChildFragmentManager() sur le getChildFragmentManager() documentation

+0

Cela signifie que je dois garder une référence au parent 'Fragment' quelque part être capable d'appeler 'getChildFragmentManager()'. La méthode dans la question est placée dans l'activité pour agir comme une passerelle entre l'activité et ses fragments.I * pourrait * garder une référence au 'Fragment' parent, mais cela fait partie d'un' FragmentPagerAdapter', donc il n'est pas si facile de contenir une référence parce que 'FragmentPagerAdapter # getItem()' renvoie 'new FilteredRecipesFragment()'. Quelle est la meilleure façon de procéder? –

+0

Je suis à court d'idées ... laissez-moi y penser –