4 Fragments, ActionBar, and Menus

Chapter Objectives

In this chapter you will:

  Explore how to build applications that use an ActionBar and Fragments.

  Understand the Fragment lifecycle.

  Learn to configure the ActionBar.

  Implement Fragments with Responsive Design Techniques.

  Explore animation in Fragment Transactions.

  Experiment with Fragments, ListViews, and ArrayAdapters.

  4.1 Fragmentation and Android Fragments

Android devices come in many shapes and screen sizes, and they have different performance characteristics. Multiple versions of Android are concurrently being used and supported at any given time. Often, companies produce their own variants on the system’s user interface, which can change the look of default elements. It can be challenging, problematic, and time-consuming to develop an Android application that works optimally in this fragmented environment; however, fragmentation also has benefits for both users and developers. The availability of affordable Android devices makes them accessible to a large number of consumers. For developers, this translates into a wider audience and market for applications.

A well-designed app is partly characterized by its user interface, which must be as easy to navigate and use as possible. When designing and coding layouts, several factors should be considered, such as spacing, positioning, size, and the grouping of user interface controls. Layouts must be compatible to many physical screen sizes; as screen sizes vary, so do the positioning, spacing, and size of these control elements on the screen. The user interface layouts must resize correctly when run on different devices, and they must respond to changes, such as moving from portrait to landscape orientation.

The design concept behind Android’s Fragment class was conceived with the goal of promoting reuse of, and interaction between, the different elements that make up an application. Rather than simply using an Activity and a Layout to define the complete user interface of an application screen, it is often more efficient to use fragments. The user interface can be divided into logical sections, with these sections represented by fragments. A fragment can then be reused in more than one screen within the application.

A Fragment is modeled as a subdivision of an Activity. In other words, a Fragment is integrated into an Activity; therefore, it needs an Activity to run. Using Fragments in building applications helps the developer easily present a consistently well-designed user interface. Fragments are particularly helpful in adapting a user experience across a wide range of devices.

  4.2 The Fragment Lifecycle

Fragments are associated with an activity and can be created, added, or removed while the activity is running. For example, an application can use one fragment for receiving its own input events, thus allowing the user to input information, and use another fragment for rendering output.

Like an Activity, a Fragment has its own lifecycle, as well as its own user interface. The Fragment’s lifecycle is connected to the activity that owns it. Each fragment has its own callback methods in the standard Activity lifecycle.

The following code listing illustrates a Fragment class that overrides several of its callback methods that are joined with an activity.

Lines 3–9:

onCreate() is called to do initial creation of the fragment. Just as in an Activity, saved state changes can be restored in this method. onCreate() can be called while the fragment’s activity is still in the process of being created.

Lines 11–17:

onStart() is called at the start of the fragment lifecycle. This method makes the fragment visible to the user, based on starting its containing activity. It is typical to apply user interface changes within this method.

Lines 19–27:

onResume() makes the fragment interact with the user, based on resuming its owner activity.

Lines 29–37:

onPause() is called when the fragment is no longer interacting with the user, either because its activity is being paused or because a fragment operation is modifying it within the activity.

Lines 39–46:

onSaveInstanceState is called to save the user interface state changes at the end of the activity lifecycle.

Lines 48–57:

onStop() is called when the fragment is no longer visible to the user, either because its activity is being stopped or because a fragment operation is modifying it in the activity. onDestroyView() allows the fragment to clean up resources associated with its View.

Lines 60–66:

onDestroy() is called to do final cleanup of the fragment’s state. onDetach() is called immediately before the fragment stops being associated with its activity.

image

image

A fragment layout can be installed in an activity using setContentView(), as shown in the code segment that follows:

image

As previously illustrated, a Fragment has the same callback methods as an Activity; however, it also has its own set of callbacks. For example, when a fragment is no longer being used, it goes through a reverse series of callbacks, including onPause(), onStop(), and onDestroy(). Additionally, callbacks are made to onDestroyView() and onDetach() to carry out actions specific to Fragments.

The following list outlines the additional callbacks used in the lifecycle of a Fragment:

onCreateView()

This is a core lifecycle method that is called to bring a fragment up to a resumed state, interacting with the user. This callback method creates and returns the view hierarchy associated with the fragment.

onInflate()

Called every time the fragment is inflated.

onActivityCreated()

Called when the fragment’s activity has been created and this fragment’s view hierarchy is instantiated. Final initializations, such as restoring a state or retrieving a view, are often implemented here.

onAttach()

Called after the fragment has been attached (associated) to an activity.

onDestroyView()

Informs the fragment that its view is being destroyed so that it can clean up any associated resources. This is called after onStop() and before onDestroy().

onDetach()

Called when the fragment is no longer attached to its activity, after onDestroy(). This is the final call before the fragment object is released to the garbage collector.

The following code listing illustrates these callbacks in FragmentB:

image

image

  4.3 Action Bar

The action bar is a vital and flexible design element for an application. A rectangular window feature that appears at the top of the screen, the action bar provides information and displays control elements to the user.

In a basic configuration, the action bar displays the application icon and a title. The title often identifies the running activity. In this simple format, users have an indication of where they are and a consistent identity from which to recognize the application.

In a more complex configuration, the action bar can feature user action control elements, navigation modes, and drop-down menus. The purpose of the action bar, as in the one shown in Figure 4-1, is to improve user interaction and provide a higher quality experience. It supports easy navigation through action controls, featured as tabs and drop-down lists.

The action bar was first introduced in Android 3.0. Support for older versions can also be achieved but requires the use of the Android Support Library. The action bar is included by default in all activities for applications with a minimum SdkVersion of 11.

An action bar can be constructed with the following features:

Application Icon:

 

 

The application icon can be used as a unique identification for an application. To the right of the icon is the View control, the title element that can specify the application name or the activity the user is currently using.

Action Items:

Action items are buttons for the most used action of the application. To provide quick and easy access, it is also typical to include action buttons for the important actions that require accessibility and prominence. If all of the specified action buttons cannot be displayed on the screen, those that do not fit will automatically be moved to the action overflow menu.

Action Overflow:

 

The action overflow menu is a drop-down menu list that is often used for actions performed less frequently. This is also the location of actions that do not fit on the main action bar.

image

images  FIGURE 4-1 The ActionBar of an application.

  Lab Example 4-1: Fragments and the ActionBar: Menu Experiment

This lab features the Actionbar Experiment I application. It is a first look at the basics of fragments that also explores how an action bar is used so we can better understand its association with the user interface.

Part 1: The Design

Actionbar Experiment is an app that illustrates how fragments can use the ActionBar Android user interface component. This app combines four fragments into a single activity to build a multipane user interface. These fragments are basic, yet self-contained, components. Each fragment holds a photograph representing one meal in a given day: breakfast, snack, lunch, and dinner.

image

images  FIGURE 4-2 An Actionbar containing Tabs.

The action bar for this application displays a unique application icon. It also supports consistent navigation and view switching through the use of Tabs, as shown in Figure 4-2. The application is made up of four Tabs and four corresponding Fragments. When a Tab is selected, its corresponding Fragment replaces the fragment currently located on the screen.

Part 2: Application Structure and Setup

The settings for the application are as follows:

•  Application Name:

Actionbar Experiment

•  Project Name:

ActionbarExperiment

•  Package Name:

com.cornez.actionbarexperiment

•  Android Form:

Phone and Tablet

•  Minimum SDK:

API 18: Android 4.3 (Jelly Bean)

•  Target SDK:

API 21: Android 5.0 (Lollipop)

•  Compile with:

API 21: Android 5.0 (Lollipop)

•  Activity Name:

MyActivity

•  Layout Name:

activity_my

The application does not use the Android default ic_launcher.pg file. The launcher icon is the bitmap file provided in the textbook resources. This bitmap file stores the icon as a PNG and is added to the drawable folder, along with PNG files representing the meal photographs: breakfast, snack, lunch, and dinner.

The final project structure for the Actionbar Experiment application is shown in Figure 4-3. The project is driven by a single Actvity, MyActivity.java, and a set of Fragment subclass source files. The Fragment files are Breakfast Fragment.java, SnackFragment.java, LunchFragment.java, and DinnerFragment.java.

image

images  FIGURE 4-3 Project structure for the ActionBar Experiment application.

In addition to the activity layout, activity_my.xml, each of the four Fragment classes have their own associated layout files. Finally, a colors.xml file is used to store a backdrop color.

The orientation of the screen will be locked into landscape mode. It should be noted that when an application is viewed in landscape mode, the action bar might be configured differently from the normal portrait view. Android automatically rearranges visible icons located on the action bar depending on several factors, such as the amount of space available to accommodate the icon, action control icons, and so forth. In landscape mode, for example, an “add” option is often shown as an icon on the action bar rather than in the drop-down menu.

Unlike an Activity, a Fragment is never declared in the Android Manifest.xml file. The following is the code listing for AndroidManifest.xml used by the Actionbar Experiment I application:

image

Part 3: External Value Resources

strings.xml and colors.xml are the two value resource files used by the Actionbar Experiment application. strings.xml has been edited to contain the action bar Tab strings. colors.xml is created to store the background color, black, to be used as a backdrop for the fragments as they enter and exit the screen.

The XML code listings for strings.xml and colors.xml are as follows:

image

Part 4: Creating the User Interface and a Fragment

The user interface for the Actionbar Experiment application consists of five layouts. The layout associated with the running activity is always visible while the app is visible. This layout, activity_my.xml, uses a ViewGroup container, shown in Figure 4-4, to hold incoming and outgoing fragment layouts.

image

images  FIGURE 4-4 activity_my.xml contains a LinearLayout view for storing fragments.

The code listing for activity_my.xml is as follows:

Line 6:

A black backdrop is applied to the background of the root element, a LinearLayout.

Line 8:

The class MyActivity is the associated activity specified for this layout.

Lines 11–17:

A LinearLayout container ViewGroup is declared. The name assigned to this container is fragment_container.

image

Each of the four Fragments used by the app has an associated layout that stores the photograph of a meal. The code listing for these XML files is shown below. Figure 4-5 illustrates the graphic visual design of the layout for fragment_snack.xml.

All four layouts will consistently feature the following properties:

Line 6:

A black backdrop is applied to the background of the root element, a LinearLayout.

Lines 8–14:

An ImageView is declared to store a drawable image.

image

image

image

images  FIGURE 4-5 The fragment_snack.xml layout shown in landscape orientation.

image

image

image

Part 5: Defining the Fragment Subclasses

To create a fragment for use in an application, a subclass of Fragment must be created, if it does not already exist. A Fragment class uses code that looks very much like an Activity. It contains callback methods similar to an Activity, such as onCreate(). Oftentimes, you can convert an existing Android application to use Fragments by moving code from an activity’s callback methods into the respective callback methods of the Fragment.

The BreakfastFragment class is an extension of the Fragment class. It has its own lifecycle, yet it is tied to MyActivity.

Lines 11–13:

The method onCreateView (LayoutInflater, ViewGroup, Bundle) is a core lifecycle method that is called to bring the fragment up to the resumed state (interacting with the user). This callback method creates and returns the view hierarchy associated with the fragment.

Line 16:

The inflate() method inflates a new view hierarchy from the specified XML resource; in this case, fragment_breakfast.xml. The container argument specifies the ViewGroup location where the fragment will be inflated.

The code listing for the implementation of the four Fragment subclasses is as follows. Each is responsible for inflating its associated user interface layout.

image

image

Part 6: Source Code for the App Activity

MyActivity is the sole Activity used by the Actionbar Experiment application. This Activity source file is responsible for displaying the app’s user interface that will hold Fragments as they enter and exit the screen.

Lines 3, 5–6:

The imports for ActionBar, Fragment, and FragmentTransaction are required when configuring an ActionBar and binding its controls to an Activity or Fragment.

Lines 26–27:

The actionBar object is instantiated. Its navigation mode is set to NAVIGATION_MODE_TABS, which will allow the application to utilize Tabs for navigation.

Line 28:

The title element in the action bar can be disabled by setting the attribute setDisplayShowTitleEnabled to false.

Lines 31–38:

Four Tabs are constructed using ActionBar.Tab. Note that these tabs have not yet been added to the ActionBar.

Lines 41–44:

The Fragment objects used by the application (breakfastFragment, snackFragment, lunchFragment, and dinnerFragment) are instantiated.

image

image

Within the ActionBar, Tabs can trigger an event only if an event listener has been applied.

Lines 46–58:

A listener event is registered to each of the Tabs located on the ActionBar. Set the ActionBar.TabListener that will handle switching to and from a specific tab. The handler for the listener event is the anonymous class MyTabListener().

It should be noted that all tabs must have a TabListener set before being added to the ActionBar.

Lines 60–64:

Tabs are added to the ActionBar.

Lines 68–71:

If application has not been launched for the first time, the state of the navigation is restored using a constant, TAB_KEY_INDEX.

image

image

The handler for the Tab listener events is the class MyTabsListener. This class implements the ActionBar.TabListener interface. Its callbacks will be invoked when a tab is focused, unfocused, added, or removed from the ActionBar.

Lines 76–78:

The constructor of this class assigns the Fragment whose layout will appear on the screen.

Lines 80–83:

Implementation for onTabReselected will not be used.

Lines 85–89:

When a Tab is selected from the ActionBar, its associated Fragment layout will replace the current layout located in the fragment_container within the activity layout.

When a Tab is unselected, the remove() method of FragmentTransaction will remove the existing fragment. If it was added to a container, its view will also be removed from that container.

image

image

  4.4 ActionBar Configurations

Control elements that appear directly on the action bar as an icon and/or text are known as action buttons.

When an Activity starts, its associated layout is inflated on the screen and the action bar is populated with action buttons, such as the one shown in Figure 4-1. The activity’s onCreateOptionsMenu() method is responsible for inflating a menu hierarchy from a specified XML resource file.

In the following sample code segment, onCreateOptionsMenu() calls getMenuInflater().inflate (R.menu.my, menu) to inflate the menu and add the defined items from the menu to the action bar. The name of the resource file in this example is my.xml. By default, every Activity supports an options menu of actions or options.

image

The menu resource file, such as the example my.xml, is always located in the res/menu directory of the project. The action button item definitions are specified using the <item> tag. The following XML file produced the action bar shown in Figure 4-1.

Lines 1–38:

Five button elements are defined using the <item> tag.

Lines 5–10:

The first action button is defined.

Line 6:

Each action button is given an identifier name, such as menuitem_search.

Line 7:

Many icon images are available through android.R.drawable. These are publicly accessible files and can be used in Android applications. Unique bitmaps for action button icons can also be constructed by the app developer and placed in the drawable folder. For the search action button, the icon value assigned ic_menu_search. A complete list of these R.drawable files can be found at developer.android.com/reference/android/R.drawable.html.

Line 8:

showAsAction is an attribute that defines how the item will be displayed in the action bar. The possible values for this attribute are: collapseActionView, ifRoom, never, and withText.

