Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
ViewPager
• Purpose: To be able to use swipe operations to switch
between fragments (or views)
• Why not ListView? ViewPager facilitates paging between
fragments integrating the FragmentManager calls.
• Adapter: Use either the FragmentPagerAdapter or
FramentStatePagerAdapter to manage fragments. The
former detaches instead of removing fragments when
done, so they can be relaunched. They are never
destroyed, so be careful.
• Support: ViewPager is not standard in recent Android
versions, so the support version must be used.
Date and Time Picker
• These widgets are used date and time selections
• They have large margins, so it is difficult to
incorporate them in layouts with other widgets
– To shrink: android:scaleX, android:scaleY
(scales but doesn’t reduce overall size)
– To reduce margins: android:layout_marginLeft
android:layout_marginRight
– Define the format: android:datePickerMode
DialogFragment
Implementation Steps
1. Launch like any fragment, but add call
setTargetFragment() in the FragmentManager
transaction
2. Implement onActivityResult() to receive returned data
3. In extension to DialogFragment, override
onCreateDialog() to find links to widgets, set listeners,
and initialize and show the alert dialog.
4. Use getTargetFragmene().setResult() to return data
when the ok button is triggered.
5. The Back button is equivalent to a cancel operation
User Interface and Handlers
Goal: Create an easy to use, intuitive, immersive experience
• Can be done in code (like in Swing)
– Similar to previous generation UI API's (like Swing, AWT)
– Painful with lots of lines of code
– Five times more statements than XML version
• Normally done in XML and strongly advised
–
–
–
–
Progressive enhancement/Model-View (like JavaFX)
Easier to maintain, lots less code and separate from source
Can create specialized views for different environments
Store layout files as text in resource subdirectories
• res/layout: The default version
• res/layout-landscape, res/layout-fr-small
User Interface Example
• This application contains a series of labels presented
vertically.
• There is an outer container and two inner containers
• The second inner container contains two lower level
sub-containers
Layout File Structure
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- NAME CONTAINER XML goes here -->
<!-- ADDRESS CONTAINER goes here -->
</LinearLayout>
Notes
1.
2.
3.
4.
5.
6.
Shown is the outer container: like a frame in Java
Linear layout is similar to BoxLayout in Java
match_parent uses all the space provided by the parent container
Android > 2.2: fill_parent is deprecated; replaced by match_parent
"http://schemas.android.com/apk/res/android" contains XML android schema
Layouts and views are nestable, but minimize nesting for maximum performance
Name Container
Shown as a comment in the previous slide
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Name:" />
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="John Doe" />
</LinearLayout>
Notes
• Use all available space horizontally and only the space needed vertically
• This example uses hard-coded text, which is possible, but not advisable
• TextView in this example is similar to Java JLabel components
Address Container
Shown as a comment in the previous slide
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent“ android:layout_height="wrap_content">
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content" android:text="Address:" />
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content" android:text="911 Hollywood Blvd." />
</LinearLayout>
Notes
• Use all available space horizontally and only the space needed vertically
• Two sub views (components) containing text strings
Using String ids
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent“ android:layout_height="wrap_content">
<TextView android:id="@+id/nameText" android:text="@string/name_text"
android:layout_width="wrap_content“ android:layout_height="wrap_content"/>
<TextView android:id="@+id/nameValue"
android:layout_width="wrap_content" android:layout_height="wrap_content"/>
</LinearLayout>
Notes
1.
2.
3.
@string/name_text refers to a strings.xml entry in res/values/strings.xml
<string name="name_text">Name:</string>
The + in @+id/nameValueText adds a code for nameValueText if not defined
Java Access: TextView name = (TextView)findViewById(R.id.nameValue);
name.setText("John Doe"); or name.setText(R.string.JohnDoe);
Text Views
• TextView: Like a smarter Java Jlabel
– Attribute: android:autoLink= "email|web|phone|map"
• Creates hyperlink, initiates a phone call, or draws a map
• Code: (TextView)findViewById(R.id.tv).setAutoLinkMask(Linkify.ALL);
– Other attributes: android:minLines, android:maxLines, etc.
• EditText: Like Java JTextField with additional capabilities
– Autocorrection for captalizing text, etc.
– Able to validate syntax for phone numbers, emails, etc.
– Display field hints: android:hint="@string/someHint" or setHint()
– Additional attributes like android:textMultiLine, etc.
• AutoCompleteTextView: Completion suggestions while user types based
on a supplied array of strings (ex: list of states)
• MultiAutoCompleteTextView: Completion Suggestions during partial text
entry after token boundaries (like commas, spaces, and periods).
EditText Example
<EditText android:inputType="textMultiLine" <!-- Multiline input -->
android:lines="8" <!– Desired component height -->
android:minLines="6" <!-- Minimum lines if limited space -->
android:gravity="top|left" <!-- Cursor Position -->
android:maxLines="10" <!-- Maximum Lines to display if room -->
android:layout_width="match_parent"
android:layout_height= "wrap_content "
android:scrollbars="vertical" <!-- Vertical Scroll Bar -->
android:hint="@string/email_hint"
android:inputType="textEmailAddress" />
Button Controls
• Button (Example launches browser)
Button btn = (Button)this.findViewById(R.id.btn);
btn.setOnClickListener(new OnClickListner())
{ Intent intent = new Intent(Intent.ACTION_VIEW, URI.parse("http://www.sou.edu));
startActivity(intent);
});
• ImageButton: Clickable image (or icon) in res/drawable directory
<ImageButton android:id="@+id/imageBtn" android:src="@drawable/btnImage"
android:layout_width="wrap_content" android:layout_height="wrap_content" />
• ToggleButton: Switch from on to off on each click, bar shows green if on
<ToggleButton android:id="@+id/cctglBtn"
android:layout_width="wrap_content" android:layout_height="wrap_content"
Android:textOn="Stop" Android:textOff="Run"
android:text="Toggle Button"/> <-- android:text not used, inherited from TextView -->
Checkbox Buttons
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent android:layout_height="match_parent“ />
<CheckBox android:text="Chicken"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked= "true" />
<CheckBox android:text="Fish"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<CheckBox android:text="Steak"
android:layout_width="wrap_content“ android:layout_height="wrap_content"
android:checked="true" />
</LinearLayout>
Radio Buttons
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent" android:layout_height="match_parent">
<RadioGroup android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RadioButton android:id="@+id/chRBtn" android:text="Chicken"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<RadioButton android:id="@+id/fishRBtn" android:text="Fish"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<RadioButton android:id="@+id/stkRBtn" android:text="Steak"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RadioGroup></layout>
Other Android Controls
• ImageView: <ImageView android:id="@+id:myImageCode" />
– Display a color: anroid:src="#555555"
– Display an image:
android:src="@drawable/manatee" android:scaleType="centerInside"
– Specify a picture not in the res/drawable directory
ImageView img = (ImageView)findViewById(R.id.myImageCode);
img.setImageUri(Uri.fromFile(new File("/sdcard/cats.jpg")));
•
•
•
•
DatePicker, TimePicker: Select a date,time using dropdown menus
DigitalClock: Display a digital clock updating automatically
MapView: Display a Google map
WebView: Display HTML/JavaScript from an Android native application
Layout Managers
A view that controls how the sub-views are arranged
• LinearLayout
– components arranged horizontally or vertically
– Similar to Java BoxLayout
• TableLayout
– Specify rows and columns
– Similar to laying out HTML tables
• RelativeLayout: positioning relative to other components
– layout_centerInParent, alignParentTop, alignParentBottom
– layout_above, layout_toRightOf, layout_toLeftOf, layout_below
• FrameLayout
– Multiple components in the same space
– Similar to Java OverlayLayout and CardLayout
TableLayout
Example
One row/ three columns
Stretch to fill entire width
<TableLayout xmlns:android=http://schemas.android.com/apk/res/android
android:layout_width= "match_parent" android:layout_height= "match_parent"
android:stretchColumns="0,1,2"> <-- indicate which columns to stretch -->
<EditText android:text="Full Name:"/>
<TableRow>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Barack"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Hussein"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Obama"/>
</TableRow>
android:layout_span="2" to span two view columns
</TableLayout>
Example: FrameLayout
Only the first picture is visible
Similar to Java OverlayLayout
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/frmLayout" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView android:id="@+id/one" android:src="@drawable/one"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter" />
<ImageView android:id="@+id/two" android:src="@drawable/two"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter" android:visibility="gone" />
Android Code for Frame Layout
@Override protected void onCreate(Bundle savedInstanceState)
{ super.onCreate(savedInstanceState);
setContentView(R.layout.frame);
ImageView one = (ImageView)this.findViewById(R.id.one);
ImageView two = (ImageView)this.findViewById(R.id.two);
one.setOnClickListener(new OnClickListener()
{ @Override public void onClick(View view)
{ ImageView two=(ImageView) FramelayoutActivity.this.findViewById(R.id.two);
two.setVisibility(View.VISIBLE); view.setVisibility(View.GONE);
}});
two.setOnClickListener(new OnClickListener()
{ @Override public void onClick(View view)
{ ImageView one=(ImageView)FramelayoutActivity.this.findViewById(R.id.one);
one.setVisibility(View.VISIBLE); view.setVisibility(View.GONE);
}}); }
Reusable layouts
Inserting one layout into another
<?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="vertical">
<include android:id="@+id/my_actionbar"
layout= "android:layout/actionbar" />
<include android:id= "@+id/my_image_text_layout"
layout = "@layout/image_text_layout" />
</LinearLayout>
Frame Layout Example
<FrameLayout xmlns:android
= http://schemas.android.com/apk/res/android
android:layout_width=“match_parent"
android:layout_height=“match_parent">
<ImageView android:layout_width=“match_parent"
android:layout_height=“match_parent"
android:scaleType="center"
android:src="@drawable/golden_gate" />
<TextView
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:layout_gravity="center_horizontal|bottom"
android:padding="12dp“ android:background="#AA000000"
android:textColor="#ffffffff" android:text="Golden Gate" />
</FrameLayout>
Frame Inefficiency
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="center"
android:src="@drawable/golden_gate" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="20dip"
android:layout_gravity="center_horizontal|bottom"
android:padding="12dip"
android:background="#AA000000"
android:textColor="#ffffffff" android:text="Golden Gate" />
</FrameLayout>
Merging Directly into Parent View
Note: no fill specifications
?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
<ImageView android:id="@+id/one" android:src="@drawable/one"
android:layout_width=“match_parent"
android:layout_height=“match_parent"
android:scaleType="fitCenter" />
<ImageView android:id="@+id/two" android:src="@drawable/two"
android:layout_width=“match_parent"
android:layout_height=“match_parent"
android:scaleType="fitCenter" android:visibility="gone" />
</merge>
Lazy View (Inflate only when needed)
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<ListView android:id="@+id/myListView" android:src="@drawable/one"
android:layout_width="match_parent" android:layout_height="match_parent“
/>
<ViewStub android:id="@+id/progress" android:inflateId="@+id/progress_inflate"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_gravity= "bottom" android:layout= "@layout/progress_panel" />
</FrameLayout>
Java Code
View stub = findViewById(R.id.progress_inflate);
Stub.setVisibility(true); Later: Stub.setVisibility(false);
Weight and Gravity
• Weight: Sizing a component in a view
– Controls size relative to other components
– Android:layout_weight
– Components with large weights expand more
• Gravity: Component alignment
– android:gravity: applies to the text within a view
– android:layout_gravity: applies to the view alignment
– Possible values: "right", "left", "center", "top", "bottom",
"center_vertical", "clip_horizontal"
Padding
Definition: Space around the text
<LinearLayout xmlns:android=http://schemas.android.com/apk/res/android
android:orientation="vertical"
android:layout_width="match_parent“
android:layout_height="match_parent">
<EditText android:layout_width="wrap_content" android:text="one"
android:layout_height="wrap_content" android:padding="40dp" />
</LinearLayout>
Measurements
• Well known measurements:
Pixels: px, Inches: in, Millimeters: mm, Points: pt (1/72 of an inch)
• Density-independent pixels: See next slide
• Scale-independent pixels: sp scales dp to font sizes
if Font size is normal normal, sp=dp; if font size is large, sp>dp
Density Independent pixels
• Physical screen width 1.5 inches
• Lower resolution screen
–
–
–
–
Dots Per Inch (dpi) 160
Actual pixels 240 (width * dpi)
Density 1.0 (dpi/160)
Density Independent pixels 160 or (160 * density)
• Higher resolution
–
–
–
–
Dots Per Inch (dpi) 240
Actual pixels 360 (width * dpi)
Density 1.5 (dpi/160)
Density Independent pixels 240 or (160 * density)
• Notes:
– Most devices now define a pt as 1/72 of an inch
– Android devices define dp as 1/160 of an inch
dp and sp measurements
• dp: density independent pixels (margins, padding)
• sp: Scale independent pixels (font sizes)
• pt, mm, in: text doesn’t recommend. However, I’ve found that
modern device pt sizes are accurate (1/72 of an inch)
Complex Views
Displays a set of data using a single view
• ListView:
A scrollable list displayed vertically
• GridView:
A scrollable list of items displayed with a fixed number of
columns
• SpinnerView: (Like a Java combo box)
A scrollable drop down menu of choices
• GalleryView: (now deprecated, use ViewPager)
Horizontally scrollable list focusing on the center of the list
Note: Analogous to Swing JTree, JList, JTable components
AdapterViews
Adapter: object that formats the display of a single cell of a complex view
• Purposes
– Connect a complex view to the data
– Define the display format of a particular cell, which can contain a
variety of sub views
– Reuse the cell layout component for memory, performance efficiency
• Adapters Required Because: It is unworkable to display a large lists
with thousands of components, each requiring megabytes of memory.
• Built in Android adapter classes
– ArrayAdapter: Data items stored in an array
– SimpleCursorAdapter: Data are rows of an SQL table
• Custom Adapter: Class that overrides various adapter methods
Activity using ArrayAdapter
public class MyActivity extends Activity
{ private ArrayAdapter<String> instance;
@Override public void onCreate(Bundle savedInstanceState)
{ super.onCreate(savedInstanceState);
setContentView(R.layout.main); // main.xml in res/layout
ListView view = (ListView)findViewById(R.id.my_list_view); // scrollable list
ArrayList<String> words = new ArrayList<String> // create some data
(Arrays.asList("the", "quick", "green", "Android", "jumped“);
int layoutID = android.R.layout.simple_list_item_1; // format of list items
adapter = new ArrayAdapter<String>(this, layoutID, words);
view.setAdapter(adapter); // Attach array adapter to the list
adapter.notifyDataSetChanged(); // force redisplay of items
}
}
Item class for a To Do list Application
public class ToDoItem
{ String task; Date created;
SimpleDataFormat sdf;
public ToDoItem(String task, Date created)
{ sdf = new SimpleDateFormat("dd/mm/yy");
task = this.task; created = this.created;
}
public ToDoItem(String task)
{ this(task, new Date(java.lang.System.currentTimeMillis())); }
public String getTask() { return task; }
public Date getCreated() { return created; }
@Override public String toString() { return "("+sdf.format(created)+") "+task; }
}
Goal: display a list of these To Do items
Custom Adapter Code
public class ToDoItemAdapter extends ArrayAdapter<ToDoItem>
{ private int resource; private items = List<ToDoItem> items;
private SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
public ToDoItemAdapter(Context context, int resource, List<ToDoItem> items)
{ super(context, layout, items); this.resource = resource; this.items = item; }
@Override public View getView(int position, View view, ViewGroup parent)
{ if (view == null)
{ LayoutInflater inflater = (LayoutInflater)getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(resource, null); // null = use existing context
}
ToDoItem item = getItem(position);
view.findViewById(R.id.rowDate).setText(sdf.format(item.getCreated()));
view.findViewById(R.id.row).setText(item.getTask());
return view;
} }
Menu Categories
• Regular option menus: Activity associated (onCreateOptionsMenu())
• Secondary menus: Rarely used menu items created separately from
the parent menu appearing after regular menu items
• Submenus: A menu within a menu that appears in a floating window;
options appear when the user selects a parent item
• Context menus: triggered by a long press on a view
• Popup menus: An alternate way to attach menus to a view
• Icon menus: List of icons displayed along the screen bottom
• Alternative menus: Link to applications that can handle and
manipulate data from a content provider
Note: When more menu items exist than can show, a more button appears
Steps to create menus
1. Choose icons to be used
•
•
Create your own in the required sizes
Use the image asset wizard to choose one that is
standard
2. Define the menu items in XML
3. Call setHasOptionsMenu(true); in onCreate() or
onCreateView()
4. Code onCreateOptionsMenu() to inflate the menu
5. Code the onOptionsItemSelected() menu to listen
for and handle selections
Option Menu Framework
Classes: android.view.Menu, android.view.SubMenu, android.view.MenuItem
Regular Menu From XML
XML in file game_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:id="@+id/menuGroup"> // Group of items tied together
<item android:id="@+id/new_game" android:title="@string/new" />
<item android:id="@+id/help" android:title="@string/help" />
<group>
</menu>
Java Code to include the menu
@Override public boolean onCreateOptionsMenu(Menu menu)
{ super.onCreateOptionsMenu(menu); // Allow for system menu items
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.game_menu, menu);
return true; // Force menu to be visible
}
Note: Android calls onPrepareMenuOption every time a menu is invoked.
Overriding this method enables dynamically changing menu items.
Menu Groups
• Definition: A sequence of items from a menu
• Purpose: Control all grouped items at once
• Examples:
– menu.setGroupCheckable(id, checkable, exclusive): Check
selected items; if exclusive, only one group item can be checked
– menu.setGroupEnabled(id, enabled): Control ghosted items
– menu.setGroupVisible(id, visible): Show or hide the group items
– menu.removeGroup(id): Remove all items from the group
Creating a Menu in Code
• Regular menu items
int group = Menu.CATEGORY_NONE, order=Menu.FIRST, menuID = 99;
menu.add(group, menuID++, order++, "append");
menu.add(group, menuID++, order++, "clear");
• Secondary menu items
int group = Menu.CATEGORY_SECONDARY
int order=Menu.FIRST, menuID = Menu.FIRST;
menu.add(group, menuID++, order++, "secondary item #1");
menu.add(group, menuID++, order++, R.string.secItem2);
• Java Setup code
@Override public boolean onCreateOptionsMenu(Menu menu)
{ super.onCreateOptionsMenu(menu); // Allow for system menu items
addRegularMenuItems(menu); addSecondaryMenuItems(menu);
return true; // Force menu to show
}
Respond to Menu Item Selections
Android calls onOptionItemSelected method when an item is selected
@Override public boolean onOptionsItemSelected(MenuItem item)
{ switch (item.getItemId())
{ case R.id.new_game:
newGame();
return true; // consume this selection here
case R.id.help:
showHelp();
return true; // consume this selection here
case R.id.secondary:
this.myMenu.setGroupVisible(Menu.CATEGORY_SECONDARY, true);
return true; // consume this selection here
default:
return super.onOptionsItemSelected(item);
} }
Icon Menus
• In XML: android:icon="@drawable/ballons"
• In Code: item.setIcon(R.drawable.balloons);
• Restrictions
– Will not appear on expanded menu options (those
which show only when the more item is selected)
– Check marks are not supported
Submenus
• In XML:
<item android:title="Outer Menu Item>
<menu><item> . . .</item></menu>
• In Code:
int base = Menu.FIRST;
∙ ∙ ∙
SubMenu sub = menu.addSubMenu(base, item++ ,Menu.NONE, "submenu");
sub.add(base, order++, menuID++, "sub item # 1");
sub.add(base,order++, menuID++, R.string.subItem2 );
• Restrictions
– Icons work with submenus, but not with individual submenu items
– You cannot nest a submenu to a submenu
• Advantage: Android automatically controls the visibility
• Note: The order argument is optional; Menu.NONE indicates a default order.
Context Menus
onContextItemSelected()
View
Context Menu Creation
• Ownership: view
• Creation: Activity
– Register in the activities onCreate method
@Override public void onCreate(Bundle savedInstanceState)
{ super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView tv = (TextView)this.findViewById(R.id.textViewId);
registerForContextMenu(tv); // Indicate that view has context menu
}
– Populate: (note: info can get position for complex views)
onCreateContextMenu(ContextMenu m, View v, ContextMenuInfo info)
– Listener: onContextItemSelected(MenuItem item)
Popup Menu
It displays when touching the image,
It disappears when selecting if selected or touching outside its bounds
• Specify in an XML view declaration
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_overflow_holo_dark"
android:contentDescription="@string/descr_overflow_button"
android:onClick= "showPopup" />
• Activity code to display the popup
public void showPopup(View v)
{ PopupMenu popup = new PopupMenu(this, v);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.actions, popup.getMenu());
popup.show();
} // Note: R.menu.actions refers to the XML menu declaration
Note: Listener attached with onMenuItemClick() method
Alternative
Menus
• Application menus items can launch content providers that provide
an intent filter in their manifest
• Content Providers expose data by defining a MIME type and a
content URI access point for other applications
• Example: (The application Employees maintains employee data)
1. MIME type: vnd.android.cursor.item/mina.android.Emps
2. Other application can access the data by calling the Uri
content://mina.android.Emps/All access all employees or the Uri
content://mina.android.Emps/1 access a single employee instance
• An alternative menu item in an Application, when clicked, launches
the content provider using the Uri in an intent
The Employee Content Provider
• The content provider manifest defines an activity with the xml file
can handle external employee requests
<activity android:name=".Demo" android:label="@string/app_name">
<intent-filter android:label="Access Employees">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.ALTERNATIVE" />
<data android:mimeType="vnd.android.cursor.item/employees" />
</intent-filter>
</activity>
• This activity responds to implicit launch intents with
Action: Intent.ACTION_VIEW.
Category: android.intent.category.ALTERNATIVE.
MIME type: vnd.android.cursor.item/employees
Alternative Menu Launch
public boolean onCreateOptionsMenu(Menu menu)
{ menu.add("Regular item"); //adds a regular menu item
//create intent with the employee content provider Uri
Intent alternativeIntent =
new Intent(Intent.ACTION_VIEW, Uri.parse("content://employees/All"));
alternativeIntent.addCategory(Intent.CATEGORY_ALTERNATIVE);
menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, // applicable group id
Menu.CATEGORY_ALTERNATIVE, //item id
Menu.CATEGORY_ALTERNATIVE, //item order
this.getComponentName(), //our activity class name
null, //Specific menu items to place first
alternativeIntent, // the intent corresponding to this selection
0, //no special flags to control menu items
null); // Place menu into optional array generated from specific menu items
return true;
Add menu item to launch employee application to do
}
alternative actions other than View, Pick, or Edit
Dialogs
Analogous to Java's JOptionPane
• Functionality: Popup windows for user interaction
– Asynchronous: Returns immediately from the dialog call
– Modal: The dialog gets focus while the dialog popup shows
– Call Back Listeners: Required to receive user inputs
– Layout: Dialogs can have a layout with subcomponents
• Examples
– Alerts: Simple output messages
– Prompts: Accept user input
– Toast: Alerts that disappear after a designated time period
Alerts
if (validate(field1) == false) { showAlert("Very Bad"); }
public static void showAlert(String message, Context ctx)
{ AlertDialog.Builder builder = new AlertDialog.Builder(ctx); //Create a builder
builder.setTitle("Alert Window");
// Configure the anonymous listener
builder.setPositiveButton("OK", new OnClickListener()
{ public void onClick(DialogInterface v, int buttonId) { /* auto dismiss */ }
} );
AlertDialog alert = builder.create(); // Create the dialog
alert.show(); // Make it visible
}
Prompts
• Create a layout for a prompt dialog: using xml in res/layout
• Create a builder object
AlertDialog.Builder builder = new AlertDialog.Builder(context);
Builder.setTitle("Why this?");
• Set the layout as the builder view
LayoutInflater promptLayout = LayoutInflater.from(activity);
View view = promptLayout.inflate(R.layout.prompt, null);
builder.setView(view);
• Add buttons and callbacks
PromptListener listener = new PromptListener(view); // User-defined class
Builder.setPositiveButton("OK", listener);
Builder.setNegativeButton("Cancel", listener);
• Create and show the dialog: AlertDialog ad = builder.create(); ad.show();
Note: For applications with many dialogs, Android provides a Managed-Dialog
factory scheme for reusing previously created dialog objects
Toast
An alert that displays for a period of time, and then disappears
• Toast display (could be a useful debug tool)
public void toastDisplay(String message)
{
String data = "MY_CLASS" + ":" + message;
Toast toast = Toast.makeText
(activity, data, Toast.LENGTH_SHORT); // user definable
Toast.show();
}
• Exercise the toast display function
toastDisplay("hello");
toastDisplay(resources.getString(R.string.toast_msg);