Ce tutoriel va pousser un peu plus loin la création et la gestion des vues sous Android. Dans ce dernier, vous allez apprendre à gérer le passage d’une vue à une autre dans votre application.

Un passage d’une vue à une autre signifie un changement d’activité avec passage de données si nécessaire entre les deux activités

pré-requis

Pour bien comprendre cette partie, nous allons partir du tutoriel “Introduction aux vues sous Android”, donc du code de ce tutoriel.
Pour ceux n’ayant pas fait ce tutoriel, voici le code source ici
Et voici ce que vous devez obtenir juste en compilant le code

Nous allons faire en sorte que lorsqu’un utilisateur clique sur le bouton “Se connecter”, il soit redirigé vers une autre vue.

Création de la deuxième activité

Nous allons commencer par créer une deuxième activité (vue), cette dernière va afficher l’adresse mail et mot de passe saisie dans la vue de login.

Une création de vue débute toujours par la création du fichier XML. Que l’on appellera “login_display.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:paddingTop="@dimen/layout_padding_top" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/email"
        android:textColor="@color/black_color"
        android:textSize="@dimen/big_text_size"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/email_display"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:hint="@string/hint_mail"
        android:textColor="@color/black_color"
        android:textSize="@dimen/big_text_size" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingTop="@dimen/normal_padding"
        android:text="@string/password"
        android:textColor="@color/black_color"
        android:textSize="@dimen/big_text_size"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/password_display"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:hint="@string/hint_pass"
        android:textColor="@color/black_color"
        android:textSize="@dimen/big_text_size" />

</LinearLayout>
  • Voici quelques explications de ce code :
    • android:paddingTop : C’est pour l’espacement du haut du Layout (un peu comme en HTML).
    • android:gravity : Spécifie l’emplacement du contenu dans le conteneur (ici l’emplacement du texte dans le TextView).
    • android:textSize : Spécifie la taille de texte.
    • android:textStyle : Spécifie un style au texte (bold, italic, bolditalic).
    • android:textColor : Spécifie la couleur du texte.
    • android:id : Donne un “identifiant” à l’objet, afin de pouvoir y accéder depuis votre activité.
    • android:hint : Spécifie un texte par défaut sur la zone. Ce texte sera affiché quand aucun “android:text” n’est défini (sert surtout en texte d’indication pour des champs de formulaire par exemple).
    • TextView : Représente un champs d’affichage de texte.
    • Les autres champs sont expliqués dans le tutoriel Introduction aux vues sous Android

Ensuite on crée l’activité (classe Java) correspondante à l’interface XML qu’on vient de créer. On l’appellera “LoginDisplayActivity.java”.


public class LoginDisplayActivity extends Activity {
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.login_display);
    } 
}


Une des erreurs les plus fréquentes est d’oublier de déclarer la nouvelle activité dans le fichier “AndroidManifest.xml”.
Cela s’effectue dans la balise “application” du fichier manifeste, il suffit de rajoute la ligne suivante (On met toujours un point devant le nom de la classe) :

<activity android:name=".LoginDisplayActivity" />

Ce qui donnera comme fichier :

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.tutos.android.ui"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".LoginDisplayActivity"
            android:label="@string/title_activity_login_display" />
    </application>

</manifest>

le fichier “strings.xml”, qui se trouve dans le dossier res/values a été mis à jour. Il ressemble maintenant à :

<resources>
    <string name="app_name">FirstAndroidView</string>
    <string name="hello_world">Hello world!</string>
    <string name="menu_settings">Settings</string>
    <string name="title_activity_main">MainActivity</string>
    <string name="image_content_description">Un Android avec un chien</string>
    <string name="create_account">Créer un compte</string>
    <string name="email">Adresse email</string>
    <string name="password">Mot de passe</string>
    <string name="connect">Se connecter</string>
    <string name="title_activity_login_display">LoginDisplayActivity</string>
    <string name="hint_mail">"Ici : L'adresse email de l'utilisateur"</string>
    <string name="hint_pass">"Ici : Le mot de passe de l'utilisateur"</string>
</resources>

Ces différentes données seront accessibles via “@string/nomDeVariable

Ainsi que le fichier dimens.xml

<resources>
    <dimen name="padding_small">8dp</dimen>
    <dimen name="padding_medium">8dp</dimen>
    <dimen name="padding_large">16dp</dimen>
    
    <dimen name="layout_padding_top">80dp</dimen>
    <dimen name="big_text_size">20sp</dimen>
    <dimen name="normal_text_size">15sp</dimen>	
    <dimen name="normal_padding">20dp</dimen>
    <dimen name="large_padding">100dp</dimen>
    <dimen name="small_padding">10dp</dimen>
