Skip to content


Guide d’implémentation avancé

Ce Guide d’implémentation avancé optionnel couvre les considérations du code des messages in-app, trois cas d’utilisation personnalisés créés par notre équipe et les extraits de code qui l’accompagnent. Visitez notre dépôt de démonstration Braze ici! Notez que ce guide d’implémentation est centré autour d’une implémentation Kotlin, mais les extraits de code Java sont fournis aux personnes intéressées. Vous recherchez des implémentations HTML ? Jetez un coup d’œil à notre référentiel de modèles HTML!

Considérations du code

Le guide suivant propose une intégration de développeur personnalisée facultative à utiliser en plus des messages in-app par défaut. Les composants et les fabriques de vue personnalisée sont compris selon les besoins de chaque cas d’usage, en offrant des exemples pour étendre la fonctionnalité et personnaliser nativement l’apparence et la convivialité de vos messages in-app. Dans certains cas, il existe plusieurs manières d’obtenir des résultats similaires. L’implémentation optimale dépendra du cas d’usage spécifique.

Fabriques personnalisées

Le SDK Braze permet aux développeurs de remplacer un certain nombre de valeurs par défaut par des objets de fabriques personnalisés. Ces derniers peuvent être enregistrés avec le SDK Braze, selon les besoins, pour obtenir les résultats souhaités. Dans la plupart des cas, cependant, si vous décidez de remplacer une fabrique, vous devrez soit différer explicitement la valeur par défaut, soit remettrez la fonctionnalité fournie par Braze par défaut. L’extrait de code suivant illustre comment fournir des implémentations personnalisées des interfaces IInAppMessageViewFactory et IInAppMessageViewWrapperFactory. Après avoir bien compris les concepts qui sous-tendent la modification de nos usines par défaut, consultez nos cas d’utilisation pour commencer à mettre en œuvre des fonctionnalités d’envoi de messages in-app personnalisées.

Types de messages in-app

1
2
3
4
5
6
7
8
class BrazeDemoApplication : Application(){
 override fun onCreate() {
    super.onCreate()
    registerActivityLifecycleCallbacks(BrazeActivityLifecycleCallbackListener(true, true))
    BrazeInAppMessageManager.getInstance().setCustomInAppMessageViewWrapperFactory(CustomInAppMessageViewWrapperFactory())
    BrazeInAppMessageManager.getInstance().setCustomInAppMessageViewFactory(CustomInAppMessageViewFactory())
  }
}

Types de messages in-app

1
2
3
4
5
6
7
8
9
public class BrazeDemoApplication extends Application {
  @Override
  public void onCreate{
    super.onCreate();
    registerActivityLifecycleCallbacks(new BrazeActivityLifecycleCallbackListener(true, true));
    BrazeInAppMessageManager.getInstance().setCustomInAppMessageViewWrapperFactory(new CustomInAppMessageViewWrapperFactory());
    BrazeInAppMessageManager.getInstance().setCustomInAppMessageViewFactory(new CustomInAppMessageViewFactory());
  }
}

Cas d’utilisation

Vous trouverez ci-dessous trois cas d’utilisation. Chaque cas d’utilisation comporte des extraits de code et un aperçu de l’aspect et de l’utilisation des messages in-app dans le tableau de bord de Braze :

Message in-app personnalisé à glissement vers le haut

Lors de la création de votre message in-app à glissement vers le haut, vous remarquerez peut-être que vous ne pouvez pas modifier l’emplacement du message à l’aide des méthodes par défaut. Une telle modification est rendue possible en sous-classant la classe DefaultInAppMessageViewWrapper pour ajuster les paramètres de mise en page. Vous pouvez ajuster la position finale à l’écran en écrasant la méthode getLayoutParams retournant le LayoutParams modifié par vos propres valeurs de positionnement personnalisées. Visitez le CustomSlideUpInAppMessageViewWrapper pour commencer.

Wrapper de vue personnalisé