Action buttons that cannot fit (ifRoom) on the action bar, due to constraints in size, are placed in the action overflow menu. Action buttons that are less important to the activity or application can specifically designate the overflow menu as their required location.

Line 9:

title attribute represents the title associated with the item. The format required is a String value. The string ui_menu_search was defined in strings.xml.

image

image

Several options are available when configuring the ActionBar. For example, if a menu item supplies both a title and an icon, as shown with the previous example, the action button always displays the icon by default. To display both the title and the icon, the withText value can be added to the showAsAction attribute.

The title of an action button should always be defined, even if it does not appear in the action bar. This provides flexibility in the application. For example, if the user performs a long-press on the button icon, a tool-tip containing the title will be revealed.

An action bar can be divided into two action bars: one on the top of the screen and the other on the bottom, as shown in Figure 4-6. This is helpful when more space is needed, such as when the action bar is found to be narrow. The top action bar contains the application icon and title. The bottom action bar has more room; thus, more of the action button will be visible to the user.

image

images  FIGURE 4-6 Action bar with five action buttons and the overflow button.

To split the action bar, the attribute android:uiOptions can be applied to the activity or the application in the AndroidManifest file. This option is supported in API level 14 and above. To add support for lower API levels, a metadata element must be applied. The following XML code segment is an example activity definition in an AndroidManifest.xml file:

Line 4:

A splitActionBarWhenNarrow value applied to the android:uiOptions attribute.

Lines 6–7:

UI options can be applied in a metadata element. Metadata is simply a name-value pair for an item of additional, arbitrary data that can be supplied to the parent component. A component element can contain any number of <metadata> subelements.

image

4.4.1 Overflow on the Action Bar

Narrow devices can often require the use of the overflow button. When creating layouts on devices with a narrow screen, it is best to use ifRoom to request that an item appear in the action bar. It is also a good design technique to allow the system to move elements into the overflow when there is not enough room. Figure 4-7 shows action buttons Quit and Settings placed in the overflow menu.

image

images  FIGURE 4-7 Buttons placed in the overflow menu display text titles.

The code for the XML menu resource file that produced the action bars displayed in Figure 4-7 is as follows:

image

image

4.4.2 Adding an Action View

An action view is simply a widget that appears in the action bar as a substitute for an action button. An action view provides quick access to heavily used actions. By placing these actions directly on the action bar, they appear as a consistent tool the user can easily utilize across multiple activities and fragments. From a developer’s standpoint, the action bar can be designed once and used throughout the application screens.

Consider a collapsible search view widget. A search action view can be added as an embedded search view widget in the action bar.

To declare an action view, the actionLayout or actionViewClass attribute can be added to an item to specify either a layout resource or a widget class. The following segment of XML code adds a search view widget item to an action bar:

Line 3:

actionViewClass is an optional View class that uses an action view. android.widget.SearchView provides the user interface for entering a search query.

Line 5:

The showAsAction attribute is set to, or includes, the collapseActionView value. This is optional and declares that the action view should be collapsed into a button.

image

When a user executes a search request, the system starts your searchable activity and sends it to an activity action that performs the search.

  Lab Example 4-2: Unit Conversion Calculator App

The objective of this lab example is to illustrate the use of the overflow menu as an option for presenting action tasks to the user. Using the overflow menu as a tool for application task navigation provides the user with action items that are available at all times, regardless of which activity or fragment is active. In addition, the overflow menu is often the first place users tend to look to understand what is included on the app.

Part 1: The Design

The Unit Conversion Calculator is a measurement converter, as illustrated in Figure 4-8. The user can use the conversion calculator to convert from one measure to another. To select the unit of measurement, the user chooses an option available from the overflow menu, as shown in Figure 4-9.

The application is designed to allow the user to input a unit value into a text field. The conversion to the target unit will automatically execute. Because the main purpose of the app is to explore the overflow menu, the number of conversions available is kept to a minimum. Conversions include feet to meters, inches to centimeters, and pounds to grams. The user is also provided an action item for quitting the app. The Quit action item is placed last on the overflow menu.

image

images  FIGURE 4-8 Unit Conversion Calculator.

As an added design feature, the user can show and hide the action bar by performing a single tap on unoccupied territory on the screen. This flexibility can be helpful when the user determines more screen space is needed.

It should be mentioned that long or poorly organized menus are difficult for users to scan. Long menus, in particular, can be overwhelming and confusing to the user. When given a large set of action items, it is better to reorganize them into other menus.

image

images  FIGURE 4-9 The Overflow menu contains Action Items.

Part 2: Application Structure and Setup

The settings for the Unit Conversion Calculator app are as follows:

•  Application Name:

Unit Conversion Calculator

•  Project Name:

UnitConversionCalculator

•  Package Name:

com.cornez.unitconversioncalculator

•  Android Form:

Phone and Tablet

•  Minimum SDK:

API 18: Android 4.3 (Jelly Bean)

•  Target SDK:

API 21: Android 5.0 (Lollipop)

•  Compile with:

API 21: Android 5.0 (Lollipop)

•  Activity Name:

MyActivity

•  Layout Name:

activity_my

•  Menu name:

my

The launcher is set to the Android default ic_launcher.png file. No additional drawable files are needed for this app. The final project structure is shown in Figure 4-10. The source file conversion.java is the only new file added to the project.

image

images  FIGURE 4-10 Project structure for the Unit Conversion Calculator app.

The application requires a single Activity class, MyActivity.java. Fragments are not used in this app. Changes are made to the auto-generated files MyActivity. java, activity_my.xml, my.xml, strings.xml, and AndroidManifest.xml.

The orientation of the screen for the application will be locked into portrait mode, which will be set within the activity. The complete attribute settings for the Android-Manifest are shown in the XML code listing as follows:

image

Part 3: Strings Value Resources

strings.xml is the only value resource, aside from the menu resource, required by the application. The new string elements are divided into two categories. The first category defines strings used by the application’s layout file. The second category of strings represents the action bar overflow menu strings.

The complete strings.xml code is listed as follows:

image

image

Part 4: The Action Bar and Menu Design

The action bar is configured to feature a limited number of elements: application icon, title, and the overflow menu. Action buttons are not used in this application. The overflow menu holds all the action elements (i.e., controls) for the application.

The code listing for the XML file, menu/my.xml, is shown below:

Line 3:

The context for the menu is an Activity. The activity for this application is implemented as MyActivity.class.

Lines 5–34:

Four action elements are defined as individual items using the <item> tag.

Line 9:

Each action item requires a resource ID.

Line 10:

To force an action item onto the overflow menu, the value is never applied to the showAsAction attribute.

Line 11:

The action title, as it appears on the overflow menu, is set using the appropriate strings.xml definition.

image

image

Part 5: The Layout User Interface

A single layout, activity_my.xml, is used to support the entire user interface for the Unit Conversion Calculator application. This layout is bound to the activity MyActivity.java. Control elements for this layout are simple and arranged in a linear manner; however, the spacing between the elements requires a relative arrangement. As shown in the graphic layout design in Figure 4-11, the root element for the layout is a RelativeLayout, with an EditText providing the numeric input.

The XML code listing for activity_my.xml is shown below:

Lines 23–35:

The EditText input control is defined. It is given the identifier name editText1, which will be referenced in the MyActivity.

Line 31:

The alignment of the user’s input into the text field will be centered along a horizontal axis.

Line 32:

A zero value hint text is displayed when the input text field is empty.

Line 33:

The type of data entered into the text field is restricted to a numeric value.

Lines 50–57:

The output text field, used to display the converted measurement, is given the identifier name textView3, which will be referenced in MyActivity.

image

images  FIGURE 4-11 The layout design for activity_my.xml.

image

image

Part 6: The Source Code

The two source files used by the application are MyActivity, which provides the controller mechanism, and the Conversion class, which is used to implement the data required by the conversions.

The Conversion class defines the data for a measurement object to be converted. This class also implements the logic for the computation of the conversion. The data members of the class are used to describe the units of the conversion, the value to be converted, and result of the conversion. The code listing for Conversion is as follows:

image

image

MyActivity will launch once the application has been activated. AndroidManifest specifies this activity as the main activity of the application. The Java code listing for MyActivity.java is shown below:

Lines 18–21:

All layout control elements need to be referenced because they are dynamic and will change, depending on the type of measurement conversion the user wants to apply to the input. The variables objects on Lines 18–21 include the unit measurement labels and the input and output measurement values.

Line 31:

A Conversion object is instantiated. The initial conversion type is set to “Feet to Meters” in the Conversion constructor.

Line 32:

The call to the method setUpReferenceDisplay() assigns references to the layout control elements. setUpReferenceDisplay appears on Lines 36–49.

Line 48:

addTextChangeListener() is applied to the input EditText control on the layout. This is a TextWatcher that is triggered when the user inputs a new number or edits the existing number.

Lines 51–71:

inputTextWatcher() is implemented as a TextWatcher. A try/catch is used to ensure the input is a valid number.

image

image

Lines 72–78:

The onTouchEvent() is called when the user taps a single finger on a blank area of the screen. If the finger motion is registered as a simple “finger down” action, as opposed to gestures such as a swipe/fling, the event signals to the application that the user wants to hide or redisplay the action bar.

Lines 80–91:

The method toggleActionBar() is used to hide or show the action bar. Its current state is found using isShowing(). The visibility of the action bar is toggled accordingly.

Lines 95–99:

The menu hierarchy, specified by menu/my.xml, is inflated. The settings within my.xml will restrict the items to the overflow menu.

Lines 101–130:

onOptionsItemSelected () is called when an action item located on the menu has been selected. This method identifies the item by its resource id. resetDisplay () processes the action and resets the display to the units of measurement specified by the menu item.

Lines 132–137:

resetDisplay() resets the screen with new labels of conversion.

image

image

  4.5 Responsive Design with Fragments

Responsive design techniques have been applied to web design to build websites that are able to work across different screen sizes. Responsive design techniques should also be applied to Android appplications for solving interactive design and layout problems within a responsive framework, such as the optimal arrangement of data elements in a fragmented environment.

In some ways, responsive design is similar to adaptive design, which was introduced in Chapter 2. At times, these two design techniques can overlap; however, responsive design and adaptive design have significant differences. To simplify, responsive design is used for heavy data-driven content. It uses screen grouping techniques and complex navigation to present data content in a more intuitive and device-sensitive way. Adaptive design is primarily used for the rearrangement of fixed user interface elements in an application. For example, adaptive design methods would not be ideal for solving problems related to the arrangement of data control elements for a database-driven application.

On an Android mobile device, responsive design revolves around a master/detail flow interface design pattern. In this design pattern, the user is provided with a list of items, which is referred to as the master list. Upon selecting one of the items, additional information relating to that item is then presented to the user within an area of the screen called a details panel. For example, consider an email application. One panel of the screen, the master list panel, displays a list of the inbox messages consisting of the address of the sender and the subject of the message. Upon selecting one of the email items from the list, the body of the email message appears in another panel of the screen, the detail panel.

image

images  FIGURE 4-12 Fragments can be combined or separated on a device.

This design concept is responsive in the sense that list and detail panels of the app can change based on the width of the device. On a large tablet-sized Android device, the screen is large enough to display both panels. The master list can appear as a narrow vertical panel along the left-hand edge of the screen, while the remainder of the screen can display the detail panel. This arrangement is referred to as a two-pane mode.

Small Android devices do not have a screen size large enough to combine lists and details together effectively on a screen. A solution for smaller Android devices is to display the master list within its own individual screen. The detail panel will also be displayed on a separate screen, which will appear when a selection is made from the master list. The detail screen must feature an action icon that allows the user to return to the master list.

In Android, responsive design makes use of Fragments. A user interface can be divided into multiple panes using Fragments and reused in more than one screen of an application, as shown in Figure 4-12. Fragments can be combined or separated on a device. Although a single screen is implemented as an Activity subclass, the individual content panes are implemented as Fragment subclasses.

When building an application that follows a similar master/detail design pattern, the application often needs a set of Java and XML layout resource files. As an example, consider a general application with a list of items and the details for a selected item to be displayed when the user selects the item from the list. Figure 4-13 shows the layout structure for such an application.

image

images  FIGURE 4-13 A layout design using fragments.

activity_item_twopane.xml is the layout that contains both the list of items and a container to display details. The container is used to hold a fragment. This layout is used when the application is running on a device large enough to support the two-pane mode.

The XML resource file named activity_item_list.xml is populated with the list of items, and is always used on devices that are too small to support the two-pane mode.

The activity_item_detail.xml layout resource file occupies its own screen, which means it is associated with another activity. This layout is inflated from the activity ItemActivityDetail.java, and it is used on small screens. The layout uses a container to place a fragment. The fragment_item_detail.xml is the user interface for the detail pane.

Two separate activities are required to represent the item list activity (ItemListActivity.java) and the item detail activity (Item_Detail Activity.java).

ItemListActivity.java has a different presentation depending on the size of the device. On a large device, the activity presents the list of items and the item details side-by-side using two panes. The activity can do this by using a fragment. The ItemListFragment class can represent the list of items, and the Item DetailFragment class can represent the item details (if present). These classes must be created. On a small device, the activity can solely present the list of items. A selected item leads to an ItemDetailActivity representing item details.

Item_DetailActivity.java is a necessary activity that serves as a “shell” that is used to present an item detail fragment; it appears only when a small device is being used.

This sample application uses two Fragment source files: an item list fragment (ItemListFragment.java) and an item detail fragment (ItemDetailFragment.java).

ItemListFragment.java will be the list fragment class that represents a list of Items. ItemDetailFragment.java will be the fragment class representing a single-item detail on the screen.

If the display is large enough to support the two-pane mode, an instance of the item_list fragment from the activity_item_twopane.xml layout is created and displayed. If the display cannot accommodate both panes, the instance contained in the activity_item_list.xml file is used.

  Lab Example 4-3: Shades App: A Fragment Experiment

This lab example explores using responsive design, with the use of Fragments, to create a responsive user interface that can be adapted from a two-pane to a single-pane configuration, based on a change in screen orientation.

Part 1: The Design

When launched, the Shades application provides the user with a fixed list of color shades: plum, blue, and gold. When a shade is selected, information about that shade is displayed. The user interface is designed to respond to changes in screen orientation. When the user is viewing the application in landscape mode, a two-pane configuration is used, displaying the list of shades in a left-hand pane and information about an individual shade in a right-hand pane. As the user rotates the device into portrait orientation, a single-pane configuration is used. One activity is used to display the list of shades. Once a shade is selected, a new activity appears on the screen with information about the shade. The two-pane and one-pane configurations for the Shades application are shown in Figure 4-14.

Fragments used with this master-detail pattern design provide the responsive framework for the application. In the default landscape mode, the main Activity contains two Fragments: a list Fragment and an information Fragment. When in portrait mode, the Activity contains only the list Fragment.

Selecting a shade from the master list either updates the information Fragment or launches a new activity, the information Fragment Activity.

