sexta-feira, 12 de outubro de 2012

How to navigate between screens in Android


Hello everyone.

Up to this topic, we have learned how to install Android, create a project and even create fine layouts. What next? So far, in all examples seen was used at most one screen for example. The next step to be taken is to learn to navigate in more than one screen in the same application.

On Android, each screen is a Java class that extends the Activity class. To navigate between more than one Activity, we use the Intent class. If we are in an Activity and want to go to another, we have to call an Intent (ie have the "intention" of changing from one screen to another).

To understand the concept of Intent, we will create three very simple examples that basically pass through multiple screens of the same application. In the 1st example, we will create a simple transition from one screen to another. In the 2nd example, we will create a transition from one screen to another where the source screen sends a variable to the target screen. In the 3rd example, we will create a transition from one screen to another where the target screen returns a value to the source screen. This post will be divided between these three examples.

Simple transition from a source screen to a target screen
In Android, when we create a project in Eclipse, the AndroidManifest.xml file is generated, which is a configuration file where we report various informations, such as which screens exists in the application, which is the minimum and maximum API of the Android API that the application may run, among others. So, the first step to be taken in the creation of our example is to tell the AndroidManifest.xml the screens that we use in our application. Suppose we have 3 screens in our application: Screen1Activity.java, Screen2Activity.java Screen3Activity.java (is advised on Android to have the name of an Activity with the posfix "Activity"). So we need to declare them in the AndroidManifest.xml file, as shown below:



Agora que já temos as Activity's declaradas no AndroidManifest.xml, o próximo passo será criar o layout de cada uma dessas telas. De início, criaremos algo bem simples, como uma TextView sendo mostrada no centro da tela. Algo como isso:



For each screen, the parameter android:text="@string/screen1_title" shall be adjusted to the proper names (for Screen2 for example, the parameter is android:text="@string/screen2_title", and similarly for Screen3).

Then we need to create the Activity's of these screens (Java classes extending the Activity class). They basically follow this model:



Now that we created all our screens, its layout's, and declared all in AndroidManifest.xml, we can finally deal with the Intent's, allowing us to navigate among these 3 screens.

To navigate between screens, we need to create a user input device to select it when this transition occurs between screens. The best device for this case is to create a Button that, when clicked, change the current screen of the application. For that, we'll create a Button in Screen1Activity.java and other Button in Screen2Activity.java. The idea is that the transition occurs from the Screen1 to Screen2, and from Screen2 to Screen3.

Modifying the layout of Screen1, we have the following content in the XML file:



And it's layout will be as shown below:



Now, we need to map the id of the Button in our Activity (as is taught in the previous post). Modifying the structure of the source code of the screen Screen1Activity.java, we have the following content:



Now, we just need to implement the call to Screen2. For we call another screen in Android, we use an Intent. The syntax of a call to a class Intent is shown below:


The constructor of Intent class is: Intent intent = new Intent(packageContext, cls). The argument "packageContext" is the context of the current Activity. The argument "cls" is the class of Activity for which the current Activity want to go. In the image above, the values ​​of these arguments are, respectively, "Screen1Activity.this" and "Screen2Activity.class". So, we have the "intention" to migrate from Screen1 to Screen2.

The complete source code of Screen1Activity.java is shown below:



Now we simply need to adapt this source code for Screen2Activity.java, to have implemented the transition between Screen2 and Screen3. And it's done! We'll have implemented an application with several screens, and the transition between them.

Now, we will see how to implement a transition between two screens in which the target screen will send data to the target screen.

Transition from a source screen to a target screen with sent information between them
In the transition above, we used the method startActivity() to make the transition between screens. However, it was an easy transition, without sending information. This time, we'll send information from one screen to another. To perform this kind of task, we'll use again the method startActivity(). However, we'll modify a bit it's structure, as shown below:



The above image is the updated content of the event onClick(). What has changed here is that was included a Bundle on the Intent that calls the next screen. In Android, Bundle is the class that stores what is sent from one screen to another. This class has several methods. In the image above, we can see the method putString(). This method receives the "key" that will pass the string to the next screen, and it's value. The key is a value (always String) which we use to obtain, in the target screen, the passed data from one screen to another.

