Comment créer une superposition d'aide comme vous le voyez dans quelques applications Android et ICS?

93

Je souhaite créer des superpositions d'aide comme celles que vous voyez lorsque ICS se charge pour la première fois ou dans des applications comme ES File Explorer ou Apex Launcher (il y en a plus, mais je ne peux pas y penser pour le moment). S'agit-il simplement d'une disposition relative avec une vue superposée? Je n'ai pas pu trouver d'exemple de code pour faire une telle chose. Quelqu'un sait comment cela se fait ou a des idées?

Explorateur de fichiers ES Explorateur de fichiers ES

ssuperz28
la source

Réponses:

84

Supposons que vous appeliez normalement setContentView(R.layout.main), mais lors de la première exécution, vous voulez avoir cette superposition.

Étape # 1: Créez un FrameLayoutcode Java et transmettez-le à setContentView().

Étape # 2: Utilisez LayoutInflaterpour gonfler R.layout.maindans le FrameLayout.

Étape # 3: Utilisez LayoutInflaterpour gonfler la superposition dans le FrameLayout.

Étape n ° 4: Lorsque l'utilisateur appuie sur le bouton (ou autre) pour ignorer la superposition, appelez removeView()pour supprimer la superposition du FrameLayout.

Étant donné que la superposition est un enfant ultérieur de FrameLayout, elle flottera au-dessus du contenu de R.layout.main.

CommonsWare
la source
6
@ ssuperz28: Ouais, eh bien, sauf pour les pointes de flèches et les bulles dessinées à la main. Vous êtes seul pour ceux-là. :-)
CommonsWare
Je ne sais pas si vous avez réussi à faire ce que vous vouliez, mais voici une autre alternative. stackoverflow.com/questions/8841240/… Si vous maintenez la solution donnée par CommonsWare, la seule chose qui me passe pour définir les flèches, est de définir le FrameLayout des instructions avec une resourceImage ou backgroundImage déjà avec l'image avec les flèches (et transparence).
Edison Santos le
1
Existe-t-il un moyen de le faire mais de le faire par rapport à la position des enfants qui sont en dessous du FrameLayout?
4gus71n
@CommonsWare - Monsieur, cela fonctionnerait quel que soit le périphérique?
Rat-a-tat-a-tat Ratatouille
2
@ user3364963: Ajustez dynamiquement les positions des choses. Ma réponse a été quelque peu simplifiée. Je suppose qu'ils déterminent la position des éléments à mettre en évidence et ajustent les coordonnées des "marques d'entraîneur". Une coutume ViewGrouppour la couche «marques de coach» pourrait gérer cela, et il existe des bibliothèques (par exemple ShowcaseView) qui offrent des implémentations prédéfinies de ce modèle.
CommonsWare
80

"Coach mark" est "Help overlay" dans UX talk :-)

coach_mark.xml est la mise en page de votre marque de coach

coach_mark_master_view est l'identifiant de la vue la plus haute (racine) dans coach_mark.xml

public void onCoachMark(){

    final Dialog dialog = new Dialog(this);
    dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
    dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
    dialog.setContentView(R.layout.coach_mark);
    dialog.setCanceledOnTouchOutside(true);
    //for dismissing anywhere you touch
    View masterView = dialog.findViewById(R.id.coach_mark_master_view);
    masterView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            dialog.dismiss();
        }
    });
    dialog.show();
}

Ajout d'un échantillon de coach_mark.xml (à cette excellente solution fournie par Oded Breiner), il est donc facile pour les personnes de copier et coller pour voir rapidement l'exemple de travail.

Exemple de coach_mark.xml ici, changez le -> drawable / coach_marks en votre image:

coach_mark.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:id="@+id/coach_mark_master_view">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
         <ImageView
             android:id="@+id/coach_marks_image"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:layout_centerInParent="true"
             android:layout_gravity="center_horizontal"
             android:src="@drawable/coach_marks" />
    </RelativeLayout>