image

images  FIGURE 4-14 One-and two-pane configurations.

Part 2: Application Structure and Setup

The settings for the application are as follows:

•  Application Name:

Shades

•  Project Name:

Shades

•  Package Name:

com.cornez.shades

•  Android Form:

Phone and Tablet

•  Minimum SDK:

API 18: Android 4.3 (Jelly Bean)

•  Target SDK:

API 21: Android 5.0 (Lollipop)

•  Compile with:

API 21: Android 5.0 (Lollipop)

•  Activity Name:

MyActivity

•  Layout Name:

activity_my

The launch icon for the application is a PNG file added to the drawable folder. This bitmap file, also named ic_launcher.png, is provided in the textbook resource material. The application’s final project structure is shown in Figure 4-1. The Java source files include two Activity classes and two Fragment classes. MyActivity is the main activity of the project. MyActivity uses activity_my.xml as its associated layout file.

InformationActivity.java is the Activity class that will be activated when the user is in portrait mode and has selected a shade. If the user remains in landscape mode during the entire application, InformationActivity will never launch.

As shown in the res/layout directory in Figure 4-15, the Shades app relies on three XML layout files: an activity layout and two fragment layouts. The activity layout, activity_my.xml, is the screen interface for the main activity of the application. Two versions of activity_my.xml are shown. The first version, designed for a landscape orientation, is located in the default res/layout folder and uses a two-pane layout. The second version of activity_my.xml, designed for a portrait screen orientation, is located in res/layout-port and uses a one-pane layout.

The two XML fragment layout files are list_fragment_xml and infor mation_fragment.xml. Both files are used to structure the fragments of data, representing the shade list and the individual information, which will be inserted into the pane containers.

AndroidManifest.xml must declare both activities used by the Shades application, as shown below:

Lines 11–21:

MyActivity.class is specified as the main activity to be launched when the application is launched for the first time.

Line 24–31:

The secondary activity, InformationActivity.class, is set as the child activity of MyActivity.

image

images  FIGURE 4-15 The final project structure for the Shades application.

image

image

Part 3: External Value Resources

Color has been added to the Shades application to provide a visual demarcation for the two-pane configurations; this is primarily a visual cue. The pane used for the master list uses a caramel background color. The pane used for the information data uses a light-tan background color. The color definitions are placed in a newly added XML file colors.xml, which is located in res/values.

image

The master list elements and the information about individual shades of color will be stored in strings.xml file. It should be noted that Shades is a simple application used to simplify and demonstrate how fragments can be used with a master/detail design pattern. Outside an example such as this, it is not practical to employ strings.xml as a data repository. More practical solutions will be explored later in the chapter, as well as in subsequent chapters.

The XML code listing for strings.xml is as follows:

image

Part 4: Individual Fragment Layouts

As a component of an application’s user interface, Fragments are designed with corresponding layouts. In this application, the master list fragment layout is defined by list_fragment.xml. The master list for this demonstration app is limited to three shades of color. Each shade is placed, as a button control, directly on the list_fragment.xml layout file, as shown in its visual representation in Figure 4-16. The layout’s root container is set to a LinearLayout.

The code listing for list_fragment.xml appears below:

Line 5:

The background color, for this master list, is set to caramel.

Lines 11–12:

The width of each button will be uniform. The value fill_parent, assigned to the attribute layout_width, will stretch the width of the button to fill the layout.

Line 13:

The Activity uses the contentDescription attribute to update the information pane when the user selects a color shade.

image

images  FIGURE 4-16 list_fragment.xml.

image

image

The detail, or information, fragment layout is defined by the XML file information_fragment.xml. Information about a selected shade is a text element. This text element is placed in a TextView, as shown in the visual representation of the layout in Figure 4-17.

The XML code listing for information is shown below:

Line 2:

A RelativeLayout ViewGroup is used as the root element of the layout file. This allows the text element to be placed freely on the screen.

Lines 12–13:

The text element is set to appear in the center of the pane.

image

images  FIGURE 4-17 The layout, information_fragment.xml, used to hold color information.

image

Part 5: The Main User Interface to Hold the Fragments

activity_my.xml provides two possible configurations. The Android operating system will choose the appropriate resources based on the current device characteristics. For this application experiment, the two layout configurations are placed in separate folders: res/layout and res/layout-port. The same name, activity_my.xml, is used in both locations.

It should be noted that using multiple layout folders works well for a simple application such as this one. For an application that is more complex, relying on a variety of folders to store versions of the same layout can be hard to maintain. For advanced applications, references can be used to refer to a specific item in Android from a particular resource folder. In addition, you can quickly calculate the suitability of a screen size, and you can apply pane configurations accordingly.

To keep the layout simple, the root element of the default main activity in a landscape orientation is a LinearLayout, as shown in Figure 4-18.

The XML code for activity_my.xml is listed below:

Line 4:

The orientation attribute of the LinearLayout is set to horizontal, which allows the Fragment elements to be placed side by side.

Lines 9–16:

The master list fragment is defined. The class associated with this Fragment is ListFragment.class.

Lines 18–26:

The information fragment is defined. The class associated with this Fragment is InformationFragment.

image

images  FIGURE 4-18 activity_my.xml uses a LinearLayout root element.

image

image

A second version of activity_my.xml will be created and placed in a new resource folder named layout-port. The Android system will select this second version of the layout when the current device is in a portrait orientation. The visual design for this version of the main activity layout is shown in Figure 4-19. It contains a LinearLayout with a single element, a Fragment container, and it is given the identifier name fragment1.

image

images  FIGURE 4-19 The main layout designed for portrait orientation. Fragment1 is shown holding the color list.

This portrait version of activity_my.xml is used to define the single pane information Activity. This layout is a placeholder for the ListFragment class. The XML code for this file appears as follows:

image

Part 6: Coding the Application

Two Activities are used by this application: MyActivity and Information Activity. MyActivity is the main activity of the application and will always remain running while the application is in landscape mode. This activity displays fragments side by side with the master list on the left and the information detail on the right. When the system determines a single pane configuration, MyActivity is responsible for launching a second activity, InformationActivity, to display the information detail when required. The Java code for MyActivity.java is listed below:

Lines 18–26:

The information fragment is defined. The class associated with this Fragment is InformationFragment.

Lines 19–42:

The onShadeItemSelected() method is from the interface OnItemSelectedListener. This interface is declared in the ListFragment class and is discussed further in this lab example. The method onShadeItemSelected() is a handler for a listener event that is triggered when the user selects a shade from the master list.

Lines 23–30:

findFragmentById() is used to find a fragment identified by the given identifier. The InformationFragment is assigned, if it exists. If the fragment is present in the current configuration, the information about the selected shade is placed into the text element of this fragment.

Lines 33–41:

If a single-pane configuration is on display in the window, an Intent is created to start another Activity, the InformationActivity, to display shade information. The information about the shade is added onto the Intent and passed before the Activity is started. The argument link is the specific information about the shade choice selected.

image

image

The ListFragment is the Fragment class that provides the structure for the master list containing clickable buttons. ListFragment serves as a component to the MyActivity class.

The code listing for ListFragment.java appears as follows:

Line 12:

A listener object, used for signaling and identifying which shade on the master list has been selected, is declared.

Line 13:

When a shade from the master list is selected, the string information holds the detail information to be displayed.

Lines 21–24:

ListFragment inflates its user interface view, list_fragment.xml, in the container set aside by activity_my.xml.

Lines 26–33:

Each shade item on the master list is referenced by a button view. OnClicklistener events are registered to the buttons. The handler for this click event is ShadeChangeListener.