</resources>

Voilà, notre deuxième activité est créée mais ne sert à rien pour l’instant car elle n’est pas encore reliée à notre première activité.

Passage d’une activité à une autre

Nous allons mettre en place le passage d’une activité à une autre, donc pour cela revenons dans la classe “MainActivity.java”.
Le passage d’une activité à une autre se fait en plusieurs parties :

  • On déclare un nouveau “OnClickListener” sur le bouton utilisé pour passer à la seconde activité (ici le bouton “se connecter”).
    • Pour le passage d’une activité à une autre c’est facile.
    • On crée un nouveau Intent (Les intents peuvent être considérés comme des messages utilisées par le système afin de communiquer avec des applications, activités …
    • Le premier argument représente le contexte (facilement récupérable à l’aide de l’activité de départ) et le second représente l’activité d’arrivée.
    • On utilise la méthode “startActivity” avec comme argument l’intent crée précédemment.

    Ce qui donnera pour la méthode OnCreate :

    @Override
    public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
            
      final Button loginButton = (Button) findViewById(R.id.connect);
      loginButton.setOnClickListener(new OnClickListener() {
    			
      @Override
      public void onClick(View v) {
    	Intent intent = new Intent(MainActivity.this, LoginDisplayActivity.class);
    	startActivity(intent);
    	}
    });
       }
    

    Si vous tester le code actuel, le passage de la première activité à la seconde s’effectue correctement mais les données utilisateur ne sont pas transmise.

    Passage de données d’une activité à une autre

    Pour transmettre ces données, il suffit de les ajouter à l’intent crée précédemment en leur spécifiant une clé permettant de les identifier. Ce qui donnera :

    final String EXTRA_LOGIN = "user_login";
    final String EXTRA_PASSWORD = "user_password";
    	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
            
        final EditText login = (EditText) findViewById(R.id.user_email);
        final EditText pass = (EditText) findViewById(R.id.user_password);
        final Button loginButton = (Button) findViewById(R.id.connect);
        loginButton.setOnClickListener(new OnClickListener() {
    			
    	@Override
    	public void onClick(View v) {
    	Intent intent = new Intent(MainActivity.this, LoginDisplayActivity.class);
    	intent.putExtra(EXTRA_LOGIN, login.getText().toString());
    	intent.putExtra(EXTRA_PASSWORD, pass.getText().toString());
    	startActivity(intent);
    	}
        });
    }
    
    • On déclare les deux identifiants utiles pour pour le passage de données (EXTRA_LOGIN et EXTRA_PASSWORD)
    • On initialise les composants utilises (Zones de saisies pour le login et password)
    • Lors du clic sur le bouton, on récupère les textes saisies par l’utilisateur (getText().toString)
    • Pour finir, on associe ces valeurs (textes) avec l’intent déclaré précédemment (méthode putExtra)

    Maintenant, il faut récupérer les données transmises par l’intent et les assigner aux zones de texte, ce qui donnera :

    public class LoginDisplayActivity extends Activity {
    
    	final String EXTRA_LOGIN = "user_login";
    	final String EXTRA_PASSWORD = "user_password";
    	
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.login_display);
    
           Intent intent = getIntent();
           TextView loginDisplay = (TextView) findViewById(R.id.email_display);
           TextView passwordDisplay = (TextView) findViewById(R.id.password_display);
           
           if (intent != null) {
        	   loginDisplay.setText(intent.getStringExtra(EXTRA_LOGIN));
        	   passwordDisplay.setText(intent.getStringExtra(EXTRA_PASSWORD));
           }
        }
    }
    
    
    • Il faut récupérer l’intent passé à la nouvelle activité à l’aide de la méthode getIntent et vérifier que ce dernier n’est pas nulle
    • Initialiser les deux zones de textes servant à afficher les informations utilisateurs (login / password)
    • Récupérer les deux informations à l’aide de leurs clés et de la méthode getStringExtra. Il faut utiliser la méthode getTypeExtra ou Type correspond au type de la donnée passé
    • Lier les textes récupérés aux TextView à l’aide de la méthode setText

    Ce qui donnera :

    Gestion des erreurs

    On aimerait gérer quelques cas d’erreurs lors du clic sur le bouton “Se Connecter” :

    • Le cas des champs Vides.
    • Adresse mail ne correspondant pas au format d’une adresse mail.

    Pour cela nous allons modifier le fichier “MainActivity’ et rajouter ces différents tests dans la méthode “onClick”.

    • Pour tester si l’adresse mail ne correspond pas au format d’une adresse mail :
    loginButton.setOnClickListener(new OnClickListener() {
    
    	@Override
    	public void onClick(View v) {
            final String loginTxt = login.getText().toString();
    	final String passTxt = pass.getText().toString();
    	// On déclare le pattern que l’on doit vérifier
    	Pattern p = Pattern.compile(".+@.+\\.[a-z]+");
    	// On déclare un matcher, qui comparera le pattern avec la
    	// string passée en argument
    	Matcher m = p.matcher(loginTxt);
    	// Si l’adresse mail saisie ne correspond au format d’une
    	// adresse mail on un affiche un message à l'utilisateur
    	if (!m.matches()) {
    	        // Toast est une classe fournie par le SDK Android
    		// pour afficher les messages (indications) à l'intention de   
                    // l'utilisateur. Ces messages ne possédent pas d'interaction avec l'utilisateur
    		// Le premier argument représente le contexte, puis
    		// le message et à la fin la durée d'affichage du Toast (constante 
                    // LENGTH_SHORT ou LENGTH_LONG). Sans oublier d'appeler la méthode
                    //show pour afficher le Toast
    		Toast.makeText(MainActivity.this, R.string.email_format_error,
    	        Toast.LENGTH_SHORT).show();
    			return;
    		}
    
    	Intent intent = new Intent(MainActivity.this,
    	LoginDisplayActivity.class);
            intent.putExtra(EXTRA_LOGIN, loginTxt);
    	intent.putExtra(EXTRA_PASSWORD, passTxt);
    	startActivity(intent);
    	}
    });
    

    • Puis le cas des différents champs qui ne doivent pas être vides. Pour cela, il suffit simplement de rajouter le code suivant :
    //Si un des deux champs est vide, alors on affiche l'erreurs
    final String loginTxt = login.getText().toString();
    final String passTxt = pass.getText().toString();
    
    if (loginTxt.equals("") || passTxt.equals("")) {
    	Toast.makeText(MainActivity.this,
    		R.string.email_or_password_empty,
    		Toast.LENGTH_SHORT).show();
    	return;
    }
    

    Ce qui donnera :

    Conclusion

    Voila, ce tutoriel se termine ici. En espérant qu’il vous a aidé à mieux comprendre comment fonctionne les activités et les vues sous Android ainsi que comment gérer le passage de données entre deux vues. N’hésitez pas à commenter ou poser vos questions.
    Le code source est disponible à l’adresse suivante