Now that we transmited data from the source screen to the target screen, we need to capture these data in the target screen (in this case, in Screen2Activity.java). This is done through the method getIntent().getExtras(), which returns a Bundle. Below is shown the source code of a custom method that performs this task.



Some comments need to be made about the image above:

  • We have to check if the extras are null or not. This is very important because we can call a screen from different parent screens. For example, both Screen1 as Screen2 may call Screen3. And if Screen1 send data to Screen3, the extras from the image above won't be null. But if Screen2 don't send data to Screen3, the extras from the image above will be null.
  • mTextView is an attribute of Screen2Activity.java, which is nothing more than the TextView of this screen. As we are getting data from the previous screen, to check whether these data come from Screen1 to Screen2, we'll update this TextView.

The complete source code for this screen is shown below:



And it's done! We already know how to pass data from one screen to another. Following this topic, we will see how to implement a transition between two screens when the target screen returns a value to the source screen.

Transition from a source screen to a target screen, with information sent from the target screen to the source screen
In the above transitions, we used the method startActivity(). This time we will use another method: startActivityForResult(). With this method, the destiny Activity can return informations to source Activity. This is quite useful in some cases.

For example, suppose we have a Screen1, that can call either Screen2 as Screen3. This case, if Screen1 was a customer base, Screen2 a customers deletion and Screen3 a customer registration, when we open Screen2 or Screen3 and perform some operation, we will be redirected to Screen1. But in this screen we need to know whether the deletion/registration was successful or not. In this case, we need to send some feedback to Screen1, from the end of execution of screens 2 and 3. This is done with the method startActivityForResult().

Below is shown a basic example of this functionality. The idea is that an Activity is called in Screen1, and that the daughter Activity returns an information to Screen1. The Screen1 may call both Screen2 and Screen3. This information will be captured by Screen1 through the event: protected void onActivityResult (int code, int result, Intent intent). Let's see our example.

Below is shown the XML layout of our screens.







And the source code of Screen1Activity.java:



And now, the source code of Screen2Activity.java. Screen3 will be similar to this screen.



Now, let's run this example, to set right all that was said above. Clicking on the "Go to Screen 2," here's what happens:



Now we are in Screen2. Clicking the "Return to previous screen" button, here's what happens:



Basically, what happened was that the Screen1 received a return from it's child Activity. Thus, we can identify which of the screens was called by Screen1.

And it's done! We already know how to pass data from one screen to another in every possible way. But before we close this topic, we will talk about a very useful property layout in Android.

When a button is clicked, the ideal would be the user to have a feedback of what happened. In other words, when the button is clicked, stay in one color. When loose, stay in another. Thus, the user will know if the click event of the button was activated or not. We will implement this in our example.

Initially, we will implement the XML file that "animates" the button. Let's call it "button_behavior.xml". Your source code is:




So, when the button is clicked, a drawable will be called. When he is not clicked, another drawable will be called. Now, we need to understand the content of the mentioned events of the above file (pressed_behavior.xml and normal_behavior.xml). Below is shown the source code of these files:





These files have some parameters:

  • gradient  This parameter selects the color the button will have. It can have 3 different mixed colors. For our example, we will have an identical color gradient (the same for each gradient option) in each drawable.
  • corners  This parameter creates smooth contours on the button. In our case, we have the button corners slightly rounded in a size of 3dp.
  • stroke  Parameter that provides an edge on our button. Here, we have a black border of 1px size.

NOTE: There are other parameters besides the three above. But they will not be seen this time.

Now we need to turn this animation on the buttons of our example. To do this, simply include the parameter android:background="@drawable/button_behavior" in each of the buttons on our application. By doing so, we will have much more stylish buttons, which are very intuitive to the user.

-----

And here ended another blog topic.

If someone has a question, suggestion or criticism, feel at ease.

Nenhum comentário:

Postar um comentário