Lines 38–45:

The onClick event handler ShadeChangeListener is implemented. view.getContentDescription() collects the View description stored in the XML definition for the button.

Lines 47–49:

The public interface can support the passing of information to the controlling activity of a fragment. Often, communication between the fragment and its activity is managed through a public interface defined in the fragment. The public interface ListFragment.OnItemSelectedListener communicates which list item was selected.

Lines 52–61:

onAttach() is called when a ListFragment is first attached to MyActivity.

Lines 62–64:

updateDetail() communicates the shade information to MyActivity.

image

image

image

The InformationFragment class requires information about the selected shade item, which is then loaded into a TextView located on the associated layout. The Java code is listed below:

Lines 12–22:

onCreateView () is called to instantiate the fragment’s user interface view.

Lines 17–18:

The layout associated with the fragment, information_fragment.xml, is inflated and loaded into the container on activity_my.xml.

Line 19:

The view, specfically R.layout.information_fragment, is returned.

Lines 23–27:

The public method setText() sets the TextView, located on the layout information_fragment.xml, to the shade information.

image

image

Part 7: Defining the Single-Pane Detail Activity

InformationActivity.java is the single-pane Activity that shows the detail information about a specific shade.

Lines 15–21:

If the orientation of the screen has returned to landscape mode, this single-pane Activity is no longer needed because the two-pane model does not fit comfortably on the screen. getConfiguration () returns the current configuration, which can be matched with the constant Configuration. ORIENTATION_LANDSCAPE. finish () and return finish the Activity and return to the starting Activity.

Line 27:

setDisplayHomeAsUpEnabled() enables the “up” control element located on the action bar.

Line 29:

The Intent that started this activity is returned by the call getIntent(). The extended data (the passed shade information) is retrieved from this intent.

Lines 34–35:

A reference is made to the TextView located on the Fragment layout information_fragment.xml. The string value of the TextView is set to the information about the shade that was selected from the master list.

image

image

  4.6 Animation in Fragment Transactions

Transition animations can be applied directly to fragments that are entering and exiting a transaction.

To manage fragments, the FragmentManager provides the structure that handles transactions between fragments. A transaction refers to the sequence of steps that add, replace, or remove fragments.

Operations performed by the FragmentManager occur inside a transaction. For example, the following code segment illustrates a Fragment transaction:

Line 1:

getFragmentManager() returns the FragmentManager for interacting with fragments associated with current activity.

Lines 3–4:

FragmentTransaction is the API for performing a set of Fragment –operations. A FragmentTransaction object is instantiated. beginTransaction initiates edit operations on the Fragments associated with this FragmentManager.

Lines 6–9:

A series of edit operations is performed on the fragment associated with the FragmentTransaction object instantiated on Lines 3–4.

Common edit operations that can occur in a transaction are:

a.  add()/remove(): to add and remove a Fragment from the FragmentManager.

b.  attach()/detach(): to attach/detach a Fragment from the Activity (e.g., make it an active Fragment that can be seen by the user).

c.  show()/hide(): to show or hide a Fragment by calling View.setVisibility() on the Fragment’s root View.

Line 10:

commit() is called to mark the end of the transaction.

image

Fragment transactions support transition animations. Two versions of the setCustomAnimations() method, from the FragmentTransaction class, are used to set the animation resources to be applied to fragments that are entering and exiting a given transaction.

The method setCustomAnimations(int enter, int exit) is used to play an animation for enter and exit operations. These animations, however, will not be played when popping the back stack.

popEnter and popExit animations can be played for enter and exit operations specifically when popping the back stack. The setCustom Animations (int enter, int exit, int popEnter, int popExit) method is used for this purpose.

  Lab Example 4-4: Recipes–Fragments with Transition Animations

The objective of this lab example is to work with fragments in an application and to apply transition animations. This lab will explore the FragmentTransaction class, basic animation effects, and the Android interpolator.

Part 1: The App Design

The Recipes App was constructed for the purpose of demonstrating fragment transition animations; hence, it is very simple. The behavior of this application is similar to a flip card, with a swiveling rotation animation. The application is displayed in Figure 4-20. Upon first launching Recipe App, the user is presented with a photograph of a cooked dish. In the lower left corner is a button for flipping the photograph over to view the recipe directions. The photograph and the recipe directions are both Fragments that enter and exit within a transaction.

image

images  FIGURE 4-20 The Recipes app.

Part 2: Application Structure and Setup

The settings for the application are as follows:

•  Application Name:

Recipes

•  Project Name:

Recipes

•  Android Form:

Phone and Tablet

•  Minimum SDK:

API 18: Android 4.3 (Jelly Bean)

•  Target SDK:

API 21: Android 5.0 (Lollipop)

• Compile with:

API 21: Android 5.0 (Lollipop)

•  Activity Name:

MyActivity

•  Layout Name:

activity_my

The application icon launcher is set to the Android default ic_launcher.png file, and a photograph of a cooked dish has been added to the drawable folder. The final application structure is shown in Figure 4-21. Two Java Fragment classes–one for the recipe photos and another for the recipe directions–,and a main Activity are the source files required by the application. The Activity and the Fragments each have an associated XML layout file.

An animation folder, res/anim, has been added to store the enter/exit animation definitions for “rotating” Fragments in and out of a transaction.

image

images  FIGURE 4-21 Project structure for the Recipes application.

The AndroidManifest file for Recipes specifies a landscape orientation for the main activity and sets the main activity to the Java class MyActivity. The XML code for this file is listed as follows:

image

Part 3: Value Resources

strings.xml is the only required value resource file used by the Recipes app. As a demonstration application, this project stores its recipe data in the strings.xml file. To evolve this app into a more practical application, a database would be the optimal choice for the data source. The XML code for strings.xml is listed as follows:

image

image

Part 4: Designing Individual Fragments

The two Fragments for this application represent the front and back of a recipe flip card. The front of the card displays the photo of the cooked dish, and the back contains the directions of the recipe.

The layout for the photo fragment, fragment_recipe_photo, consists of an ImageView placed inside the root element, a FrameLayout. The visual layout structure is shown in Figure 4-22.

image

images  FIGURE 4-22 The visual layout design for fragment_recipe_photo.

The XML code for fragment_recipe_photo.xml is listed as follows:

Line 11:

The value centerCrop scales an image uniformly, which maintains the image’s aspect ratio. This means the width and height of the image will be equal to or larger than the corresponding dimension of the view, minus padding.

image

image

The visual design structure for fragment_recipe_directions.xml is shown in Figure 4-23.

image

images  FIGURE 4-23 The layout, fragment_recipe.xml, used to hold color information.

The XML code for fragment_recipe_directions.xml is listed as follows:

image

image

Part 4: User Interface and Fragment Design

The application’s user interface is designed to hold fragments. The main layout of the application, activity_my.xml, corresponds to the application’s activity. The visual structure for this layout is shown in Figure 4-24. The layout consists of a FrameLayout placed inside the root element, a RelativeLayout. The FrameLayout serves as a Fragment container, which allows a set of fragments to be moved in and out of the user’s view on the screen. A Button control element is placed below the Fragment container and will be used to flip the recipe over.

image

images  FIGURE 4-24 The visual design for activity_my.xml.

The XML code for activity_my.xml is listed as follows:

image

Part 5: The Transition Animations

Fragments are transitioned into the container located on activity_my.xml with the help of the Android interpolator. An interpolator defines the rate of change of an animation. This allows the basic animation effects–such as alpha, scale, translate, and rotate–to be accelerated, decelerated, repeated, and so on.

