2 Layout Menu Style Themes Multimedia
2 Layout Menu Style Themes Multimedia
2 Layout Menu Style Themes Multimedia
www.issacitlabs.com
www.facebook.com/issaclabs
www.linkedin.com/in/issacitlabs
UI : Android Layouts and Its Types
Android Layouts:
A Layout dictates the alignment of widgets (such as Text, Buttons,
EditText box) as we see in the Android Application. All the visual structure
we see in an android app is designed in a Layout. Every Layout is
defined in an xml file which is located in App > res > Layout in New
Android Studio.
Types of Layouts:
The layouts most commonly used are:
1. Linear Layout
2. Relative Layout
2
However there are several other layouts such as:
1. Web View Layout
2. Frame Layout
3. List View Layout
4. Grid View Layout
5. Table Layout
6. Tab Layout
Here we try to discuss these layouts in brief as these layouts are used
extensively in any Android Project.
3
Linear Layout:
4
5
Relative Layout:
Relative Layout is a layout where the widgets (such as Text Views, Buttons,
etc.) are represented with respect to previous widget or parent View. A
Relative Layout example is shown in the figure in the next slide.
Here in the next slide figure, Forgot Password button is positioned relative
to Login Button, whereas Register a new Account is aligned with
respect to Parent Layout.
6
7
List View:
A List View is a View Layout where all the items are specified in the form of
a list as shown in fig. below.
8
Grid View:
A Grid View is a View Layout where the items (such as pictures, files etc.)
are placed in a Grid manner as shown in figure below.
9
Android Screen UI Components
Up to this point, you have seen that the basic unit of an Android application
is an Activity. An Activity displays the user interface of your application,
which may contain widgets like buttons, labels, text boxes, etc. Typically,
you define your UI using an XML file (for example, the main.xml file
located in the res/layout folder), which may look like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical android:layout_width="fill_parent"
android:layout_height="fill_parent >
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="@string/hello />
</LinearLayout>
10
During runtime, you load the XML UI in the onCreate() event handler in your
Activity class, using the setContentView() method of the Activity class:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
What happens is that during compilation time, each element in the XML
file is compiled into its equivalent Android GUI class, with attributes
represented by methods. The Android system then creates the UI of the
Activity when it is loaded.
11
While it is always easier to build your UI using a XML file, there are times
where you need to build your UI dynamically during runtime (for
example, when writing games). Hence, it is also possible to create your
UI entirely using code.
12
Views and ViewGroups
13
Android supports the following ViewGroups:
LinearLayout
AbsoluteLayout
TableLayout
RelativeLayout
FrameLayout
ScrollView
14
Each View and ViewGroup has a set of common attributes, some of
which are shown in Table 1.
Attribute Description
layout_width Specifies the width of the View or ViewGroup
layout_height Specifies the height of the View or ViewGroup
layout_marginTop Specifies extra space on the top side of the View or
ViewGroup
layout_marginBottom Specifies extra space on the bottom side of
the View or ViewGroup
layout_marginLeft Specifies extra space on the left side of the View or
ViewGroup
15
layout_marginRight Specifies extra space on the right side of the View
or ViewGroup
layout_gravity Specifies how child Views are positioned layout_weight
Specifies how much of the extra space in the layout to be
allocated to the View
layout_x Specifies the x-coordinate of the View or ViewGroup
layout_y Specifies the y-coordinate of the View or ViewGroup
Note that some of these attributes are only applicable when a View is in
certain specific ViewGroup(s). For example, the layout_weight and
layout_gravity attributes are only applicable if a View is either in a
LinearLayout or TableLayout.
16
Using menus in your apps
We use menus to show additional app functions without taking up too much
screen space.
There are 3 types of menus:
Options menus these are mainly an activitys menu items. Usually these
options impact the app, an example being the Settings option
Context menus these are menus that appear in a floating window when
the user clicks on a particular element. These options affect that element
Popup menus this is also a floating window. It displays a list of items
anchored to the view that the user clicked
17
Import the support classes
The Action Bar and popup menus have only been available since Android
3.0.
Were using the support library so were able to use these on devices using
earlier versions of Android.
This session applies to apps running on Android 2.1 (API Level 7) and later.
Import android.support.v7.app.ActionBarActivity
Import android.support.v7.widget.PopupMenu;
Use the support librarys PopupMenu class to provide popup menus in apps
prior to Android 3.0 (API Level 11)
18
If used in apps running on Android 3.0 and higher, they will also use this
class and not switch to the frameworks newer class.
public class MainActivity extends ActionBarActivity
Create your activity by extending the support librarys ActionBarActivity
class to add an Action Bar to activities running on Android 2.1 (API Level
7) and higher
19
Options Menus
The items
Flag your important menu items as action items and theyll appear on the
Action Bar if theres room. The rest will appear in the overflow menu.
You can include an icon for your action items to display on the Action
Bar. The icon wont display in the overflow menu.
You can include submenus, check boxes and radio buttons in the
overflow menu but not on the Action Bar.
20
Creating the options menu dynamically in code
You can create your menus dynamically in code, like this: The
onCreateOptionsMenu is called once to create the initial menu
21
Note the following:
Always call through to the super class as it may add extra system menu
options
getMenuInflater().inflate you dont need to inflate a menu resource file.
You can create your whole menu in code without one. Were using a
menu resource file and adding an item in code. We inflate the menu
resource file, main.xml . inflate() has two parameters:
1. the resource file that we want to inflate
2. the Menu object that we want to inflate the resource into
title the text that will display in the menu
22
groupId this is the ID of a group of items that this item can belong to.
You can group menu items together so that you can make changes to
the group; for example, you could set all the items in a group to invisible.
Our item does not belong to a group so we pass the NONE constant
itemId this is the unique ID of the item. We use the constant for
Menu.FIRST which is 1. You can use Menu.FIRST + 1 for the next item
and so on
order this is the order of the item in the list. We use 103 here so that
this item follows item two (defined in the main.xml file) which has an
order of 102. You can use Menu.NONE if the order of the items is not
important
add we add item to the menu object, passing the relevant parameters
return true so that the menu can be displayed
23
You can also create the menu in xml.
Creating the options menu in xml
Its better to define the menu in xml and then inflate it in your activity or
fragment when needed.
Heres how we defined the context menu in xml. Its saved as the
my_context_menu.xml file in the res/menu folder:
Our context menu has two items. Weve only included the id and title
attributes. There are other attributes that you can include
24
25
Defining your menu in xml:
Makes it easy to visualize the structure of your menu
Separates your menu content from behavioural code
Allows you to create alternative menu structures for different screen
sizes and platforms
26
Context menus
Context menus display actions that affect the specific element to which
they are attached.
The context menu appears in a floating window which closes when an
item is selected.
27
Android SDK: Exploring Styles and Themes
Styles and themes are time-saving ways to create a consistent look and feel across your
Android application. In this tutorial, Ill cover everything you need to know to apply these
useful concepts to your own project. Starting with a quick introduction, this tutorial then
demonstrates how to work with the styles and themes that are predefined by the Android
platform. Finally, I will walk you through the process of creating your own, both from scratch
and by using inheritance.
28
Why Should I Use Themes and Styles?
Implementing styles and themes has several benefits.
Efficiency: If youre going to be using the same collection of attributes throughout your
application, defining them in advance turns this:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ff0000ff"
android:textStyle="italic"
android:typeface="serif"
android:text="@string/disclaimer" />
29
Into this:
<TextView
style="@style/disclaimerFont"
android:text="@string/disclaimer" />
Consistency: Defining a style or theme helps to ensure a consistent look
and feel.
Flexibility: When you inevitably come to tweak your UI, you only need to
touch the code in one location. This change is then automatically
replicated, potentially across your entire application. Styles and themes
give you the freedom to quickly and easily update your UI, without
touching previously-tested code.
30
Step 1: Create a Custom Style
Defining and referencing custom styles in Android is similar to using string
resources, so well dive straight in and implement a custom style.
Open the res/values/styles.xml file. This is where youll define your styles.
31
Ensure the styles.xml file has opening and closing "resource" tags:
<resources>
</resources>
Give your style a unique identifier. In this tutorial, well use "headline":
<style name="headline">
Add your attributes and their values as a list of items.
<item name="android:textStyle">bold</item>
Once youve finished adding items, remember the closing tag:
</style>
32
This is the custom style well use :
<resources>
<style name="headline">
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:typeface">monospace</item>
<item name="android:textColor">#ff0000ff</item>
<item name="android:textStyle">bold</item>
<item name="android:textSize">20dp</item>
</style>
</resources>
33
Step 2: Apply Your Style
Applying a style to a View is easy. Open your layout file, and then locate the
View and add:
<TextView
style="@style/headline"
android:text="Hello, world!" />
Tip: Note the missing android: XML prefix. This prefix is omitted because
the "headline" style isnt defined in the android namespace.
Boot up the emulator and take a look at your custom style in action.
34
Step 3: Examine the Predefined Styles
Youve seen how easy it is to define and apply a custom style, but the
Android platform features plenty of predefined styles, too. You can
access these by examining the Android source code.
Locate the Android SDK installed on your hard drive and follow the path:
platforms/android/data/res/values
Locate the styles.xml file inside this folder. This file contains the code for all
of Androids predefined styles.
35
Step 4: Apply a Default Style
Pick a style to apply. In this example, well use the following:
Return to your layout file, and add the following to your View:
<TextView
android:id="@+id/textView1"
style="@android:style/TextAppearance.StatusBar.EventContent.Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
Experiment with other default styles to see what different effects can be
achieved.
36
Step 5: Create a themes.xml File
Now that youre familiar with custom and default styles, well move onto themes.
Themes are very similar to styles, but with a few important differences.
Before we apply and define some themes, its a good idea to create a dedicated
themes.xml file in your projects "Values" folder. This is especially important if
youre going to be using both styles and themes in your project.
To create this file:
Right-click on the "Values" folder.
Select "New", followed by "Other".
In the subsequent dialog, select the "Android XML Values File" option and click
"Next".
Enter the filename "themes" and select "Finish".
37
Step 6: Apply a Default Theme
Unlike styles, themes are applied in the Android Manifest, not the layout file.
Pick a theme to work with by opening the themes file in platforms/android/data/res/values and
scrolling through the XML code. In this example, well use the following:
Open the Android Manifest file. Depending on the desired scope of your theme, either apply it
to:
A single activity:
<activity android:theme="@android:style/Theme.NoTitleBar"
Or the entire application:
<application android:theme="@android:style/Theme.NoTitleBar"
Finally, check how this looks in the emulator.
38
Step 7: Cut Corners Using Inheritance
Although you can define custom themes from scratch, its usually more
efficient to extend one of the Android platforms predefined themes using
inheritance. By setting a parent theme, you implement all of the
attributes of the predefined theme, but with the option of re-defining and
adding attributes to quickly create a tailor-made theme.
In values/themes.xml, set the unique identifier as normal, but specify a
parent theme to inherit from.
<style name="PinkTheme" parent="android:style/Theme">
</style>
39
Tip. Check platforms/android/data/res/values/themes for parent themes to
extend.
Define each attribute thats being added or modified. In this example were
implementing the default Theme but with a new font colour:
<style name="PinkTheme" parent="android:style/Theme">
<item name="android:textColorPrimary">#FF69B4</item>
</style>
Open the Android Manifest and locate either the application or activity tag.
Apply your theme:
<application android:theme="@style/PinkTheme">
As always, check your work in the emulator.
40
Implicit vs. Explicit Parenting
Styles support parenting, wherein a child style adopts all attributes of a parent style. It
would be rather limiting if they did not.
Suppose I want every Button in the app to look the same, so I make a ButtonStyle. Later, I
decide half the Buttons should look slightly different - with parenting, I can just
create ButtonStyle.Different, getting the base style + the tweaks.
It turns out there are two ways of defining parents, implicitly and explicitly:
<!-- Our parent style --> <style name="Parent" /> <!-- Implicit parenting, using dot notation
--> <style name="Parent.Child" /> <!-- Explicit parenting, using the parent attribute -->
<style name="Child" parent="Parent" /> Simple enough, right? But what do you think
happens here, when we define parents with both methods?
<style name="Parent.Child" parent="AnotherParent" /> If you answered that the style has
two parents, you are wrong. It turns out that it only has one parent: AnotherParent.
Each style can only have one parent, even though there are two ways to define it. The
explicit parent (using the attribute) takes precedence. This leads me to the next rule.
41
Rule : DO NOT mix implicit and explicit parenting.
Mixing the two is a recipe for confusion. Suppose I have this layout:
<Button style="@style/MyWidgets.Button.Awesome" android:layout_width="match_parent"
android:layout_height="match_parent" /> But it turns out that my style is defined thus:
<style name="MyWidgets.Button.Awesome" parent="SomethingElse" /> Even though it looks like
my Button is based on MyWidgets.Button, it's not! The style name is misleading and the only way to
discover that is to do extra work and dig into your style files.
The common temptation is to keep using dot notation with explicit parenting so that your
styles look hierarchically related:
<style name="MyButton" parent="android:Widget.Holo.Button" /> <style name="MyButton.Borderless"
parent="android:Widget.Holo.Button.Borderless" /> Object-oriented styles! They look so pretty, right?
But looks are all you're getting - an illusion that styles are related when they are not. The deception
is that MyButton.Borderless is related to MyButton, but they have nothing in common! Let's remove the
confusion by removing the dots from the name:
<style name="MyButton" parent="android:Widget.Holo.Button" /> <style name="MyBorderlessButton"
parent="android:Widget.Holo.Button.Borderless" /> I lose out on the hierarchy looking pretty, but I gain a
lot of utility in code.
42
Styles vs. Themes
Styles and themes are two different concepts. While styles apply to a single View,
themes are applied to a set of Views (or to a whole Activity).
For example, suppose you are using AppCompat and you want to set the primary
color for the screen. For this, you must theme the entire Activity:
<style name="MyTheme"> <style
name="colorPrimary">@color/my_primary_color</style> </style> Themes use the
same data structure as styles - even using the style tag - but they are, in fact,
used in totally different circumstances! They don't operate on the same attributes
- for example, you can define a textColor on a View, but there is
no textColor attribute for a theme. Likewise, there exists colorPrimaryin themes,
but in styles they go unused.
43
Thus:
Rule : DO NOT mix styles and themes.
Two common mistakes I've seen:
Applying a theme (as a style) to a View:
<View style="@android:style/Theme" /> It just makes no sense because a View can't use any of the
theme attributes anyways. Nothing happens.
Combining the themes/styles in your hierarchy via parenting. I've seen this as a result of people trying to
maintain the illusion of hierarchy using dot notation:
<style name="MyTheme" /> <style name="MyTheme.Widget" /> <style
name="MyTheme.Widget.Button" /> Stupid! So, stupid! It does not make any sense and sometimes
misfires in strange ways. Just don't do it!
As of Lollipop, you can apply themes to a View and all its children 2. Even in that circumstance, you
shouldn't mix up the two, though you could use them both in parallel:
<View style="@style/MyView" android:theme="@style/MyTheme" /> AppCompat has a simulacrum
of View theming for the Toolbar, but that's all you'll get for a while until Lollipop is the minimum
supported version of your app. In other words - you can have fun with this feature in a couple years.
44
A Brief Note On ActionBar
Overview
An ActionBar is located at the top of an activity and it can display any number of status or
navigation related elements such as title, icon, buttons, or arbitrary action-related views.
This is typically used for displaying the title of the application and providing a primary
navigation for the app. The ActionBar can contain primary action buttons as well as a
drawer toggle icon for displaying the navigation drawer.
Note that we will be using the support library and AppCompatActivity for these examples
since the library provides maximum compatibility with pre-3.0 Android versions. The APIs
and usage are the same with the standard ActionBar just with small changes to the
imported classes and class names.
45
TOC
Overview
Usage
Setting up AppCompatActivity
Populating Action Buttons
Configuring ActionBar Icon Order
Custom ActionBar Styles
Custom ActionBar Layout
Adding ActionView Items
Adding SearchView to ActionBar
Using ActionProvider and ShareActionProvider
Navigating Up with the App Icon
Configuring the ActionBar from a Fragment
Configuring a Split-Action Bar
46
Usage
In the Defining ActionBar cliffnotes we looked at the basics of adding items
to the ActionBar and handling clicks. In this section, we take a look at
how to use AppCompatActivity to support all Android versions and also at
several powerful and extensible ActionBar features:
Using the split action bar to have a top and bottom menu
Adding ActionView (app:action_layout) and SearchView widgets
Configuring icon order within ActionBar
Using ActionProvider and ShareActionProvider to enable richer functions
Configuring Home Icon to navigate "Up"
Inflating menu icons from fragments within the ActionBar
47
Setting up AppCompatActivity
In order to ensure that the ActionBar works on all Android versions, we are going to use
AppCompatActivity to setup our support ActionBar. Follow the AppCompat setup guide to
make sure you're including the library.
Once the library has been added, be sure to sync your project with the gradle file (Tools =>
Android => Sync Project with Gradle Files) and make sure any applicable activities are now
extending from AppCompatActivity in order to enable the compatibility fragments and action
bar:
public class MainActivity extends AppCompatActivity { // ... }
and change the parent theme to a support compatible theme in values/styles.xml such
asTheme.AppCompat.Light.DarkActionBar:
<resources> <!-- Base application theme. --> <style name="AppTheme"
parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. -->
</style> </resources>
48
Now the support ActionBar is configured and ready to be used. However,
one should note that the res/menu xml files now need to use
an app: prefix for showAsAction as shown below:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"> <item
android:id="@+id/action_refresh" android:title="@string/action_refresh"
android:icon="@drawable/ic_action_refresh"
app:showAsAction="ifRoom" /> </menu>Note the use
of app:showAsAction instead of android:showAsAction in the case of
adding support action bar items.
49
Populating Action Buttons
The action bar provides users access to the most important action items
relating to the app's current context. Those that appear directly in the
action bar with an icon and/or text are known as action buttons.
For the support ActionBar, just change onCreateOptionsMenu to use the
compatibility inflater:
@Override
public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu;
this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu); return true; }
See the Defining the ActionBar cliffnotes for the basic details of adding items
and handling clicks.
50
Configuring ActionBar Icon Order
You can control the order of items within the ActionBar
using orderinCategory where each menu item has an integer specified and
lower integers are displayed with a higher priority:
<item android:id="@+id/menu_ordinary" android:orderInCategory="200"
app:showAsAction="ifRoom" android:title="Ordinary" /> <item
android:id="@+id/menu_important" android:orderInCategory="20"
app:showAsAction="ifRoom" android:title="Important" />This can be useful
to be explicit with the desired order based on importance of actions.
51
Custom ActionBar Styles
We can configure the ActionBar styles and properties by creating our own
ActionBar theme styles. For example, we could add the following
to res/values/styles.xml:
<resources> <!-- Define your colors in `res/values/colors.xml` --> <color
name="simple_yellow">#ECD078</color> <color
name="primary_blue">#53777A</color> <style name="AppTheme"
parent="Theme.AppCompat.Light.DarkActionBar"> <item
name="android:actionBarStyle">@style/MyActionBar</item> <item
name="android:actionBarTabTextStyle">@style/MyActionBarTabText</item
> <!-- Support library compatibility --> <item
name="actionBarStyle">@style/MyActionBar</item>
52
<item name="actionBarTabTextStyle">@style/MyActionBarTabText</item> </style>
<style name="MyActionBar"
parent="@style/Widget.AppCompat.Light.ActionBar.Solid.Inverse"> <item
name="android:background">@color/simple_yellow</item> <item
name="android:titleTextStyle">@style/MyActionBar.TitleTextStyle</item> <!--
Support library compatibility --> <item
name="background">@color/simple_yellow</item> <item
name="titleTextStyle">@style/MyActionBar.TitleTextStyle</item> </style> <style
name="MyActionBar.TitleTextStyle"
parent="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"> <item
name="android:textColor">@color/primary_blue</item> </style> <style
name="MyActionBarTabText"
parent="@style/Widget.AppCompat.ActionBar.TabText"> <item
name="android:textColor">@color/primary_blue</item> </style> </resources>
53
Now verify the theme for the application or activity within the AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.codepath.example.servicesdemo"
...>
<application ...
android:theme="@style/AppTheme" >
</manifest>
Now your properties and styles will take affect within the ActionBar. This results in the following:
54
Custom ActionBar Layout
In certain cases, you might want to change the styling of the ActionBar title more significantly. For
example, you may want to tweak the icon, change the size of the title, tweak the color, or
center the text. In order to achieve this, you can replace the default title with your own custom
XML view. First, define your custom ActionBar XML in res/layout/actionbar_title.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:gravity="center" android:orientation="vertical" > <TextView
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:text="@string/app_title" android:textColor="#ffffff"
android:id="@+id/mytext" android:textSize="18dp" /> </LinearLayout>Now we've defined the
XML layout desired and we need to load this custom XML file and replace the ActionBar title
with our customized XML inside the Activity by calling setCustomView:
55
import android.support.v7.app.ActionBar; // in Activity#onCreate
getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
getSupportActionBar().setCustomView(R.layout.actionbar_title);At this point, we now have
replaced the default ActionBar with our preferred layout and have complete control over it's
appearance. The above code results in:
If you want to include the app icon with the custom layout you need to
append DISPLAY_SHOW_HOME as well:
getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM |
ActionBar.DISPLAY_SHOW_HOME); Note you can still define
an onCreateOptionsMenu method in your Activity to define the action buttons. This custom
view will then share space with the action buttons, which normally are placed to the right side
of the Action Bar.
56
Adding ActionView Items - If you want to provide a menu item beyond simply icon or
text, such as providing a more interactive widget, an Action View enables you to do
so. The most common Action View is the SearchView, which collapses to show only
the search icon and expands to show an EditText when the user has clicked an
icon. You can also use an Action View to create a custom layout too.
An ActionView is a full fledged view that is constructed via a layout XML file which is
embedded into the ActionBar. First, you need to create the XML layout that will be
embedded in the ActionBar in res/layout/action_view_button.xml:
<!-- res/layout/action_view_button.xml --> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:orientation="horizontal" > <Button android:id="@+id/btnCustomAction"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="Button" /> </LinearLayout>
57
Next, we can attach that layout to any item by specifying
the app:action_layout property:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"> <item
android:id="@+id/miActionButton" app:showAsAction="ifRoom"
app:actionLayout="@layout/action_view_button" android:title="Loading..." />
</menu>and now the views specified in the layout are embedded in the ActionBar.
The above code results in:
58
We can access a reference to the embedded ActionView in the Activity by overriding
the onPrepareOptionsMenu method:
@Override
public boolean onPrepareOptionsMenu(Menu menu) { MenuItem actionViewItem =
menu.findItem(R.id.miActionButton); // Retrieve the action-view from menu View v =
MenuItemCompat.getActionView(actionViewItem); // Find the button within action-
view Button b = (Button) v.findViewById(R.id.btnCustomAction); // Handle button
click here return super.onPrepareOptionsMenu(menu); }Using ActionView can
help you add any custom views you'd like to your ActionBar.
59
Adding SearchView to ActionBar
One common example of an ActionView is the built-in SearchView which provides a simple search control
within your application located in the ActionBar. First, we need to add the SearchView action item in the
menu xml:
<!-- res/menu/menu.xml -->
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" >
<item android:id="@+id/action_search"
android:orderInCategory="5"
android:title="Search"
android:icon="@android:drawable/ic_menu_search"
app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="android.support.v7.widget.SearchView" /></menu>
Notice that the app:showAsAction attribute also includes the "collapseActionView" value which collapses the
search into an icon until clicked. The above code results in the search view in the action bar:
60
Now we need to hook up a listener for when a search is performed:
// Make sure to import the support version of the SearchView import
android.support.v7.widget.SearchView; @Override public boolean
onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu); MenuItem searchItem =
menu.findItem(R.id.action_search); final SearchView searchView = (SearchView)
MenuItemCompat.getActionView(searchItem); searchView.setOnQueryTextListener(new
OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { //
perform query here // workaround to avoid issues with some emulators and keyboard devices
firing twice if a keyboard enter is used // see https://code.google.com/p/android/issues/detail?
id=24599 searchView.clearFocus(); return true; } @Override public boolean
onQueryTextChange(String newText) { return false; } }); return
super.onCreateOptionsMenu(menu); }
61
We can expand the SearchView any time programmatically by
calling expandActionView on the search view:
@Override public boolean onCreateOptionsMenu(Menu menu) { // ... lookup the
search view MenuItem searchItem = menu.findItem(R.id.action_search); final
SearchView searchView = (SearchView)
MenuItemCompat.getActionView(searchItem); // Expand the search view and
request focus searchItem.expandActionView(); searchView.requestFocus(); }We
can customize the search icon and text color with this approach with styles or the
Java code below:
62
@Override public boolean onCreateOptionsMenu(Menu menu) { // ... lookup the
search view MenuItem searchItem = menu.findItem(R.id.action_search); final
SearchView searchView = (SearchView)
MenuItemCompat.getActionView(searchItem); // Use a custom search icon for the
SearchView in AppBar int searchImgId =
android.support.v7.appcompat.R.id.search_button; ImageView v = (ImageView)
searchView.findViewById(searchImgId);
v.setImageResource(R.drawable.search_btn); // Customize searchview text and
hint colors int searchEditId = android.support.v7.appcompat.R.id.search_src_text;
EditText et = (EditText) searchView.findViewById(searchEditId);
et.setTextColor(Color.BLACK); et.setHintTextColor(Color.BLACK); }
63
Using ActionProvider and ShareActionProvider
You can build your own action provider by extending the ActionProvider class, but
Android provides some pre-built action providers such as ShareActionProvider
which facilitates a "share" action by showing a list of possible apps for sharing.
64
65
Navigating Up with the App Icon
To enable the app icon as an Up button, call setDisplayHomeAsUpEnabled.
"Up" in contrast to the Back button takes the user to the logical parent screen of the
current screen. This is not based on the navigation history but rather on the
relationship between screens. For example, in a mail client "Back" might take the
user to a previous email but "Up" would always take the user to the list of mail in the
inbox.
First, specify that the home icon should be used as "Up":
@Override protected void onCreate(Bundle savedInstanceState)
{ super.onCreate(savedInstanceState); setContentView(R.layout.activity_details); //
Enable up icon getSupportActionBar().setDisplayHomeAsUpEnabled(true); ... }We
can also explicitly override the "Up" button in the AppBar in
the onOptionsItemSelected by checking for theandroid.R.id.home id being selected:
66
@Override public boolean onOptionsItemSelected(MenuItem item) { switch
(item.getItemId()) { // This is the up button case android.R.id.home:
NavUtils.navigateUpFromSameTask(this); //
overridePendingTransition(R.animator.anim_left, R.animator.anim_right); return
true; default: return super.onOptionsItemSelected(item); } }This allows us to
configure the transition or otherwise handle behavior when the "up" button is
pressed.
67
Compile-time Configuration
To specify the "up" activity at compile-time we can set the logical parent of an activity in
the AndroidManifest.xml:
<activity android:name="com.example.myfirstapp.ChildActivity"
android:label="@string/title_activity_display_message"
android:parentActivityName="com.example.myfirstapp.ParentActivity" > <!-- Parent
activity meta-data to support API level 7+ --> <meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.myfirstapp.ParentActivity" /> </activity>And now when
the home icon is pressed on the child, the parent activity will always be shown.
If you want to navigate up from current activity to it's Parent activity, but want that
Parent activity preserves it's state, also specify launch mode for the parent activity
in the AndroidManifest.xml. android:launchMode="singleTop"
68
Run-time Configuration
If we want to set the "up" button dynamically rather than in the manifest, we can override
thegetSupportParentActivityIntent() method on the activity returning the desired intent based
on the argument passed in:
public static final String PACKAGE_NAME = "com.myapplication."; public static final String
PARENT_NAME_EXTRA = "ParentClassName"; @Override public Intent
getSupportParentActivityIntent() { // Extract the class name of our parent Intent parentIntent
= getIntent(); String className = parentIntent.getStringExtra(PARENT_NAME_EXTRA); //
Create intent based on the parent class name Intent newIntent = null; try { //you need to
define the class with package name newIntent = new Intent(this,
Class.forName(PACKAGE_NAME + className)); } catch (ClassNotFoundException e)
{ e.printStackTrace(); } // Return the created intent as the "up" activity return newIntent; }
Then when launching a new activity, we need to supply the ParentClassName as an extra to
control the desired parent:
Intent intent = new Intent(this, ChildActivity.class);
intent.putExtra(ChildActivity.PARENT_NAME_EXTRA, "ParentActivity"); startActivity(intent);
69
Configuring the ActionBar from a Fragment
Configuring the action bar from a fragment is very similar to how it's done from an
activity, with a couple small differences. By default, Android assumes that fragments
don't want to contribute items to the action bar. When a fragment actually wants to
add items to the action bar, it needs to tell Android about this by
calling setHasOptionsMenu(true) in it's onCreate() method:
@Override public void onCreate(Bundle savedInstanceState)
{ super.onCreate(savedInstanceState); // ... setHasOptionsMenu(true); }Now
Android knows to call the fragment's onCreateOptionsMenu(...) and related
methods.
70
Keep in mind that any action bar items added by the fragment will be appended to any
existing action bar items. This includes action bar items added by the containing
activity. You can use the orderInCategory property of your action bar items to
control the ordering yourself.
Adding items to the menu is very similar to how it's done in an activity. Inside a
fragment, Android provides a MenuInflater for you in the callback:
@Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { //
Inflate the menu; this adds items to the action bar. inflater.inflate(R.menu.my_menu,
menu); // ... }Handling clicks is exactly the same as if you were in an activity. The
only difference is that the fragment'sonOptionsItemSelected(...) method only gets
called if the activity's onOptionsItemSelected(...) doesn't handle the click.
71
@Override public boolean onOptionsItemSelected(MenuItem item) { // handle item
selection switch (item.getItemId()) { case R.id.my_item: // Handle this selection
return true; default: return super.onOptionsItemSelected(item); } }Configuring a
Split-Action Bar
Split action bar provides a separate bar at the bottom of the screen to display all action
items when the activity is running on a narrow screen (such as a portrait-oriented
handset). This is helpful when you want to display a top and bottom row of actions
for a context.
72
For Holo-based themes, to add support for the split-action bar, just add the option to
the manifest for that activity:
<manifest ...> <activity android:uiOptions="splitActionBarWhenNarrow" ... > <meta-
data android:name="android.support.UI_OPTIONS"
android:value="splitActionBarWhenNarrow" /> </activity> </manifest>Note: Split
action bar only works with Holo-based themes. splitActionBarWhenNarrow is
**not supported byTheme.Material or the appcompat-v7 actionbar backport. If you
wish to use either Theme.Material or appcompat-v7, you willneed to create your
own "split action bar", by having a Toolbar at the bottom of the screen that you
populate separately.
Libraries
AppCompatActivity - The support library for ActionBar which provides backwards
compatibility to nearly all Android versions.
73
Defining The ActionBarEdit PagePage History
Overview
The ActionBar, now known as the App Bar, is a consistent navigation element that is
standard throughout modern Android applications. The ActionBar can consist of:
An application icon
An "upward" navigation to logical parent
An application or activity-specific title
Primary action icons for an activity
Consistent navigation (including navigation drawer)
Important to note is that prior to 3.0, there was no ActionBar. In 2013, Google
announced a support library that provides much better compatibility for older
versions and support for tabbed interfaces. Since most of the examples below
depend on this support library, make sure to include the AppCompat library.
74
ActionBar Basics
Every application unless otherwise specified has an ActionBar by default. The
ActionBar by default now has just the title for the current activity.
Changing the ActionBar Title
The ActionBar title displayed at the top of the screen is governed by
the AndroidManifest.xml file within the activity nodes. In the example below, the
activity "FirstActivity" will have an ActionBar with the string value of the resource
identified by@string/activity_name. If the value of that resource is "Foo," the string
displayed in the ActionBar for this activity will be "Foo." Note that
the application node can supply a android:label that acts as the default for activities
and components with no other specified label.
75
<application android:icon="@drawable/ic_launcher" android:label="@string/app_name"
android:theme="@style/AppTheme"> <activity
android:name="com.codepath.example.simpleapp.FirstActivity"
android:label="@string/activity_name" > </activity> </application>Change
the android:label or android:icon to modify the ActionBar title or icon for a given
activity or for the application as a whole. In any Java activity, you can also
call getSupportActionBar() to retrieve a reference to the ActionBar and modify or
access any properties of the ActionBar at runtime:
ActionBar actionBar = getSupportActionBar(); // or getActionBar();
getSupportActionBar().setTitle("My new title"); // set the top title String title =
actionBar.getTitle().toString(); // get the title actionBar.hide(); // or even hide the
actionbarYou can also change many other properties of the ActionBar not covered
here. See the Extended ActionBar Guide for more details.
76
Displaying ActionBar Icon
In the new Android 5.0 material design guidelines, the style guidelines have changed
to discourage the use of the icon in the ActionBar. Although the icon can be
added back with:
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setLogo(R.mipmap.ic_launcher);
getSupportActionBar().setDisplayUseLogoEnabled(true);The above code results in:
You can read more about this on the material design guidelines which state: "The use
of application icon plus title as a standard layout is discouraged on API 21 devices
and newer."
77
Adding Action Items
When you want to add primary actions to the ActionBar, you add the items to the
activity context menu and if properly specified, they will automatically appear at the
top right as icons in the ActionBar.
An activity populates the ActionBar from within the onCreateOptionsMenu() method:
public class MainActivity extends AppCompatActivity { @Override public boolean
onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the
action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu);
return true; } }Entries in the action bar are typically called actions. Use this method
to inflate a menu resource that defines all the action items within
a res/menu/menu_main.xml file, for example:
78
<!-- Menu file for `activity_movies.xml` is located in a file such as
`res/menu/menu_movies.xml` --> <menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"> <item
android:id="@+id/miCompose" android:icon="@drawable/ic_compose"
app:showAsAction="ifRoom" android:title="Compose"> </item> <item
android:id="@+id/miProfile" android:icon="@drawable/ic_profile"
app:showAsAction="ifRoom|withText" android:title="Profile"> </item> </menu>You
also should note that the xmlns:app namespace must be defined in order to
leverage the showAsAction option. The reason is that a compatibility library is used
to support the showAsAction="ifRoom" option. This option is needed to show the
item directly in the action bar as an icon. If there's not enough room for the item in
the action bar, it will appear in the action overflow. If withText is specified as well (as
in the second item), the text will be displayed with the icon.
79
The above code results in two action icons being displayed:
80
Handling ActionBar Clicks
There are two ways to handle the click for an ActionBar item. The first approach is you
can use the android:onClick handler in the menu XML, similar to handling button
clicks:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"> <item
android:id="@+id/item1" android:icon="@drawable/ic_compose"
android:onClick="onComposeAction" app:showAsAction="ifRoom"
android:title="Compose"> </item> </menu>and then define the
method onComposeAction in the parent activity before attempting to run the
application or an exception will be thrown for the missing method:
81
public class MainActivity extends AppCompatActivity { public void
onComposeAction(MenuItem mi) { // handle click here } }The second approach is to
use the onOptionsItemSelected() method. Using the MenuItem passed to this
method, you can identify the action by calling getItemId(). This returns the unique ID
provided by the item tag's id attribute so you can perform the appropriate action:
@Override public boolean onOptionsItemSelected(MenuItem item) { // Handle
presses on the action bar items switch (item.getItemId()) { case R.id.miCompose:
composeMessage(); return true; case R.id.miProfile: showProfileView(); return
true; default: return super.onOptionsItemSelected(item); } }and then you can
handle all the action buttons in this single method.
82
Understanding ToolBar
ToolBar was introduced in Android Lollipop, API 21 release and is the spiritual
successor of the ActionBar. It's a ViewGroupthat can be placed anywhere in your
layout. ToolBar's appearance can be more easily customized than the ActionBar.
ToolBar works well with apps targeted to API 21 and above. However, Android has
updated the AppCompat support libraries so the ToolBar can be used on lower
Android OS devices as well. In AppCompat, ToolBar is implemented in
theandroid.support.v7.widget.Toolbar class.
83
Sharing Content with Intents
84
Android Styles and Themes
85
1. Android Design Patterns
Android is one among the most matured mobile platform today. Like
every platforms, android development follows certain guidelines and
patterns. The patterns are derived in order to make the app look
amazing, simplifying life, and to provide the best performance.
Google developers insist to follow the platform design guidelines for
developing android applications. Remember to focus on below three
overreaching goals while developing your applications
Application should be usable and easy to understand
Your app should strive to combine beauty. But remember not to make it
too complex. Make your app not to heavy, it should be responsive.
86
2. Using Custom Styles
Android supports customizing view and widgets by applying styles.
A style is a collection of properties that specify the look and format
for a View or widget. A style can specify properties such as height,
padding, font color, font size, background color, and much more. In
Android Styles works similar to CSS (cascading stylesheets) that
are used in web designing application.
In android Styles are XML files that are placed in the /res/values
directory of your project.
87
The root node of the XML file must be <resources> and you use a style
tag that includes the name attribute. This tag contains than more or
more item tags which define values for named attributes. For
example, the below example we will create a TextView in android
using XML layout editor.
88
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello_world" android:textColor="#006633"
android:background="#f0f0f0" android:typeface="monospace"
android:textStyle="italic" android:padding="5dp"> </TextView>
This works great for us, but what if we have to use the same or
similar TextView style at multiple places in our application?? Yes,
we can surely achieve this by copying the same style in multiple
places.
89
But that will result in following problems
What if we have to re-skinning our application tomorrow? We have
to change in all over the places we have used the color, styles. And I
am sure this will consume quite a lot time.
We will end up writing repetitive code, which is again difficult to
maintain.
90
Sounds Frustrating? Now, we can overcome this by declaring a style
for the TextView. A single style can be used by multiple places in our
application. Change in the style at single place will reflect the
changes all over. Sounds interesting? Let us see the below code
snippet.
<TextView android:id="@+id/textView2"
style="@style/MtTextViewStyle" android:text="@string/hello_world">
</TextView>
In this above code snippet, the TextView is referencing
@style/MyTextViewStyle style.
91
2.1. Defining Style Class
A style xml file can be declared separately and that can be used or
applied in other layout files. We can create a new xml file and save it
in the res/values/ directory of your project. The root node of the XML
file must be <resources>.
Multiple styles can be defined in a single style.xml file. For each
style you want to create, add a <style> element to the file with a
name that uniquely identifies the style. Then add an <item> element
for each property of that style, with a name that declares the style
property and a value to go with it. The value for the <item> can be a
keyword string, a hex color, a reference to another resource type, or
other value depending on the style property.
92
Here is the style we have defined for the TextView example
<style name="MyTextViewStyle"> <item
name="android:layout_width">fill_parent</item> <item
name="android:layout_height">wrap_content</item> <item
name="android:textColor">#006633</item> <item
name="android:typeface">monospace</item> <item
name="android:background">#f0f0f0</item> <item
name="android:textStyle">italic</item> <item
name="android:padding">5dp</item> </style>
93
2.2. Apply a Style to View
Heres how to set a style for a View in the XML layout:
<TextView android:id="@+id/textView2"
style="@style/MyTextViewStyle"
android:text="@string/hello_world"> </TextView>Now this TextView
will be styled as defined by the style named MyTextViewStyle
94
2.3. Inheriting Built-in Platform Styles
The parent attribute in the <style> element lets you specify a style from
which your style should inherit properties. You can use this to inherit
properties from an existing style and then define only the properties
that you want to change or add. You can inherit from styles that
youve created yourself or from styles that are built into the platform.
Below code snippet inherits the android platforms default text
appearance and then modify it
@android:style/TextAppearance.Large
95
<style name="MyTextViewStyle"
parent="@android:style/TextAppearance.Large"> <item
name="android:layout_width">fill_parent</item> <item
name="android:layout_height">wrap_content</item> <item
name="android:textColor">#006633</item> <item
name="android:typeface">monospace</item> <item
name="android:background">#f0f0f0</item> <item
name="android:textStyle">italic</item> <item
name="android:padding">5dp</item> </style>
96
2.4. Inheriting Self Defined Styles
Android allows you to inherit other styles defined in the applications.
Find the example below
<style name="MyTextViewStyle"
parent="@android:style/TextAppearance.Large"> <item
name="android:layout_width">fill_parent</item> <item
name="android:layout_height">wrap_content</item> <item
name="android:textColor">#006633</item> <item
name="android:typeface">monospace</item> <item
name="android:background">#f0f0f0</item> <item
name="android:textStyle">italic</item> <item
name="android:padding">5dp</item> </style> <style
name="MyTextViewStyle.BoldRed"> <item
name="android:textColor">#FF0000</item> <item
name="android:textStyle">bold</item> </style>
97
Notice that there is no parent attribute in the <style> tag, but because
the name attribute begins with the MyTextViewStyle style name,
which is a style that you have created. MyTextViewStyle.BoldRed
style inherits all style properties from that MyTextViewStyle. This
style then overrides the android:textColor and android:textStyle
property to make the text red and bold. The newly created style can
be referenced from TextView as @style/MyTextViewStyle.BoldRed.
98
You can continue inheriting like this as many times as youd like, by
chaining names with periods.
<style name="MtTextViewStyle"
parent="@android:style/TextAppearance.Large"> <item
name="android:layout_width">fill_parent</item> <item
name="android:layout_height">wrap_content</item> <item
name="android:textColor">#006633</item> <item
name="android:typeface">monospace</item> <item
name="android:background">#f0f0f0</item> <item
name="android:textStyle">italic</item> <item
name="android:padding">5dp</item> </style> <style
name="MtTextViewStyle.BoldRed">
99
<item
3. Applying Activity Themes
A theme is a style applied to an entire activity or application, rather than
an individual View. The technique of defining a theme is the same
as defining a style.
<style name="MyTheme" parent="android:Theme.Light"> <item
name="android:windowNoTitle">true</item> <item
name="android:colorBackground">@color/default_bg</item>
</style>The above code, overrides the default android:Theme.Light
theme and overrides android:windowNoTitle property.
100
To set a theme for all the activities of your application, open the
AndroidManifest.xml file and edit the <application> tag to include the
android:theme attribute with the style name. For example
<application android:theme="@style/MyTheme">If you want a theme
applied to just one Activity in your application, then add the
android:theme attribute to the <activity> tag.
101
4. Make Activity Look Like Dialog
Android provides other built-in themes and styles which can be used
without rewriting them yourself. You can use the Dialog theme and
make your Activity appear like a dialog box
<activity android:theme="@android:style/Theme.Dialog">Or if you want
the background to be transparent, use the translucent theme:
<activity android:theme="@android:style/Theme.Translucent">
102
Android - MediaPlayer
Android provides many ways to control playback of audio/video files and streams. One
of this way is through a class called MediaPlayer.
Android is providing MediaPlayer class to access built-in mediaplayer services like
playing audio,video e.t.c. In order to use MediaPlayer , we have to call a static
Method create() of this class. This method returns an instance of MediaPlayer
class. Its syntax is as follows
MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.song); The second
parameter is the name of the song that you want to play. You have to make a new
folder under your project with name raw and place the music file into it.
Once you have created the Mediaplayer object you can call some methods to start or
stop the music.
103
These methods are listed below.
mediaPlayer.start(); mediaPlayer.pause();On call to start() method, the music will start
playing from the beginning. If this method is called again after the pause() method ,
the music would start playing from where it is left and not from the beginning.
In order to start music from the beginning , you have to call reset() method. Its syntax
is given below.
mediaPlayer.reset(); Apart from the start and pause method, there are other methods
provided by this class for better dealing with audio/video files.
104
These methods are listed below
isPlaying()This method just returns true/false indicating the song is playing or not
seekTo(position)This method takes an integer, and move song to that particular second
getCurrentDuration()This method returns the current position of song in milliseconds
getDuration()This method returns the total time duration of song in milliseconds
reset()This method resets the media player
release()This method releases any resource attached with MediaPlayer object
setVolume(float leftVolume, float rightVolume)This method sets the up down volume for this
player
setDataSource(FileDescriptor fd)This method sets the data source of audio/video file
selectTrack(int index)This method takes an integer, and select the track from the list on that
particular index
getTrackInfo()This method returns an array of track information
105
Android Video Player
By the help of MediaController and VideoView classes, we can play the video files in
android.
MediaController class
The android.widget.MediaController is a view that contains media controls like
play/pause, previous, next, fast-forward, rewind etc.
VideoView class
The android.widget.VideoView class provides methods to play and control the video
player.
106
The commonly used methods of VideoView class are as follows:
public void setMediaController(MediaController controller)sets the media
controller to the video view.
public void setVideoURI (Uri uri)sets the URI of the video file.public void
start()starts the video view.
public void stopPlayback()stops the playback.
public void pause()pauses the playback.
public void suspend()suspends the playback.
public void resume()resumes the playback.
public void seekTo(int millis)seeks to specified time in miliseconds.
107
Android MediaRecorder Example
MediaRecorder class can be used to record audio and video files.
After recording the media, we can create a sound file that can be played later.
108
Android Sliding Menu using Navigation Drawer
You might have noticed that lot of android applications introduced a sliding panel
menu to navigate between major modules of the application. Previously this kind of
UI was done using some third party libraries where a list view and some swiping
gestures used to achieve this. But now android itself officially introduced sliding
panel menu by introducing a newer concept called Navigation Drawer.
Most of the time Sliding Menu (Navigation Drawer) will be hidden and can be shown
by swiping the screen from left edge to right or tapping the app icon on the action
bar.
109