Remplacer et renvoyer les paramètres de mise en page personnalisés
Dans la méthode getLayoutParams vous pouvez utiliser la méthode de superclasse pour accéder au LayoutParameters d’origine pour le message in-app. Ensuite, vous pouvez ajuster la position en ajoutant ou en soustrayant comme vous le souhaitez.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class CustomSlideUpInAppMessageViewWrapper(inAppMessageView: View?,
                                           inAppMessage: IInAppMessage?,
                                           inAppMessageViewLifecycleListener: IInAppMessageViewLifecycleListener?,
                                           configurationProvider: BrazeConfigurationProvider?,
                                           openingAnimation: Animation?,
                                           closingAnimation: Animation?,
                                           clickableInAppMessageView: View?) : DefaultInAppMessageViewWrapper(inAppMessageView,
    inAppMessage,
    inAppMessageViewLifecycleListener,
    configurationProvider,
    openingAnimation,
    closingAnimation,
    clickableInAppMessageView) {

    override fun getLayoutParams(inAppMessage: IInAppMessage?): ViewGroup.LayoutParams {
        val params = super.getLayoutParams(inAppMessage) as FrameLayout.LayoutParams
        params.bottomMargin = params.bottomMargin + 500 //move the view up by 500 pixels
        return params
    }
}

Remplacer et renvoyer les paramètres de mise en page personnalisés
Dans la méthode getLayoutParams vous pouvez utiliser la méthode de superclasse pour accéder au LayoutParameters d’origine pour le message in-app. Ensuite, vous pouvez ajuster la position en ajoutant ou en soustrayant comme vous le souhaitez.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class CustomSlideUpInAppMessageViewWrapper extends DefaultInAppMessageViewWrapper {

    public CustomInAppMessageViewWrapper(View inAppMessageView,
                                           IInAppMessage inAppMessage,
                                           IInAppMessageViewLifecycleListener inAppMessageViewLifecycleListener,
                                           BrazeConfigurationProvider configurationProvider,
                                           Animation openingAnimation,
                                           Animation closingAnimation,
                                           View clickableInAppMessageView){
        super(inAppMessageView,
                inAppMessage,
                inAppMessageViewLifecycleListener,
                configurationProvider,
                openingAnimation,
                closingAnimation,
                clickableInAppMessageView)

    }
    
    @Override
    public ViewGroup.LayoutParams getLayoutParams(IInAppMessage inAppMessage){
        FrameLayout.LayoutParams params = (FrameLayout.LayoutParams)super.getLayoutParams(inAppMessage)
        params.bottomMargin = params.bottomMargin + 500 //move the view up by 500 pixels
        return params
    }
}

Fournissez une fabrique personnalisée pour renvoyer votre wrapper personnalisé
Pour que le SDK Braze puisse utiliser votre wrapper personnalisé, vous devez également fournir une implémentation IInAppMessageViewWrapperFactory personnalisée qui renvoie votre wrapper personnalisé. Vous pouvez soit implémenter IInAppMessageViewWrapperFactory directement ou sous-classer BrazeInAppMessageViewWrapperFactory et ne remplacer que la méthode createInAppMessageViewWrapper :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class CustomInAppMessageViewWrapperFactory : BrazeInAppMessageViewWrapperFactory() {

    override fun createInAppMessageViewWrapper(
        inAppMessageView: View?,
        inAppMessage: IInAppMessage?,
        inAppMessageViewLifecycleListener: IInAppMessageViewLifecycleListener?,
        configurationProvider: BrazeConfigurationProvider?,
        openingAnimation: Animation?,
        closingAnimation: Animation?,
        clickableInAppMessageView: View?
    ): IInAppMessageViewWrapper {
        return if (inAppMessage is InAppMessageSlideup) {
            CustomSlideUpInAppMessageViewWrapper( //return our custom view wrapper only for slideups
                inAppMessageView,
                inAppMessage,
                inAppMessageViewLifecycleListener,
                configurationProvider,
                openingAnimation,
                closingAnimation,
                clickableInAppMessageView
            )
        } else {
            super.createInAppMessageViewWrapper( //defer to the default implementation for all other IAM types
                inAppMessageView,
                inAppMessage,
                inAppMessageViewLifecycleListener,
                configurationProvider,
                openingAnimation,
                closingAnimation,
                clickableInAppMessageView
            )
        }
    }
}

