Logo Icon Logo
A Crowd-sourced Cookbook on Writing Great Android® Apps
GitHub logo Twitter logo OReilly Book Cover Art

Starting a Second Screen from the First

Author: Daniel Fowler -- Published? false -- FormatLanguage: W


New App developers need a simple example on how to open another screen, thus understanding how Android handles UI creation.


Building upon the simple Hello World starter App another screen is loaded from a button to demonstrate the principles of starting a new UI screen.


An App will interact with a user through one or more screens. Each screen presenting information and UI elements, such as buttons, lists, sliders, edit boxes and many others. The number of screens depends upon the required functionality of the App and the type of Android device. A low cost Android phone may have a 3.5 inch display, an expensive phone may have a 5 inch display, and a tablet may have a 10 inch display. An App may only need one screen for functionality on a tablet, two or three screens on the high end phone, four or five on a low cost phone.

Each screen presented to the user is controlled by an Activity. The Activity is responsible for creating and displaying the screen and managing the UI elements. The Android View is the basic building block for UIs. Each screen element, such as a Button or EditText, is provided in the package android.widget. Screen elements are derived from View. They are placed on to the screen within containers derived from a ViewGroup, for example a LinearLayout (ViewGroups are also derived from View). A variety of ViewGroup layouts can be used, horizontal, vertical, table, grid and others.

The home screens can hold special types of View commonly referred to as Widgets; these are small UI gadgets that can be used to provide feedback from an App to the user without the need for a full App to be open. These App Widgets should not be confused with the package android.widget. The latter holds the various types of screen elements, the former is the commonly used name for home screen gadgets. App Widgets are defined using RemoteViews which are also part of the android.widget package.

The many types of Views and ViewGroups available in the Android SDK are displayed in Studio when an Activity layout is open. When a layout resource file is open, and the Design tab at the bottom of the editor is active, a palette of all available UI elements will be shown on the left of the editor. It is possible to filter by API level using the drop down towards the top right of the editor pane.

A Fragment can be defined which is a reusable piece of screen. A Fragment is also laid out using ViewGroups and Views. A Fragment can then be used on more than one screen, thus defining a section of UI once when the same section needs to be used on several screens.

As soon as an App has more than one screen defined there will be a need to load the second screen from the first. In other operating systems a second screen is often loaded directly by the first screen. Due to the design of Android an App can never directly start a new screen; it has to ask the Android operating system to start it. This is because Android was designed for mobility from the start. Android needs full control of an App to enable efficient handling of events outside of the App. Events that must interrupt the user, such as a telephone call or low battery condition; events that notify the user, such as incoming mail or a reminder firing, and the user leaving the App to deal with that notification. The user may also open another App. A variety of things can happen that will need Android to have fine control of how an App executes and responds. When Android starts a screen it knows what is running and their state. Android can dispatch messages to the activities and they can react to unexpected events accordingly. This is also why an App does not have a main method for programs as on other systems (as mention in Android Lifecycle). A main method is not required because Android itself is controlling the start up. To get a screen up and running in an App the following is required:

  1. The definition of the screen must be composed in a layout.
  2. An Activity must be defined in a Java class file to handle the screen.
  3. Android must be notified that the Activity exists, via the Apps manifest file.
  4. The App must tell Android when it is required to start the new screen.

As an example we can add another screen to the basic App created when the Start a new Android Studio project is selected in Studio. The new screen will also contain a simple message and will be started when a button is pressed on the opening screen. Open Studio and start a new project. Give it a name, e.g. Hello World. In this example the default domain of example.com is used which creates a Package name of com.example.helloworld. You may chose your own settings.

Click Next and choose the Phone and Tablet form factor and minimum SDK level, e.g. API 9. Click Next and choose Empty Activity. Click Next and on the Customize the Activity dialog leave Activity Name set to MainActivity, with Generate Layout File checked and Layout Name set to activity_main. Click finish and wait for Studio to finish building the new project (check the status bar at the bottom of the IDE). This new App will be ready to run. A button can be added to the App to display a another screen. With the Design tab active drag and drop a Button onto the initial screen. Use the Component Tree (open it from the right hand side of the IDE) to set the button text to Next.

Now add a new Activity for the second screen, Studio does all the hard lifting. Highlight the app in the project tree to the left of the IDE. Use the context menu or File menu to select New then Activity. Select Empty Activity and leave the settings as default. Activity Name set to Main2Activity, with Generate Layout File checked, Layout Name set to activity_main2, Launcher Activity unchecked, Package name will be com.example.helloworld and Target Source Set at main, finally click finish. Notice how Studio generates the layout XML and the Java class file. With the second activity_main2.xml open in Design drag and drop a TextView on to the screen. As for the Button set the text, e.g. to Hello! Again.

The button needs code to tell Android of our intention to start the activity that contains the new screen. This can be achieved by passing the name of the required activity (Main2Activity) in an Intent object to the startActivity method when the button is pressed. The startActivity method is available on the Context object; Context has a host of useful methods which provide access to the environment in which the App is executing. AppCompatActivity derives from Activity and Context so the startActivity method is always available within an Activity. By using startActivity Android gets the opportunity to perform any required housekeeping and then fire up the Activity class that was defined in the App.

