---
title: "Transmettre des données aux flows dans le SDK Android"
description: "Transmettez une valeur depuis votre application Android à un flow, et affichez-la dans un élément texte."
---

> **AI agents**: to search Adapty docs faster and with fewer tokens, install the Adapty skill. Claude Code (self-updating via plugin): `claude plugin marketplace add adaptyteam/adapty-skills && claude plugin install adapty-skills@adapty` — other tools: `npx skills add adaptyteam/adapty-skills --all`

Un [tag personnalisé](flow-custom-tags) est une variable personnalisée dont la valeur provient de votre application. Après avoir sélectionné **Value comes from outside the app** dans les paramètres d'une variable, votre application peut définir sa valeur via le SDK Adapty. Par exemple, un élément texte contient « Coins: » et un tag personnalisé. Si votre application transmet « 120 » pour ce tag, les utilisateurs voient « Coins: 120 ».

## Avant de commencer \{#before-you-start\}

Vous avez besoin du SDK Adapty v4 ou version ultérieure. Les versions antérieures à v4 n'affichent pas les flows.

## Ajouter des balises personnalisées au flow \{#add-custom-tags-to-the-flow\}

Pour afficher les valeurs de votre application dans un flow, configurez des tags personnalisés dans le builder :

1. [Créez un tag personnalisé](flow-custom-tags#create-a-custom-tag) pour chaque valeur que votre application transmet.

   <ZoomImage id="flow-custom-tag-create.webp" width="500px" alt="Formulaire de création de variable avec un nom, une description, le type de valeur String et une valeur initiale" />

2. [Insérez chaque tag dans un élément texte](flow-custom-tags#add-a-custom-tag-to-a-text-element).
3. Notez le nom complet de chaque tag, groupe compris. Le code de votre application transmet chaque valeur sous ce nom. Par exemple, si le groupe `user` contient un tag `streak`, le nom complet du tag est `user.streak`.

   <ZoomImage id="flow-custom-tag-full-name.webp" width="500px" alt="Onglet personnalisé du menu déroulant Ajouter une variable avec le tag streak dans le groupe user" />

## Passer des valeurs de balises personnalisées \{#pass-custom-tag-values\}

Créez un `AdaptyUiTagResolver` et passez-le dans le paramètre `tagResolver` de `AdaptyUI.getFlowView`. Le SDK appelle le resolver avec le nom complet de chaque balise personnalisée, par exemple `user.streak`. Le resolver retourne l'une des valeurs suivantes :

- **Une chaîne de caractères** : l'utilisateur la voit à la place de la balise. Elle doit être lisible, comme "1 250", et non "1250.0". Adapty ne la formate ni ne la traduit.
- **`null`** : l'utilisateur voit la valeur initiale de la balise comme valeur de substitution.
- **Une chaîne vide** : l'utilisateur ne voit rien à la place de la balise.

<Tabs groupId="current-os" queryString>
<TabItem value="kotlin" label="Kotlin" default>

```kotlin showLineNumbers title="Kotlin"
val customTags = mapOf(
    "username" to "DragonSlayer42",
    "coins" to "1,250",
)
val tagResolver = AdaptyUiTagResolver { tag -> customTags[tag] }

val flowView = AdaptyUI.getFlowView(
    activity,
    flowConfiguration,
    products = null,
    eventListener = eventListener,
    tagResolver = tagResolver,
)
```

</TabItem>
<TabItem value="java" label="Java">

```java showLineNumbers title="Java"
Map<String, String> customTags = new HashMap<>();
customTags.put("username", "DragonSlayer42");
customTags.put("coins", "1,250");
AdaptyUiTagResolver tagResolver = customTags::get;

AdaptyFlowView flowView = AdaptyUI.getFlowView(
        activity,
        flowConfiguration,
        null,
        eventListener,
        AdaptyFlowInsets.Unspecified,
        AdaptyCustomAssets.Empty,
        tagResolver
);
```

</TabItem>
</Tabs>

Si vous créez `AdaptyFlowView` vous-même, passez le resolver à sa méthode `showFlow`. Dans Jetpack Compose, passez-le à `AdaptyFlowScreen`. Pour un exemple de chaque appel, consultez [Afficher les flows et paywalls](android-present-paywalls).

Pour tester vos tags personnalisés, ouvrez le flow dans votre application, après avoir ajouté le code qui définit leurs valeurs. Le canevas du builder et l'[aperçu sur les appareils](paywall-device-compatibility-preview#preview-on-devices) n'affichent que les valeurs initiales : l'application mobile Adapty ne définit pas les valeurs des tags personnalisés.

Si votre application définit déjà des valeurs de tags personnalisés pour les anciens paywalls du Paywall Builder, consultez [comment les tags personnalisés dans les flows diffèrent](migrate-to-flows#custom-tags-from-the-old-paywall-builder).

## Ce que les utilisateurs voient sans valeur \{#what-users-see-without-a-value\}

Les utilisateurs voient la **valeur initiale** d'un tag personnalisé en guise de valeur de secours dans les cas suivants :

- Votre application ne transmet aucune valeur pour le tag.
- L'utilisateur n'a pas mis à jour votre application vers une version qui transmet la valeur.
- Le nom dans le code de votre application ne correspond pas au nom complet du tag, y compris la casse.
- Un autre tag personnalisé dans le même élément de texte n'a pas de valeur. Dans ce cas, tous les tags personnalisés de cet élément de texte affichent leur valeur initiale.

Pour n'afficher rien à la place d'un tag, transmettez une chaîne vide. Adapty considère une chaîne vide comme une valeur, donc la valeur de secours n'apparaît pas.

## Exemple : afficher un IMC à partir des réponses de l'onboarding \{#example-show-a-bmi-from-onboarding-answers\}

Un flow peut collecter des réponses des utilisateurs, et un tag personnalisé peut afficher une valeur provenant de votre application. Combinez les deux pour montrer aux utilisateurs un résultat que votre application calcule à partir de leurs réponses, comme un score, un plan recommandé ou une métrique de santé :

1. Un flow collecte les réponses et les envoie à votre application.
2. Votre application calcule le résultat.
3. Votre application transmet le résultat au flow suivant sous forme de valeur de tag personnalisé.

Dans cet exemple, un flow d'onboarding collecte le poids et la taille de l'utilisateur. Quand l'utilisateur ferme le flow d'onboarding après son dernier écran, votre application calcule son indice de masse corporelle (IMC). Ensuite, elle ouvre un flow de paywall qui affiche l'IMC.

### Configurer les flows \{#set-up-the-flows\}

1. [Créez deux flows](paywall-builder-templates) : un flow d'onboarding qui collecte le poids et la taille de l'utilisateur, et un flow de paywall qui affiche son IMC.
2. Ajoutez deux champs [**Number**](builder-inputs-and-forms) au flow d'onboarding :
   - Un pour le poids en kilogrammes, avec l'**Element ID** `weight`.
   - Un pour la taille en centimètres, avec l'**Element ID** `height`.

   Pour les deux champs, définissez le **Format** sur **Integer**. Un champ envoie sa valeur sous forme de texte, exactement tel que l'utilisateur l'a saisi, et l'[exemple de code](#pass-the-bmi-to-the-paywall) ne lit pas « 70.5 » et « 70,5 » de la même façon. Les nombres entiers n'ont pas de séparateur décimal, donc le code les lit de la même manière quelle que soit la locale.
3. Pour vous assurer que votre application reçoit bien les deux valeurs, terminez le flow d'onboarding par un écran sans champs de saisie. Sur cet écran, ajoutez un bouton avec l'action [**Close flow**](onboarding-actions#close-flow). Les champs envoient leurs valeurs lorsqu'ils perdent le focus ou lorsque l'utilisateur passe à un autre écran. L'action Close flow ne les envoie pas. L'exemple de code n'ouvre le paywall que si l'utilisateur a atteint le dernier écran.
4. Dans le flow de paywall, [créez un tag personnalisé](flow-custom-tags#create-a-custom-tag) nommé `bmi`. Dans le champ **Initial value**, saisissez un tiret (`—`). Les utilisateurs verront ce tiret si votre application ne transmet aucun IMC.
5. Ajoutez un élément texte avec les mots « Your BMI: » au flow de paywall. Après ces mots, [insérez le tag personnalisé `bmi`](flow-custom-tags#add-a-custom-tag-to-a-text-element).
6. Ajoutez le flow d'onboarding à un [placement](placements), par exemple `onboarding`. Ajoutez le flow de paywall à un placement avec l'ID `bmi_paywall`. Le code de la section [Transmettre l'IMC au paywall](#pass-the-bmi-to-the-paywall) récupère le paywall via cet ID.

### Transmettre l'IMC au paywall \{#pass-the-bmi-to-the-paywall\}

Collectez le poids et la taille depuis les événements `flow_user_input` du flow d'onboarding, comme dans [Traiter les données des flows](android-flow-input). Pour savoir que l'utilisateur a atteint le dernier écran, surveillez un événement `flow_screen_showed` avec `is_last_screen` à `true`, comme dans [Suivre les vues d'écran du flow](android-flow-screen-views). Lorsque l'utilisateur ferme le flow d'onboarding après cet écran, calculez l'IMC. Créez ensuite la vue du flow du paywall et passez l'IMC pour le tag personnalisé `bmi`.

Transmettez le listener suivant à la vue du flow d'onboarding :

```kotlin showLineNumbers title="Kotlin"
class OnboardingEventListener(
    private val onBmiCalculated: (bmi: String) -> Unit,
) : AdaptyFlowDefaultEventListener() {

    private val bodyAnswers = mutableMapOf<String, String>()
    private var reachedLastScreen = false

    override fun onAnalyticEvent(
        name: String,
        params: Map<String, Any?>,
        context: Context,
    ) {
        if (name == "flow_screen_showed" && params["is_last_screen"] == true) {
            reachedLastScreen = true
            return
        }
        if (name != "flow_user_input") return

        val elementId = params["element_id"] as? String ?: return
        val value = params["value"] as? String ?: return

        bodyAnswers[elementId] = value
    }

    override fun onFlowClosed() {
        // Reset `bodyAnswers` and `reachedLastScreen` on every close,
        // so that the next run starts without old answers.
        val answers = bodyAnswers.toMap()
        val finished = reachedLastScreen
        bodyAnswers.clear()
        reachedLastScreen = false

        // Number inputs send their values as strings.
        if (!finished) return
        val weight = answers["weight"]?.toDoubleOrNull() ?: return
        val height = answers["height"]?.toDoubleOrNull()?.takeIf { it > 0 } ?: return

        val heightInMeters = height / 100
        val bmi = weight / (heightInMeters * heightInMeters)

        onBmiCalculated(String.format(Locale.getDefault(), "%.1f", bmi))
    }
}
```

Quand l'utilisateur ferme le flow d'onboarding après son dernier écran, le listener appelle `onBmiCalculated` avec l'IMC. Passez une lambda pour `onBmiCalculated` qui appelle la fonction suivante. Cette fonction récupère le flow du paywall, crée sa vue et transmet l'IMC pour le tag personnalisé `bmi` :

```kotlin showLineNumbers title="Kotlin"
fun showBmiPaywall(activity: Activity, bmi: String) {
    Adapty.getFlow("bmi_paywall") { flowResult ->
        when (flowResult) {
            is AdaptyResult.Success -> {
                AdaptyUI.getFlowConfiguration(flowResult.value) { configResult ->
                    when (configResult) {
                        is AdaptyResult.Success -> {
                            val flowView = AdaptyUI.getFlowView(
                                activity,
                                configResult.value,
                                products = null,
                                eventListener = AdaptyFlowDefaultEventListener(),
                                tagResolver = AdaptyUiTagResolver { tag ->
                                    if (tag == "bmi") bmi else null
                                },
                            )
                            // add flowView to your view hierarchy
                        }
                        is AdaptyResult.Error -> {
                            // handle the error
                        }
                    }
                }
            }
            is AdaptyResult.Error -> {
                // handle the error
            }
        }
    }
}
```

`String.format` avec `Locale.getDefault()` utilise le séparateur décimal de la locale de l'utilisateur : « 22.7 » en anglais, « 22,7 » en allemand.

### Enregistrer l'IMC dans le profil de l'utilisateur \{#save-the-bmi-to-the-users-profile\}

Pour afficher différents flows aux utilisateurs en fonction de leur IMC, enregistrez-le en tant qu'[attribut personnalisé](android-setting-user-attributes#custom-user-attributes) de leur profil. Dans l'Adapty Dashboard, [créez un attribut personnalisé de type **Number**](segments#custom-attributes) avec la clé `bmi`. Affichez ensuite chaque flow à une [audience](audience) construite à partir de cet attribut.

Appelez la méthode `updateProfile` dans `onFlowClosed`, juste après la ligne qui calcule `bmi`. Passez ce `Double`, et non la chaîne formatée, afin qu'un segment puisse comparer l'IMC à un seuil :

```kotlin showLineNumbers title="Kotlin"
val params = AdaptyProfileParameters.Builder()
    .withCustomAttribute("bmi", bmi)
    .build()

Adapty.updateProfile(params) { error ->
    if (error != null) {
        // handle the error
    }
}
```