Question onActivityResult n'est pas appelé dans Fragment


L'activité hébergeant ce fragment a son onActivityResult appelé lorsque l'activité de la caméra revient.

Mon fragment commence une activité pour un résultat avec l'intention envoyée à la caméra de prendre une photo. L'application d'image se charge bien, prend une photo et revient. le onActivityResult Cependant, il n'est jamais touché. J'ai défini des points d'arrêt, mais rien n'est déclenché. Un fragment peut-il avoir onActivityResult? Je le pense car c'est une fonction fournie. Pourquoi cela n'est-il pas déclenché?

ImageView myImage = (ImageView)inflatedView.findViewById(R.id.image);
myImage.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View view) {
        Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        startActivityForResult(cameraIntent, 1888);
    }
});

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if( requestCode == 1888 ) {
        Bitmap photo = (Bitmap) data.getExtras().get("data");
        ((ImageView)inflatedView.findViewById(R.id.image)).setImageBitmap(photo);
    }
}

685
2018-05-27 04:35


origine


Réponses:


L'activité d'hébergement remplace onActivityResult(), mais il n'a pas appelé super.onActivityResult() pour les codes de résultat non gérés. Apparemment, même si le fragment est celui qui fait la startActivityForResult() appel, l'activité obtient le premier coup à gérer le résultat. Cela a du sens quand vous considérez la modularité des fragments. Une fois que j'ai implémenté super.onActivityResult() Pour tous les résultats non gérés, le fragment a réussi à gérer le résultat.

Et aussi de @siqing répondre:

Pour obtenir le résultat dans votre fragment, assurez-vous d'appeler startActivityForResult(intent,111); au lieu de getActivity().startActivityForResult(intent,111); à l'intérieur de votre fragment.


1034
2018-05-27 04:42



Je pense que tu as appelé getActivity().startActivityForResult(intent,111);. Vous devriez appeler startActivityForResult(intent,111);.


297
2018-06-13 09:13



Option 1:

Si vous appelez startActivityForResult() du fragment alors vous devriez appeler startActivityForResult(), ne pas getActivity().startActivityForResult(), car il aboutira au fragment onActivityResult ().

Si vous n'êtes pas sûr de l'endroit où vous appelez startActivityForResult() et comment vous allez appeler les méthodes.

Option 2:

Puisque l'activité obtient le résultat de onActivityResult(), vous devrez remplacer l'activité onActivityResult() et appel super.onActivityResult() se propager au fragment correspondant pour les codes de résultats non gérés ou pour tous.

Si au-dessus de deux options ne fonctionnent pas, alors référez-vous à l'option 3 car cela fonctionnera certainement.

Option 3:

Un appel explicite du fragment à la fonction onActivityResult est le suivant.

Dans la classe Activity parent, remplacez la méthode onActivityResult () et remplacez la même dans la classe Fragment et appelez le code suivant.

Dans la classe parente:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.dualPane);
    fragment.onActivityResult(requestCode, resultCode, data);
}

Dans la classe des enfants:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // In fragment class callback
}

186
2018-06-12 09:17



J'ai ce même problème avec le ChildFragmentManager. Le gestionnaire ne transmettra pas le résultat au fragment imbriqué, vous devez le faire manuellement dans votre fragment de base.

public void onActivityResult(int requestCode, int resultCode, Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);
    Fragment fragment = (Fragment) getChildFragmentManager().findFragmentByTag(childTag);
    if (fragment != null) {
        fragment.onActivityResult(requestCode, resultCode, intent);
    }
}

70
2018-05-08 20:44



Dans le cas où vous ne connaissez pas les fragments de votre activité, il vous suffit de tous les énumérer et d'envoyer des arguments de résultat d'activité:

// In your activity
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    for (Fragment fragment : getSupportFragmentManager().getFragments()) {
        fragment.onActivityResult(requestCode, resultCode, data);
    }
}

63
2018-03-27 10:40



Message original.

FragmentActivity remplace requestCode par un modifié. Après cela, quand onActivityResult() sera invoqué, FragmentActivity analyse les 16 bits les plus élevés et restaure l'index du fragment original. Regardez ce schéma:

Enter image description here

Si vous avez quelques fragments au niveau de la racine, il n'y a pas de problèmes. Mais si vous avez fragments imbriqués, par exemple Fragment avec quelques onglets à l'intérieur ViewPager, toi garanti sera confronté à un problème (ou déjà fait face).

Car un seul index est stocké à l'intérieur requestCode. C'est l'indice de Fragment à l'intérieur de FragmentManager. Lorsque nous utilisons des fragments imbriqués, il y a des enfants FragmentManagers, qui ont leur propre liste de fragments. Donc, il est nécessaire de sauvegarder toute la chaîne d'indices, à partir de la racine FragmentManager.

Enter image description here

Comment pouvons-nous résoudre ce problème? Il existe une solution de contournement commune dans ce post.

GitHub: https://github.com/shamanland/nested-fragment-issue


53
2018-06-19 09:34



C'est l'un des problèmes les plus populaires. Nous pouvons trouver beaucoup de fil à propos de ce problème. Mais aucun d'eux n'est utile pour MOI.

J'ai donc résolu ce problème en utilisant cette solution.

Voyons d'abord pourquoi cela se passe.

Nous pouvons appeler startActivityForResult directement à partir de Fragment, mais en réalité mécanicien derrière sont tous gérés par Activité.

Une fois que vous appelez startActivityForResult à partir d'un fragment, requestCode sera modifié pour attacher l'identité de Fragment au code. Cela permettra à l'activité d'être en mesure de retracer qui envoie cette demande une fois le résultat reçu.

Une fois que l'activité a été reconduite, le résultat sera envoyé à la fonction onActivityResult d'Activity avec le requestCode modifié qui sera décodé à l'identité originale de requestCode + Fragment. Après cela, Activity enverra le résultat de l'activité à ce fragment via onActivityResult. Et tout est fini.

Le problème est:

L'activité peut envoyer le résultat uniquement au fragment qui a été attaché directement à l'activité, mais pas à l'imbriqué. C'est la raison pour laquelle onActiveResult du fragment imbriqué n'a jamais été appelé quoi qu'il arrive.

Solution: 

1) Commencez l'intention dans votre fragment par le code ci-dessous:

       /** Pass your fragment reference **/
       frag.startActivityForResult(intent, REQUEST_CODE); // REQUEST_CODE = 12345

2) Maintenant dans le remplacement de votre activité parent **onActivityResult() : **

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
    }

Vous devez appeler cela dans l'activité parentale pour le faire fonctionner.

3) Dans votre appel de fragment:

@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK) {

       }
}

C'est tout. Avec cette solution, il pourrait être appliqué à n'importe quel fragment, qu'il soit imbriqué ou non. Et oui, ça couvre aussi tout le cas! De plus, les codes sont aussi beaux et propres.


35
2017-09-01 09:12