Fournissez une fabrique personnalisée pour renvoyer votre wrapper personnalisé
Pour que le SDK Braze puisse utiliser votre wrapper personnalisé, vous devez fournir une implémentation IInAppMessageViewWrapperFactory personnalisée qui renvoie votre wrapper personnalisé. Vous pouvez soit implémenter IInAppMessageViewWrapperFactory directement ou sous-classer BrazeInAppMessageViewWrapperFactory et ne remplacer que la méthode createInAppMessageViewWrapper :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class CustomInAppMessageViewWrapperFactory extends BrazeInAppMessageViewWrapperFactory {
    @Override
    public IInAppMessageViewWrapper createInAppMessageViewWrapper(View inAppMessageView, 
        IInAppMessage inAppMessage, 
        IInAppMessageViewLifecycleListener inAppMessageViewLifecycleListener, 
        BrazeConfigurationProvider configurationProvider, 
        Animation openingAnimation, 
        Animation closingAnimation, 
        View clickableInAppMessageView){
        if (inAppMessage instanceof InAppMessageSlideup){
            return new CustomSlideUpInAppMessageViewWrapper( //return our custom view wrapper only for slideups
                inAppMessageView,
                inAppMessage,
                inAppMessageViewLifecycleListener,
                configurationProvider,
                openingAnimation,
                closingAnimation,
                clickableInAppMessageView);
        }else{
            return super.createInAppMessageViewWrapper(//defer to the default implementation for all other IAM types
                inAppMessageView,
                inAppMessage,
                inAppMessageViewLifecycleListener,
                configurationProvider,
                openingAnimation,
                closingAnimation,
                clickableInAppMessageView);
        }
    }
}

Enregistrez votre fabrique auprès de Braze
Une fois que vous avez créé votre fabrique de wrapper personnalisée, enregistrez-la avec le SDK Braze via le BrazeInAppMessageManager :

1
BrazeInAppMessageManager.getInstance().setCustomInAppMessageViewWrapperFactory(CustomInAppMessageViewWrapperFactory())

Enregistrez votre fabrique auprès de Braze
Une fois que vous avez créé votre fabrique de wrapper personnalisée, enregistrez-la avec le SDK Braze via le BrazeInAppMessageManager :

1
BrazeInAppMessageManager.getInstance().setCustomInAppMessageViewWrapperFactory(new CustomInAppMessageViewWrapperFactory());

Message in-app modal personnalisé

Un BrazeInAppMessageModalView peut être sous-classé pour tirer parti d’un Spinner offrant des façons intéressantes de collecter de précieux attributs d’utilisateur. L’exemple suivant montre comment utiliser le contenu connecté pour capturer des attributs personnalisés à partir d’une liste dynamique d’éléments. Visitez le site TeamPickerView pour commencer.

Utilisation de view_type pour le comportement d’affichage de l’interface utilisateur
L’objet IInAppMessage possède un dictionnaire extras que nous pouvons interroger pour trouver la clé view_type (le cas échéant) et afficher le type de vue approprié. Il est important de noter que les messages in-app sont configurés par message, de sorte que les vues modales personnalisées et par défaut puissent fonctionner harmonieusement.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
override fun createInAppMessageView(activity: Activity, inAppMessage: IInAppMessage): View {
  return when {
      inAppMessage.extras?.get("view_type") == "picker" -> {
          getCustomPickerView(activity, inAppMessage)
      }
      //...
      else -> {
          //Defer to default
          BrazeInAppMessageManager
              .getInstance()
              .getDefaultInAppMessageViewFactory(inAppMessage).createInAppMessageView(activity, inAppMessage)
      }
  }
}

Utilisation de view_type pour le comportement d’affichage de l’interface utilisateur
L’objet IInAppMessage possède un dictionnaire extras que nous pouvons interroger pour trouver la clé view_type (le cas échéant) et afficher le type de vue approprié. Il est important de noter que les messages in-app sont configurés par message, de sorte que les vues modales personnalisées et par défaut puissent fonctionner harmonieusement.