An action handler, onCLickListener, is required for when a Button is pressed. Here the onClick method for the listener is declared in an inner class. Within onClick the code calls startActivity to start Main2Activity via an Intent. An Intent takes a Context and Activity. Since MainActivity is ultimately derived from Context, we can use this (in this case MainActivity.this because of the inner class). Here is the modified code for the MainActivity class. (When entered in Studio undeclared classes will be highlighted and with the cursor on the highlighted class use Alt-Enter to add the relevant Import declaration.)

public class MainActivity extends AppCompatActivity {
    protected void onCreate(Bundle savedInstanceState) {
        findViewById(R.id.button).setOnClickListener(new handleButton());
    class handleButton implements View.OnClickListener {
        public void onClick(View v) {
            Intent intent = new Intent(MainActivity.this, Main2Activity.class);

Studio will have added the second activity definition to the AndroidManifest.xml file in the project. Add the label attribute to the new activity section to change the screen title:

    <activity android:name=".MainActivity">
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
    <activity android:name=".Main2Activity" android:label="@string/screen2Title"></activity>

The label's value, @string/screen2Title, points to an entry in the res/strings.xml file:

    <string name="app_name">Hello World</string>
    <string name="screen2Title">Screen 2</string>

In the manifest file the dot in front of MainActivity and Main2Activity signifies that the activity is within the application package. If the activity was defined in another package then the activity name would include the full package name.

When the App runs the first screen will show:

And pressing the Next button shows:

A button is not required to go back to the first screen. Android automatically provides a back button for all screens as part of the platform.


The source code for this project can be downloaded from http://tekeye.uk/android/examples/download/secondscreen.zip.
idarwin 2014-01-29 18:40:47.4 It looks like you didn't "copy the code exactly", but that you changed the name of the package in your source code but not in the AndroidManifest.xml: I copied the exact code into a new project to play around with it, and I ran into a few errors. 06-29 21:14:04.464: E/AndroidRuntime(980): FATAL EXCEPTION: main 06-29 21:14:04.464: E/AndroidRuntime(980): android.content.ActivityNotFoundException: Unable to find explicit activity class {com.jpv.switchscreens/com.jpv.switchscreens.secondscreen}; have you declared this activity in your AndroidManifest.xml? 06-29 21:14:04.464: E/AndroidRuntime(980): ... Try making sure that your AndroidManifest definition of the package agrees with what's really there, and see if that solves your problem.
JVest2012 2013-06-29 17:19:11.764 I copied the exact code into a new project to play around with it, and I ran into a few errors. 06-29 21:14:04.464: E/AndroidRuntime(980): FATAL EXCEPTION: main 06-29 21:14:04.464: E/AndroidRuntime(980): android.content.ActivityNotFoundException: Unable to find explicit activity class {com.jpv.switchscreens/com.jpv.switchscreens.secondscreen}; have you declared this activity in your AndroidManifest.xml? 06-29 21:14:04.464: E/AndroidRuntime(980): at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1618) 06-29 21:14:04.464: E/AndroidRuntime(980): at android.app.Instrumentation.execStartActivity(Instrumentation.java:1417) 06-29 21:14:04.464: E/AndroidRuntime(980): at android.app.Activity.startActivityForResult(Activity.java:3370) 06-29 21:14:04.464: E/AndroidRuntime(980): at android.app.Activity.startActivityForResult(Activity.java:3331) 06-29 21:14:04.464: E/AndroidRuntime(980): at android.app.Activity.startActivity(Activity.java:3566) 06-29 21:14:04.464: E/AndroidRuntime(980): at android.app.Activity.startActivity(Activity.java:3534) 06-29 21:14:04.464: E/AndroidRuntime(980): at com.jpv.switchscreens.MainActivity$handleButton.onClick(MainActivity.java:21) 06-29 21:14:04.464: E/AndroidRuntime(980): at android.view.View.performClick(View.java:4204) 06-29 21:14:04.464: E/AndroidRuntime(980): at android.view.View$PerformClick.run(View.java:17355) 06-29 21:14:04.464: E/AndroidRuntime(980): at android.os.Handler.handleCallback(Handler.java:725) 06-29 21:14:04.464: E/AndroidRuntime(980): at android.os.Handler.dispatchMessage(Handler.java:92) 06-29 21:14:04.464: E/AndroidRuntime(980): at android.os.Looper.loop(Looper.java:137) 06-29 21:14:04.464: E/AndroidRuntime(980): at android.app.ActivityThread.main(ActivityThread.java:5041) 06-29 21:14:04.464: E/AndroidRuntime(980): at java.lang.reflect.Method.invokeNative(Native Method) 06-29 21:14:04.464: E/AndroidRuntime(980): at java.lang.reflect.Method.invoke(Method.java:511) 06-29 21:14:04.464: E/AndroidRuntime(980): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 06-29 21:14:04.464: E/AndroidRuntime(980): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 06-29 21:14:04.464: E/AndroidRuntime(980): at dalvik.system.NativeStart.main(Native Method) Any help would be much appreciated. Thank you.