Categories: Tutoriels

101 Responses so far.


  1. lion007 dit :

    merci pour le totoriel c tres important pour les devloppeur android

  2. Moons dit :

    Merci c’est vraiment gentil !

  3. lalit dit :

    Bonjour,
    J’ai suivi votre tuto, mais à la compilation j’ai eu des erreurs et la classe LoginDisplayActivity n’a pas démarré, elle a été stoppé.Et mon logcat affiche les erreurs suivante :
    01-01 09:30:24.708: E/AndroidRuntime(810): java.lang.NullPointerException
    01-01 09:30:24.708: E/AndroidRuntime(810): at com.tutos.android.ui.MainActivity$1.onClick(MainActivity.java:37)
    01-01 09:30:24.708: E/AndroidRuntime(810): at android.view.View.performClick(View.java:4240)
    01-01 09:30:24.708: E/AndroidRuntime(810): at android.view.View$PerformClick.run(View.java:17721)
    01-01 09:30:24.708: E/AndroidRuntime(810): at android.os.Handler.handleCallback(Handler.java:730)
    01-01 09:30:24.708: E/AndroidRuntime(810): at android.os.Handler.dispatchMessage(Handler.java:92)
    01-01 09:30:24.708: E/AndroidRuntime(810): at android.os.Looper.loop(Looper.java:137)
    01-01 09:30:24.708: E/AndroidRuntime(810): at android.app.ActivityThread.main(ActivityThread.java:5103)
    01-01 09:30:24.708: E/AndroidRuntime(810): at java.lang.reflect.Method.invokeNative(Native Method)
    01-01 09:30:24.708: E/AndroidRuntime(810): at java.lang.reflect.Method.invoke(Method.java:525)
    01-01 09:30:24.708: E/AndroidRuntime(810): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
    01-01 09:30:24.708: E/AndroidRuntime(810): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
    01-01 09:30:24.708: E/AndroidRuntime(810): at dalvik.system.NativeStart.main(Native Method)

    quelqun’1 peut il m’aider?
    Merci.

Leave a Reply


Notifiez-moi des commentaires à venir via email. Vous pouvez aussi vous abonner sans commenter.