Two XML files define the animation effects used to “flip” from the recipe photo to the recipe directions. Both animation XML files are placed in the anim folder, which was added to the project structure. rotate_in.xml characterizes how a fragment will enter the screen, and rotate_out.xml characterizes how a fragment will exit the screen.

image

images  FIGURE 4-25 Animation effect rotationX rotates around the x-axis.

The XML code for rotate_in.xml is listed as follows:

Line 5:

The <objectAnimator> tag defines attributes of the target object that will be animated.

Line 6:

The animation effect rotationX performs a rotation around the x-axis, as shown in Figure 4-25.

Lines 8–9:

Values are set to define a rotation around the x-axis from 180 to 0 degrees.

Lines 11–13:

The interpolator moves the element after 1,500 milliseconds has passed.

image

image

The XML code for rotate_in.xml and rotate_out.xml are listed as follows:

Lines 3–4:

A <set> can define its own ordering attribute. The value “together” will play animations as defined in the set at the same time. By applying the value sequentially to the order attribute, the set of animations would be played sequentially.

Lines 7–13:

The first animation set element is defined. ObjectAnimator is used to specify a rotation from −180 to 0 degrees.

Lines 16–23:

A second animation set element is defined to gradually fade the exiting Fragment so that it is no longer visible once the rotation ends. The interpolator alters the element after 500 milliseconds has passed.

image

image

Part 6: Coding the Application

The primary activity of the application is MyActivity. This is the starting point for loading either one of the Fragments.

The Java code for MyActivity.java is listed as follows:

Lines 37–61:

flipOver() is the onClick event handler that is called when the user taps the “flip over” button located on the bottom of the screen.

Line 38:

getFragmentManager() returns the FragmentManager for interacting with fragments associated with the current activity. A transaction associated with the FragmentManager is initiated.

Lines 40–48:

Specific animation resources are set to run for the fragments that are entering and exiting in this transaction. In the second setCustomAnimations(), the rotate_in and rotate_out animations will be played for enter/exit operations specifically when popping the back stack.

Lines 54–55:

The replace() edit operations are specified for this transaction. For example, if the recipe photo is visible, recipe directions will replace it.

Line 58:

commit() is called to mark the end of the transaction.

image

image

image

The Recipes app has two fragments, each represented by an independent Fragment class. Both Fragment classes include a callback to onCreateView() to inflate its user interface view. The code listings for FragmentRecipePhoto.java and FragmentrecipeDirections.java appear as follows:

image

image

image

  4.7 ListViews and Adapters

A ListView is similar to a ScrollView, which was introduced in Chapter 2. The ScrollView is an extension of the FrameLayout, and it is suitable for holding a single control element. As a scrollable control, it provides the user with the scroll mechanism to reveal more content than can be displayed on the screen at once. Scroll-Views are most often implemented with a LinearLayout. For example, a LinearLayout, containing multiple View items, can be placed within a ScrollView. The items are made scrollable if the screen is not large enough to display them all. Placing many View items into a LinearLayout is not always practical. When dealing with a dynamic list of many Views, the ScrollView is not efficient.

A ListView is a specialized control that is optimized for displaying long lists of items. It is specifically designed to be efficient when creating, recycling, and displaying scrollable Views. The list items are inserted into the list using an Adapter that collects the data content from a source, such as an array or database query, and converts each item result into a view that is placed into the list.

When the data content for the layout is dynamic or not predetermined, it is possible to use a layout that subclasses an AdapterView to populate the layout with views at runtime. A subclass of the AdapterView class uses an Adapter to bind data to its associated layout. In this way, the Adapter serves as the controller between the data source and the AdapterView layout. The Adapter retrieves the data, then turns it into a layout View, and then adds to the AdapterView layout.

An AdapterView can be populated with data in two ways. An AdapterView, such as a ListView, can be filled with data by binding the AdapterView instance to an Adapter, which retrieves data from an external source and creates a View that represents each data entry.

Android provides several subclasses of Adapter that are useful for retrieving different kinds of data and building views for an AdapterView. A common adapter is an ArrayAdapter. An ArrayAdapter is used when the data source is an array. By default, ArrayAdapter creates a view for each array item by calling toString() on each item and placing the contents in a TextView. For example, consider an array of strings that will be used to populate a ListView.

Lines 1–3:

An ArrayAdapter can be initialized, using a constructor, to specify the layout for each string and the string array.

The arguments for this constructor are:

a.  The app Context

b.  The layout that contains the TextView for each string in the array

c.  The string array

Lines 7–8:

The setAdapter() is called to set the data behind the ListView.

To customize the appearance of items placed into a ListView, the toString() method can be overridden. To create a list item other than a TextView, such as an ImageView, the ArrayAdapter class can be extended and the getView() can be overridden to return the appropriate item type.

image

  Lab Example 4-5:  Redlands Music Events App–Adapters and ListViews

This lab explores the use of an Adapter and a ListView in a single Fragment context. A Fragment containing a ListView is arranged on the screen and filled with data from a Java data file. This is a first look at using an Adapter and a ListView; hence, the application will be kept very simple. A snapshot of the application is shown in Figure 4-26.

Part 1: Application Design

Every year, the City of Redlands puts on a music festival during the summer months. The scheduled events and the dates change from year to year, but the structure of the application itself remains much the same. An internal Java data file provides the data, containing a list of scheduled events and dates.

image

images  FIGURE 4-26 A Fragment containing a ListView.

Part 2: Application Structure and Setup

The settings for the application are as follows:

•  Application Name:

Redlands Music Events

•  Project Name:

RedlandsMusicEvents

•  Package Name:

com.cornez.redlandsmusicevents

•  Android Form:

Phone and Tablet

•  Minimum SDK:

API 18: Android 4.3 (Jelly Bean)

•  Target SDK:

API 21: Android 5.0 (Lollipop)

•  Compile with:

API 21: Android 5.0 (Lollipop)

•  Activity Name:

MyActivity

•  Layout Name:

activity_my

The icon used to launch the application is the Android default icon stored in the ic_launcher.png file. To enhance the application’s visual appeal, a background graphic, a Redlands music logo, and a unique graphic divider for separating the music event items have been added to the drawable default folder. The final application structure is shown in Figure 4-27.

The two Java classes represent the data source, MusicEvents.java, and the activity of the application, MyActivity.java. A Fragment class is not required for this simple application because the Fragment will be added to the main user interface and will not be removed at any time. The main activity and its fragment will each have an associated XML layout file, activity_my.xml and fragment_my.xml. A third layout file, list_item_event.xml, will provide the visual structure for items added to the music event list.

image

images  FIGURE 4-27 Project structure for the Redlands Music Events application.

The AndroidManifest file sets the main activity of the application to MyActivity. The action attribute of the intent-filter ensures that this activity will launch when the application launches for the first time. The orientation of the activity is restricted to landscape mode. The XML code for AndroidManifest.xml is listed as follows:

image

Part 3: External Value Resources

The strings.xml file will be edited to add the Redlands Music Events dates, the start and end data of the festival.

A colors.xml file will be used to declare a “tan” color that will be used as a backdrop by the ListView. The code listing for strings.xml and colors.xml are as follows:

image

image

Part 4: The Event List Item

The event list item is an individual music event that will be added to the list of music events that make up the Redlands Music Festival. At its most basic, a music event item can be represented as a text element. The list_item_event.xml declares a TextView as its root element and sets the identifier to @+id/list_item_event_textView. The ArrayAdapter in the main activity references this identifier as it populates the ListView.

The XML code listing for list_item_event.xml appears as follows:

