Introduction
In this article we will be implementing welcome page and list page. We will also work with settings to skip welcome page. By the end of the article, we will come to know about activities, layouts and AndroidManifest.xml.
Scenario
The very first time when the app is launched, welcome page is displayed. User is allowed to make a choice whether it should be skipped next time the app is launched. If yes, ‘Do not show it again?’ is checked before moving on to the next screen.
Activity and Fragment
Before we start working on the design aspects of welcome and list views, I will brief you about Android Application Framework’s main components Activity and Fragments.Each visible page in android app is an Activity, these are managed by Android, so they must be defined in androidManifest.xml
.
One of them must be designated as the main activity to serve as the entry point of Android’s framework into our code. There can be many activities in the application but only one will be active at any point of time.
If we want to have multiple views in an Activity or would like to dynamically add/remove views or reuse an Activity’s view then we need to use Fragments. An activity itself can be on its own or composed of Fragments. A Fragment can be re-used by more than one Activity. We can define the fragments in the layout itself or add them to the activity programatically.
If we want to perceive the architecture from an MVC point of view. We can think of Activities and Fragments as the controller components, whereas the xml layouts are the views and the model is manufactured within the controller and bound to the view.
There are also components other than Activity and Fragment which we will discuss later when we use them. In this article, we will only use Activities.
We will have one activity for the ListView
and one for the Welcome Page. We will make ListActivity
the main activity. If user wants to see the welcome page then ListActivity
should simply delegate the control to WelcomeActivity
.
List View
To display list view, we need a view and an activity. Let’s first create the view.Add an xml file in layout folder. Go to File->new, click on Android XML File
, select root element as ListView
, enter the file name and finish. ListView
is one of the layouts provided by the framework. It is also called an AdaptorView
where the model is not pre-determined and needs to be bound dynamically to it. We will do that in ListActivity
class.
<ListView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/myList" android:layout_width="fill_parent" android:layout_height="fill_parent"/>
List Activity
onCreate()
method when the activity is first created. We next bind the view to the activity and model to the view. The view is identified by the id attribute value assigned in the ListView
xml. Call setContentView()
to bind a view.ArrayAdapter
which takes the current context, the layout id and the array. We will use android’s in-built list layout.public class ListActivity extends Activity { private ListView listView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.my_list); listView = (ListView) findViewById(R.id.myList); String[] listeStrings = { "Item1", "Item2", "Item3", "Item4" }; listView.setAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_1, listeStrings)); } }
Welcome Activity
public class WelcomeActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.welcome); } }
Setting
We now need to use a setting to decide whether to remain in ListItem
screen or delegate the call to WelcomeActivity
. Android has in-built support for settings, PreferenceManager
helps us manage the settings. We will introduce a new setting skipWelcome
. If its value is true, user will see List page else will be taken to the welcome page. This is configured in onCreate()
. A call to startActivity will stop the current activity and resume the activity class passed in.
public class ListActivity extends Activity { private ListView listView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.my_list); listView = (ListView) findViewById(R.id.myList); String[] listeStrings = { "Item1", "Item2", "Item3", "Item4" }; listView.setAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_1, listeStrings)); if (!PreferenceManager.getDefaultSharedPreferences(this).getBoolean("skipWelcome", false)) { startActivity(new Intent(this, WelcomeActivity.class)); } }
Save Setting
We will have to save the skipWelcome
setting when the user clicks on next button and the preference value is true. This will we implement by adding a listener to the next button.
public class WelcomeActivity extends Activity { public static final String SKIP_WELCOME = "skipWelcome"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.welcome); Button nextPage = (Button) findViewById(R.id.next_button); final CheckBox skipAbout = (CheckBox) findViewById(R.id.skip_welcome_cb); nextPage.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(WelcomeActivity.this); if (skipAbout.isChecked()) { SharedPreferences.Editor editor = prefs.edit(); editor.putBoolean(SKIP_WELCOME, true); editor.commit(); } startActivity(new Intent(WelcomeActivity.this, ListActivity.class)); } }); } }
Setting Activity
skipWelcome
setting. For this, we need a settings view and an activity. To create the view, select resource type Preferences
and root element PreferenceScreen
in the new Android XML file. Since skipWelcome
is a checkbox, we will add a CheckBoxPreference
child element with default value false.<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" > <CheckBoxPreference android:defaultValue="false" android:key="skipWelcome" android:title="@string/action_settings" /> </PreferenceScreen>
We also need an activity class. Instead of extending Activity directly, SettingsActivity
extends PerefernceActivity. In the
onCreate()
, we bind the view by calling addPreferencesFromResource(R.xml.settings);
public class SettingsActivity extends PreferenceActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.settings); } }
Now we should add the setting to the menu. We will create the menu in our ListActivity
.
package com.jopc.sandbox; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.preference.PreferenceManager; import android.view.Menu; import android.view.MenuItem; import android.widget.ArrayAdapter; import android.widget.ListView; public class ListActivity extends Activity { private ListView listView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.my_list); listView = (ListView) findViewById(R.id.myList); String[] listStrings = { "Item1", "Item2", "Item3", "Item4" }; listView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, listStrings)); if (!PreferenceManager.getDefaultSharedPreferences(this).getBoolean("skipWelcome", false)) { startActivity(new Intent(this, WelcomeActivity.class)); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { startActivity(new Intent(this, SettingsActivity.class)); return true; } return super.onOptionsItemSelected(item); } }
AndroidManifest.xml
In AndroidManifest.xml
, we define all the three activities ListActivity
, WelcomeActivity
and SettingsActivity
. ListActivity
will be our main activity.
<application android:allowBackup="true" android:icon="@drawable/ic_launcher_sandbox" android:label="@string/app_name"> <activity android:name="com.jopc.sandbox.ListActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <activity android:name="com.jopc.sandbox.WelcomeActivity"></activity> <activity android:name=".SettingsActivity" android:label="@string/action_settings"> </application>
There is still one issue with ListActivity
being the main activity. If the user has not opted for ‘skipping the welcome page’, the list activity will delegate the call to welcome page. When you click on next, ListActivity
is called but the control doesn’t stay on this page as the use has still on checked the ‘skip welcome’ option so it again delegates it back to welcome page.
This is a bug and we should fix it right away by making the welcome page the main activity. The welcome page will decide whether to stay in the same page or move on to ListActivity
based on the ‘skipWelcome’ preference.
package com.jopc.sandbox; import android.app.Activity; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.preference.PreferenceManager; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.CheckBox; public class WelcomeActivity extends Activity { public static final String SKIP_WELCOME = "skipWelcome"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.welcome); Button nextPage = (Button) findViewById(R.id.next_button); final CheckBox skipAbout = (CheckBox) findViewById(R.id.skip_welcome_cb); nextPage.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(WelcomeActivity.this); if (skipAbout.isChecked()) { SharedPreferences.Editor editor = prefs.edit(); editor.putBoolean(SKIP_WELCOME, true); editor.commit(); } startActivity(new Intent(WelcomeActivity.this, ListActivity.class)); } }); if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(SKIP_WELCOME, false)) { startActivity(new Intent(this, ListActivity.class)); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { startActivity(new Intent(this, SettingsActivity.class)); return true; } return super.onOptionsItemSelected(item); } }
Now the welcome page will be the main activity. Our androidManifest.xml
looks like below:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.jopc.sandbox" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:maxSdkVersion="21" android:minSdkVersion="4" android:targetSdkVersion="21" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher_sandbox" android:label="@string/app_name" > <activity android:name="com.jopc.sandbox.ListActivity" android:label="@string/app_name" > </activity> <activity android:name="com.jopc.sandbox.WelcomeActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".SettingsActivity" android:label="@string/action_settings" > </activity> </application> </manifest>
Design Diagram
Variation
One of the variations would be to use a web view instead of static text like ‘Welcome to sandbox’.
Also we may like the user to slide through a bunch of pages before showing the final page with ‘Do not show this again’ checkbox. We will work on the variations in our next article.
Download the source code
You can download the source code here: sandboxSkipWelcome.zip