1
2
3
4
5
6
7
8
9
10
11
12
@Override
public View createInAppMessageView(Activity activity, IInAppMessage inAppMessage) {
    if("picker".equals(inAppMessage.getExtras().get("view_type"))){
        return getCustomPickerView(activity, inAppMessage);
    } else {
        //Defer to default
        BrazeInAppMessageManager
          .getInstance()
          .getDefaultInAppMessageViewFactory(inAppMessage)
          .createInAppMessageView(activity, inAppMessage);
    }
}

Remplacer et fournir une vue personnalisée
Indiquez une mise en page qui reproduit le message in-app modal standard, mais indiquez votre vue en tant qu’élément racine, puis augmentez cette disposition

1
2
3
4
5
6
7
8
9
10
11
<com.braze.advancedsamples.inapp.modal.TeamPickerView xmlns:android="http://schemas.android.com/apk/res/android"
                                                      xmlns:tools="http://schemas.android.com/tools"
                                                      android:layout_width="match_parent"
                                                      android:layout_height="match_parent"
                                                      android:padding="0.0dp"
                                                      android:id="@+id/team_picker_view">
    <!-- ... -->
    <Spinner android:layout_width="match_parent" android:layout_height="wrap_content"
                     android:id="@+id/team_spinner"/>
    <!-- ... -->                                                      
</com.braze.advancedsamples.inapp.modal.TeamPickerView>

Augmenter et personnaliser la vue
Avant de recharger les composants Spinner, la variable de message inAppMessage sort en tant que chaîne de caractères. Ce message doit être formaté comme un ensemble d’éléments à afficher correctement. Par exemple, cela peut être effectué en utilisant String.split(",").

1
2
3
4
5
6
private fun getCustomView(activity: Activity, inAppMessage: IInAppMessage): TeamPickerView {
        val view = activity.layoutInflater.inflate(R.layout.team_picker_dialog, null) as TeamPickerView
        val teams = inAppMessage.message.split(",")
        view.setTeams(teams)
        return view
    }

Augmenter et personnaliser la vue
Avant de recharger les composants de Spinner, la variable de message inAppMessage est éditée sous la forme d’une chaîne de caractères. Ce message doit être formaté comme un ensemble d’éléments à afficher correctement. Par exemple, cela peut être effectué en utilisant String.split(",").

1
2
3
4
5
6
private TeamPickerView getCustomView(Activity activity, IInAppMessage inAppMessage) {
        TeamPickerView view = (TeamPickerView) activity.getLayoutInflater().inflate(R.layout.team_picker_dialog, null);
        String[] teams = inAppMessage.getMessage().split(",");
        view.setTeams(teams);
        return view
    }

Attribuer un attribut personnalisé
En utilisant la sous-classe de vue, après qu’un utilisateur appuie sur Envoyer, transmettez vers Braze l’attribut avec sa valeur sélectionnée correspondante et rejetez le message in-app en appelant messageClickableView.performClick().

1
2
3
4
5
6
7
    override fun onClick(v: View?) {
        val selectedTeam = spinner.selectedItem as String
        messageClickableView.performClick()
        Braze.getInstance(ctx).getCurrentUser { brazeUser ->
            brazeUser?.setCustomUserAttribute("FavoriteTeam", selectedTeam)
        }
    }

Attribuer un attribut personnalisé
En utilisant la sous-classe de vue, après qu’un utilisateur appuie sur Envoyer, transmettez vers Braze l’attribut avec sa valeur sélectionnée correspondante et rejetez le message in-app en appelant messageClickableView.performClick().

1
2
3
4
5
6
7
8
    @Override
    public void onClick(View v) {
        String selectedTeam = (String) spinner.getSelectedItem();
        messageClickableView.performClick();
        Braze.getInstance(ctx).getCurrentUser(brazeUser -> {
            brazeUser.setCustomUserAttribute("FavoriteTeam", selectedTeam);
        });
    }

Message in-app complet personnalisé