image

Part 5: The Activity XML File

The layout file that corresponds to the main activity of the application is represented by activity_my.xml. It uses a FrameLayout as the root element. No control elements have been added to this user interface.

image

Part 6: The Fragment Layout File

The activitiy’s fragment XML file holds all user interface elements used by the activity. The visual structure for fragment_my.xml is shown in Figure 4-28. The XML code for this fragment is listed as follows:

Line 11:

The background graphic, from the drawables folder, is applied to the background for the fragment.

Lines 13–23:

The Redlands Music logo is placed at the top of the screen.

Lines 25–35:

The dates for the music festival are placed in the Textview.

Lines 37–49:

The ListView that will hold all the music event items is defined. Its identifier is set for future referencing by the main activity. Visual attributes are set for color (tan) and alpha. Alpha will set the visibility of the View. The divider attribute is set to the bitmap file divider.png, stored in the drawable folder.

image

image

image

images  FIGURE 4-28 The layout design for the Music Festival application.

Part 7: Coding the Application

The purpose of MusicEvents.java is to provide a data source for the application. The data[] array contains a fixed set of music events. Each event includes the data of the event and the name. The code listing for MusicEvents.java is as follows:

image

MyActivity.java, the main activity of the application, displays the fragment. Recall that a fragment requires an activity. The fragment XML file for this application holds all user interface elements used by the activity. The visual structure for fragment_my.xml is shown in Figure 4-1. The XML code for this fragment is listed as follows:

Line 25:

The activity user interface content is set to the layout file activity_my.xml.

Lines 27–31:

When the activity is launched for the first time, a fragment transaction is processed to add MusicEventFragment to the activity layout container.

Lines 37–69:

The MusicEventFragment class is implemented. All music event data are collected and processed within onCreateView(). onCreateView() will be called once, when the fragment instantiates its user interface view.

Lines 48–50:

The music event data are collected and first stored in eventData. This data will be assigned to seasonEvents, a Java List, as a collection of String items.

Lines 52–57:

Now that we have some music event data, an ArrayAdapter is created. The ArrayAdapter will take the music data and use it to populate the ListView to which it is attached.

Line 54:

The context of the activity is supplied to the ArrayAdapter.

Line 55:

The name of the layout ID is R.layout.list_item_event.

Line 56:

R.id.list_item_event_textView is the ID of the textView to populate.

Lines 63–65:

The reference to the ListView is accessed and the adapter is attached to it.

image

image

image

  4.8 Handling Click Events in a ListView

Often, a ListView is populated with items that need to respond to a click event. You can respond to click events on an item in an AdapterView by implementing the AdapterView.OnItemClickListener interface. The onItemClick () callback method will always be invoked when an item in the AdapterView has been clicked.

As shown in the following code segment, this onItemClick() callback uses four parameters:

1.  parent: the AdapterView where the user has clicked.

2.  view: the view within the AdapterView that was clicked. This is the view provided by the adapter.

3.  position: the index position of the view in the adapter. To access the data associated with the selected item, the getItemAtPosition(position) method can be called.

4.  id: the row id of the item that was clicked.

image

  Lab Example 4-6: Shades (Part 2): Clickable Shades of Color in the ListView

In Lab Example 4-3, a master list fragment was populated with buttons representing various shades of color. When the user clicked one of the buttons, detailed information about a specific shade of color appeared in a separate pane on the screen. This application was meant to be a simple introduction to fragments, but it is considered impractical because the buttons were placed individually within the layout design. With only three buttons, this example served as a good demonstration for a first look at the concepts of Fragments. In most cases, however, a more feasible approach to constructing a master list of items would be the utilization of a ListView. As a container, a ListView can be populated with a large and dynamic collection of clickable items. In addition, this master list can be built with items obtained from a dynamic source, such as an online database.

In this lab, we enhance the first version of the Shades application by employing a ListView for the display of items and an Adapter for populating the master list with items from a dummy source. Figure 4-29 shows Shades II, the new version of Shades. The master list of items will be more extensive and each item will be clickable. The fragment behavior of the application will remain the same.

Part 1: Application Structure and Setup

The final project structure for the Shades II application is shown in Figure 4-30. Two additional files from the original Shades have been added. A data source file, DummyData, will provide all the data elements. The second file added to the structure is list-item-shade.xml. This layout represents an individual list item to be added to the ListView.

It should be noted that the data file has been given the name DummyData because it is not an optimal design for a data source. Even though it is considerably more efficient than using a layout containing physical buttons, a better option is accessing data from a database file in the cloud. This topic will be discussed in Chapter 9.

Part 2: Defining the Layout Structure for
an Individual Item to Be Added to the List

The human eye can distinguish nearly 2 million color shades, or perhaps even more. We will not be adding close to this number of color shades to the ListView, however. The goal is to add a more robust list than the set of three colors provided in the first version of Shades.

In the Shades II application, shades of color are added dynamically by creating a View object, populating it with a color, and adding it to the Listview. The blueprint of the View object can be defined as an XML file, specifically as a mini layout. The file list_item_shade.xml is the blueprint for an individual View object that stores a shade of color.

image

images  FIGURE 4-29 Shades II application features a scrollable list of clickable items.

image

images  FIGURE 4-30 Project structure for Shades II application.

The root element of list_item_shade.xml is a TextView, which stores the text for the shade of color. The XML for this file is shown as follows:

image

Part 3: Restructure list_fragment.xml

The layout for the master list, list_fragment.xml, will be restructured. Its container is a ListView named listview_shades, as shown in Figure 4-31.

image

images  FIGURE 4-31 The visual structure for the master list, list_fragment.xml.

The XML code list for list_fragment.xml is as follows:

image

Part 4: Defining the Data Source Application

Color data is provided by items stored in the Java file DummyData.java in two arrays of data. The first array contains the names of the colors, and the second array contains detailed information about each color.

This file represents pretend data for the ListView. For applications that require real data, the application code will still be used, but the data may be retrieved elsewhere, such as the cloud. To save space, the code below is incomplete. The finished code file can be found in the accompanying resources for this text.

image

Part 5: Recoding MyListFragment

MyListFragment.java represents the master list in the master-detail flow pattern. Modifications, outlined in the Line commentary below, have been made to accommodate the ListView element in the Fragment.

Lines 28–31:

The shade dummy data is collected. The set of shade names, from the data source, is placed in the ordered list named shadeListing. The shade detail information is also placed in an ordered list, shadeNameDetail.

Lines 33–38:

An ArrayAdapter is created to take shadeListing data and use it to populate the ListView it is attached to.

Lines 45–47:

The object listView is assigned the reference to the ListView on the layout. The ArrayAdapter, mShadeAdapter is attached to the ListView, via the reference.

Lines 49–60:

An OnItemClickListener listener event is registered for each new item added to the ListView. When the user clicks on a given item, the handler onItemClick() is called. Using the i parameter provided by onItemClick(), the position of the item clicked (the index) accessed. A string of information is constructed about the shade of color selected. The method updateDetail () will be passed this information.

image

image

  EXERCISES

4.1  Describe the Fragment lifecycle.

4.2  List the set of Fragment callback methods used by a Fragment.

4.3  Explain when onInflate() and onActivityCreated() are called.

4.4  Describe the features of a typical action bar.

4.5  Every Activity supports an options menu of actions. Describe what occurs in the code segment shown below:

images

4.6  Explain the purpose of an action view.

4.7  How does adaptive design differ from responsive design?

4.8  Describe the master/detail design pattern.

4.9  How are Adapters used in a master/detail design?

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.59.187.18