</LinearLayout>

Et utilisez éventuellement ce thème pour supprimer le remplissage:

<style name="WalkthroughTheme" parent="Theme.AppCompat">
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:backgroundDimEnabled">false</item>
</style>
Oded Breiner
la source
Bonjour, comment pouvez-vous étirer cette boîte de dialogue pour qu'elle corresponde à l'écran? À partir de la documentation A dialog is a small window that prompts [...]. A dialog does not fill the screen and is normally used for modal events [...].,. Si j'utilise ce code, j'obtiens ma vue principale compressée dans une petite partie de l'écran. Si je règle android:layout_width="640dp" android:layout_height="480dp"(c'est-à-dire les valeurs réelles de l'écran avec lequel je teste), cela fonctionne correctement. (bien sûr, ce n'est pas une solution réalisable)
ocramot
@ocramot: l'exemple ci-dessus devrait être en plein écran à cause de match_parent et Window.FEATURE_NO_TITLE
Oded Breiner
Ensuite, il doit y avoir un autre problème, car je le vois d'une manière différente
ocramot
1
Je sais que cela remonte à au moins quelques mois, mais cette question en plein écran a-t-elle déjà été résolue?
cbhedd
3
Pour ceux qui ne savent pas comment définir le thème du dialogue, instanciez simplement le dialogue comme ceci:new Dialog(getContext(), R.style.WalkthroughTheme);
w3bshark
4

Vous pouvez le faire assez rapidement. Vous ajoutez, par exemple, un LinearLayout où vous mettez une image avec alpha qui correspondent à vos informations d'aide et que voulez-vous dessiner comme une superposition. Dans votre xml de votre activité, vous mettez cette mise en page dans un RelativeLayout après la mise en page de votre activité avec la visibilité Gone. Lorsque vous souhaitez dessiner les informations d'aide, il vous suffit de définir cette visibilité sur visible.

J'espère, je suis clair, si vous avez des questions, je serai heureux d'y répondre.

FUBU
la source
Merci pour votre contribution. C'est ainsi que je l'imaginais. Je dois donner crédit à la réponse ci-dessous car c'est ainsi que je vais la construire. Cela semble plus gérable et je n'ai pas à modifier la disposition de mon activité principale.
ssuperz28
1

Voir mon autre réponse comment afficher par programme une disposition de superposition au-dessus de l'activité actuelle. Le fichier layout.xml de l'activité n'a pas besoin de connaître le skin de superposition. Vous pouvez mettre une superposition semi-transparente, ne couvrir qu'une partie de l'écran, une ou plusieurs vues de texte et des boutons dessus ... Comment superposer un bouton par programmation?

  • créer un modèle res / layout / paused.xml RelativeLayout ou utiliser n'importe quelle mise en page au niveau supérieur
  • créer une fonction pour afficher la peau de superposition
  • la clé est d'obtenir la poignée de layout.xml, utilisez la classe LayoutInflater pour analyser xml pour afficher l'objet, ajouter une vue de superposition à la structure de disposition actuelle
  • Mon exemple utilise une minuterie pour détruire l'objet de superposition en le supprimant complètement de la structure de la vue. C'est probablement ce que vous souhaitez également pour vous en débarrasser sans laisser de trace.

Mon objectif était que les activités principales ne connaissent pas de skin de superposition, les superpositions vont et viennent, de nombreuses superpositions différentes, toujours capables d'utiliser des fichiers texte overlay1.xml comme modèle et le contenu doit être mis à jour par programme. Je fais à peu près ce que CommonsWare nous a dit, mon message montre le code du programme réel pour commencer.

avertissement: OP "Merci pour votre contribution. C'est ainsi que j'ai imaginé que cela se faisait. Je dois donner crédit à la réponse ci-dessous" Le commentaire ne signifie pas ma réponse mais la réponse de CommonsWare. Stackoverflow a modifié l'ordre des publications.

Qui
la source