La mise en œuvre d’un message in-app immersif (plein écran) entièrement personnalisé implique une approche similaire à celle décrite dans la section relative à la mise en œuvre d’un message in-app modal personnalisé. Dans ce cas, il suffit toutefois d’étendre BrazeInAppMessageFullView et de personnaliser si nécessaire. Rappelez-vous que la vue va s’afficher sur l’IU de l’application et que les vues d’Android par défaut sont transparentes. Cela signifie que vous devrez définir un arrière-plan de sorte que le message in-app obscurcisse le contenu derrière-lui. En étendant BrazeInAppMessageFullView, le SDK Braze traitera les événements tactiles interceptés sur la vue et prendra l’action appropriée. Comme avec l’exemple modal, vous pouvez écraser ce comportement pour certains types de contrôles (comme les contrôles Switch) pour recueillir les commentaires de l’utilisateur.

Utilisation de view_type pour le comportement d’affichage de l’interface utilisateur
Nous ajouterons une autre view_type pour notre nouvelle personnalisation immersive. Retournez sur la méthode createInAppMessageView et ajoutez une option pour les « bascules » de l’IU :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
override fun createInAppMessageView(activity: Activity, inAppMessage: IInAppMessage): View {
    return when {
        inAppMessage.extras?.get("view_type") == "picker" -> {
            getCustomPickerView(activity, inAppMessage)
        }
        inAppMessage.extras?.get("view_type") == "switches" -> {
            getCustomImmersiveView(activity, inAppMessage) // new customization
        }
        else -> {
            //Defer to default
            BrazeInAppMessageManager
                .getInstance()
                .getDefaultInAppMessageViewFactory(inAppMessage).createInAppMessageView(activity, inAppMessage)
        }
    }
}

Utilisation de view_type pour le comportement d’affichage de l’interface utilisateur
Nous ajouterons une autre view_type pour notre nouvelle personnalisation immersive. Retournez sur la méthode createInAppMessageView et ajoutez une option pour les « bascules » de l’IU :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Override
public View createInAppMessageView(Activity activity, IInAppMessage inAppMessage) {
    if("picker".equals(inAppMessage.getExtras().get("view_type"))){
        return getCustomPickerView(activity, inAppMessage);
    } else if ("switches".equals(inAppMessage.getExtras().get("view_type"))) {
        return getCustomImmersiveView(activity, inAppMessage); // new customization
    } else {
        //Defer to default
        BrazeInAppMessageManager
          .getInstance()
          .getDefaultInAppMessageViewFactory(inAppMessage)
          .createInAppMessageView(activity, inAppMessage);
    }
}

Remplacer et fournir une vue personnalisée
Indiquez une mise en page qui reproduit le message in-app modal standard, mais indiquez votre vue en tant qu’élément racine, puis augmentez cette disposition

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="utf-8"?>
<com.braze.advancedsamples.immersive.CustomImmersiveInAppMessage
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
        android:layout_height="wrap_content">
    <!-- giving the parent layout a white backround color will obscure the app behind the IAM. You could also do this within your custom view -->
    <LinearLayout android:background="@color/white" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center"> 
        <!-- ... -->
        <androidx.recyclerview.widget.RecyclerView android:layout_width="match_parent"
                                                       android:layout_height="wrap_content"
                                                       android:id="@+id/option_list"/>
        <!-- ... -->
    </LinearLayout>
</com.braze.advancedsamples.immersive.CustomImmersiveInAppMessage>

Augmenter et personnaliser la vue
Avant de définir les options du composant RecyclerView, la variable de message inAppMessage est envoyée sous forme de chaîne de caractères. Ce message doit être formaté comme un ensemble d’éléments à afficher correctement. Par exemple, cela peut être effectué en utilisant String.split(","). Les title et subtitle sont également extraits de l’ensemble extras.

1
2
3
4
5
6
7
8
private fun getCustomImmersiveView(activity: Activity, inAppMessage: IInAppMessage): CustomImmersiveInAppMessage{
    val view = activity.layoutInflater.inflate(R.layout.full_screen_iam, null) as CustomImmersiveInAppMessage
    val options = inAppMessage.message.split(",")
    view.setOptions(options)
    inAppMessage.extras?.get("title").let { view.setTitle(it) }
    inAppMessage.extras?.get("subtitle").let {view.setSubtitle(it) }
    return view
}

Augmenter et personnaliser la vue
Avant de définir les options du composant RecyclerView, la variable de message inAppMessage est envoyée sous forme de chaîne de caractères. Ce message doit être formaté comme un ensemble d’éléments à afficher correctement. Par exemple, cela peut être effectué en utilisant String.split(","). Les title et subtitle sont également extraits de l’ensemble extras.

1
2
3
4
5
6
7
8
9
10
private CustomImmersiveInAppMessage getCustomImmersiveView(Activity activity, IInAppMessage inAppMessage) {
    CustomImmersiveInAppMessage view = (CustomImmersiveInAppMessage) activity.layoutInflater.inflate(R.layout.full_screen_iam, null);
    String[] options = inAppMessage.message.split(",");
    view.setOptions(options);
    String title = inAppMessage.getExtras().get("title");
    view.setTitle(title);
    String subtitle = inAppMessage.getExtras().get("subtitle"); 
    view.setSubtitle(subtitle);
    return view;
}

Attribuer un attribut personnalisé
À l’aide de la sous-classe de vue, après qu’un utilisateur bascule un des commutateurs, transférez l’attribut associé et le statut de la bascule à Braze.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
fun logClick(value:String, checked:Boolean){
    Braze.getInstance(ctx).logCustomEvent("SwitchChanged", BrazeProperties())
}

inner class OptionViewHolder(item: View): RecyclerView.ViewHolder(item), View.OnClickListener{

    var value: String = ""

    override fun onClick(p0: View?) {
        if (p0 is Switch){
            val checked = p0.isChecked
            p0.isChecked = !p0.isChecked
            logClick(value, checked)
        }
    }
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): OptionViewHolder {
    return OptionViewHolder(mInflater.inflate(R.layout.switch_cell, null))
}

override fun onBindViewHolder(holder: OptionViewHolder, position: Int) {
    holder.itemView.findViewById<TextView>(R.id.label).text = options[position]
    holder.value = options[position]
}

Attribuer un attribut personnalisé
À l’aide de la sous-classe de vue, après qu’un utilisateur bascule un des commutateurs, transférez l’attribut associé et le statut de la bascule à Braze.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
private void logClick(String value, boolean checked){
    Braze.getInstance(ctx).logCustomEvent("SwitchChanged", new BrazeProperties());
}

private class OptionViewHolder extends RecyclerView.ViewHolder, implements View.OnClickListener{

    private String value = "";

    public OptionViewHolder(View item){
        super(item);
    }

   
    @Override
    public void onClick(View view) {
        if (view instanceof Switch){
            Switch switchView = (Switch) view;
            boolean checked = switchView.isChecked;
            switchView.isChecked = !switchView.isChecked;
            logClick(value, checked)
        }
    }
}

@Override
public OptionViewHolder onCreateViewHolder(ViewGroup parent, Int viewType) {
    return new OptionViewHolder(mInflater.inflate(R.layout.switch_cell, null));
}

@Override
public void onBindViewHolder(OptionViewHolder holder, Int position) {
    ((TextView)holder.getItemView().findViewById(R.id.label)).setText(options.get(position));
    holder.value = options.get(position);
}

Interception des touches de message in-app

Un appareil Android affichant des lignes de paramètres et de bascule. La vue personnalisée gère les boutons, et tout contact en dehors des boutons est traité par le message in-app et le fait disparaître. L’interception des touchés de message in-app est essentielle pour que les boutons du message in-app personnalisé complet fonctionnent correctement. Par défaut, toutes les vues de messages in-app sont ajoutées en tant qu’écouteurs onClick sur le message, afin que les utilisateurs puissent ignorer les messages sans boutons. Lorsque vous ajoutez des contrôles personnalisés qui doivent répondre à une entrée par l’utilisateur (comme les boutons personnalisés), vous pouvez enregistrer un écouteur onClick avec la vue habituelle. Tout touché en dehors des commandes personnalisées rejettera le message in-app comme d’habitude, tandis que les touchés reçus par les contrôles personnalisés feront appel à votre écouteur onClick.

CETTE PAGE A-T-ELLE ÉTÉ UTILE?
New Stuff!