Lecture 5 Composite Views Activities Intents and Filters Lecture 4 Review How do you get the value of a string in the stringsxml file What are the steps to populate a Spinner or ListView using XML ID: 540785
Download Presentation The PPT/PDF document "Mobile Programming" is the property of its rightful owner. Permission is granted to download and print the materials on this web site for personal, non-commercial use only, and to display it on your personal computer provided you do not modify the materials and that you retain all copyright notices contained in the materials. By downloading content from our website, you accept the terms of this agreement.
Slide1
Mobile ProgrammingLecture 5
Composite Views, Activities, Intents and FiltersSlide2
Lecture 4 Review
How do you get the value of a string in the strings.xml file?
What are the steps to populate a Spinner or ListView using XML?
How many Android application components are there? Name one.
How do you launch an Activity B from within Activity A?Slide3
Agenda
ViewFlipper
SlidingDrawer
TabLayout
Activity LifeCycle
Configuration Changes
URI
Intent FiltersSlide4
ViewFlipper
Slide5
ViewFlipper
<ViewFlipper
android:id="@+id/myViewFlipper"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
</RelativeLayout>
</ViewFlipper>Slide6
ViewFlipper
<ViewFlipper
android:id="@+id/myViewFlipper"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" > </RelativeLayout></ViewFlipper>
Here I used RelativeLayouts, but you can place any widget you want in here.Slide7
ViewFlipper
<ViewFlipper
android:id="@+id/myViewFlipper"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:layout_width="match_parent"
android:layout_height
=“wrap_content" />
<TextView android:layout_width="match_parent" android:layout_height=“match_parent“
/ >
</ViewFlipper>
Here I also used just
2
Views. You can add more than just 2 Views if you want to.Slide8
ViewFlipper
Slide9
ViewFlipper
Slide10
ViewFlipper
Slide11
FrameLayout
is designed to block out an area on the screen to display a single
item.
FrameLayout should be used to hold a single child view
it can be difficult to organize child views in a way that's scalable to different screen sizes without the children overlapping each other
FrameLayoutSlide12
Example:
FrameLayoutSlide13
SlidingDrawer
hides
content out of the screen and allows the user to drag a handle to bring the content on screen
can be used vertically or horizontally
composed of two children views
the handle, that the users drags
the content, attached to the handle and dragged with it.
should only be used inside of a FrameLayout or a RelativeLayoutSlide14
SlidingDrawer
Slide15
android:handle
android:content
android:orientation
"vertical" or "horizontal"
android:allowSingleTap
"true" or "false"
allow the user to open the drawer by tapping on the handle?
SlidingDrawer - useful attributesSlide16
open
()
close()
setOnDrawerScrollListener(OnDrawerScrollListener)
setOnDrawOpenListener(OnDrawerOpenListener)
setOnDrawerCloseListener(OnDrawerCloseListener)
SlidingDrawer - useful methodsSlide17
It is used to wrap
multiple
activities
into a single
window
navigate through the
activities
using tabs
TabLayoutSlide18
TabLayout - Anatomy
TABHOST
TABWIDGET
ACTIVITY
FRAMELAYOUT
TAB CONTENT
TabHost
container holding TabWidget and a FrameLayout
TabWidget
row of tab buttons
FrameLayout
container holding the tab contents
each tab content is a child of FrameLayoutSlide19
TabLayout - XML
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TabWidget android:id="@android:id/tabs" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <FrameLayout android:id="@android:id/tabcontent" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout>
</TabHost>
TABHOST
TABWIDGET
ACTIVITY
FRAMELAYOUT
TAB CONTENTSlide20
TabLayout - XML
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TabWidget android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
</TabHost>
TABHOST
TABWIDGET
ACTIVITY
FRAMELAYOUT
TAB CONTENT
Tabs are different Activities,
we can
set
and specify
the layout for each tab programmaticallySlide21
TabLayout
If
you're going to have x number of tabs, create x number of Activities, 1 for each
tab,
in addition to the
TabActivity (Host Activity).
You can create
x
number of XML layouts for each tab, or you can reuse the same layout for each tab.Slide22
TabLayout
public class TabLayoutExampleActivity extends TabActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TabHost tabHost = getTabHost(); // The activity TabHost
TabHost.TabSpec spec;
Intent intent = new Intent(TabLayoutExampleActivity.this, LinearLayout.class);
spec = tabHost.newTabSpec("linear layout").setIndicator("Linear", null).setContent(intent);
tabHost.addTab(spec); intent = new Intent(TabLayoutExampleActivity.this, TableLayout.class); spec = tabHost.newTabSpec("table layout").setIndicator("Table",null).setContent(intent); tabHost.addTab(spec);}Slide23
TabLayout
public class TabLayoutExampleActivity extends TabActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TabHost tabHost = getTabHost(); // The activity TabHost
TabHost.TabSpec spec;
Intent intent = new Intent(TabLayoutExampleActivity.this, LinearLayout.class);
spec = tabHost.newTabSpec("linear layout").setIndicator("Linear", null).setContent(intent);
tabHost.addTab(spec); intent = new Intent(TabLayoutExampleActivity.this, TableLayout.class);
spec = tabHost.newTabSpec("table layout").setIndicator("Table",null).setContent(intent);
tabHost.addTab(spec);
}
extend TabActivitySlide24
TabLayout
public class TabLayoutExampleActivity extends TabActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TabHost tabHost = getTabHost(); // The activity TabHost
TabHost.TabSpec spec;
Intent intent = new Intent(TabLayoutExampleActivity.this, LinearLayout.class);
spec = tabHost.newTabSpec("linear layout").setIndicator("Linear", null).setContent(intent);
tabHost.addTab(spec); intent = new Intent(TabLayoutExampleActivity.this, TableLayout.class);
spec = tabHost.newTabSpec("table layout").setIndicator("Table",null).setContent(intent);
tabHost.addTab(spec);
}
the XML file containing the TabHost, TabWidget, FrameLayoutSlide25
TabLayout
public class TabLayoutExampleActivity extends TabActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TabHost tabHost = getTabHost();
TabHost.TabSpec spec;
Intent intent = new Intent(TabLayoutExampleActivity.this, LinearLayout.class);
spec = tabHost.newTabSpec("linear layout").setIndicator("Linear", null).setContent(intent);
tabHost.addTab(spec); intent = new Intent(TabLayoutExampleActivity.this, TableLayout.class);
spec = tabHost.newTabSpec("table layout").setIndicator("Table",null).setContent(intent);
tabHost.addTab(spec);
}
Reference to the Activity's TabHost (which was defined in XML)Slide26
TabLayout
public class TabLayoutExampleActivity extends TabActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TabHost tabHost = getTabHost();
TabHost.TabSpec spec;
Intent intent = new Intent(TabLayoutExampleActivity.this, LinearLayout.class);
spec = tabHost.newTabSpec("linear layout").setIndicator("Linear", null).setContent(intent); tabHost.addTab(spec); intent = new Intent(TabLayoutExampleActivity.this, TableLayout.class);
spec = tabHost.newTabSpec("table layout").setIndicator("Table",null).setContent(intent);
tabHost.addTab(spec);
}
Reusable TabSpec for each Tab. Slide27
TabLayout
public class TabLayoutExampleActivity extends TabActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TabHost tabHost = getTabHost();
TabHost.TabSpec spec;
Intent intent = new Intent(TabLayoutExampleActivity.this, LinearLayout.class);
spec = tabHost.newTabSpec("linear layout").setIndicator("Linear", null).setContent(intent); tabHost.addTab(spec); intent = new Intent(TabLayoutExampleActivity.this, TableLayout.class);
spec = tabHost.newTabSpec("table layout").setIndicator("Table",null).setContent(intent);
tabHost.addTab(spec);
}
The TabSpec tells the TabHost what views represent the
tab contents and what the tab buttons should look like.Slide28
TabLayout
public class TabLayoutExampleActivity extends TabActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TabHost tabHost = getTabHost();
TabHost.TabSpec spec;
Intent intent = new Intent(TabLayoutExampleActivity.this, LinearLayout.class);
spec = tabHost.newTabSpec("linear layout").setIndicator("Linear", null).setContent(intent); tabHost.addTab(spec); Intent intent = new Intent(TabLayoutExampleActivity.this, TableLayout.class);
spec = tabHost.newTabSpec("table layout").setIndicator("Table",null).setContent(intent);
tabHost.addTab(spec);
}
Remember from the previous lecture, this is how we use an Intent object to start another ActivitySlide29
TabLayout
public class TabLayoutExampleActivity extends TabActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TabHost tabHost = getTabHost();
TabHost.TabSpec spec;
Intent intent = new Intent(TabLayoutExampleActivity.this, LinearLayout.class);
spec =
tabHost.newTabSpec("linear layout").setIndicator("Linear", null).setContent(intent); tabHost.addTab(spec); Intent intent = new Intent(TabLayoutExampleActivity.this, TableLayout.class);
spec = tabHost.newTabSpec("table layout").setIndicator("Table",null).setContent(intent);
tabHost.addTab(spec);
}
Refer to this TabActivity's tab host (which will contain the actual tabs)Slide30
TabLayout
public class TabLayoutExampleActivity extends TabActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TabHost tabHost = getTabHost();
TabHost.TabSpec spec;
Intent intent = new Intent(TabLayoutExampleActivity.this, LinearLayout.class);
spec = tabHost.
newTabSpec("linear layout").setIndicator("Linear", null).setContent(intent); tabHost.addTab(spec); Intent intent = new Intent(TabLayoutExampleActivity.this, TableLayout.class);
spec = tabHost.newTabSpec("table layout").setIndicator("Table",null).setContent(intent);
tabHost.addTab(spec);
}
Create a new tab spec, give it the id "linear layout"Slide31
TabLayout
public class TabLayoutExampleActivity extends TabActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TabHost tabHost = getTabHost();
TabHost.TabSpec spec;
Intent intent = new Intent(TabLayoutExampleActivity.this, LinearLayout.class);
spec = tabHost.newTabSpec("linear layout").
setIndicator("Linear", null).setContent(intent); tabHost.addTab(spec); Intent intent = new Intent(TabLayoutExampleActivity.this, TableLayout.class);
spec = tabHost.newTabSpec("table layout").setIndicator("Table",null).setContent(intent);
tabHost.addTab(spec);
}
Set the label for the tab (label the user sees) to "Linear". And Slide32
TabLayout
public class TabLayoutExampleActivity extends TabActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TabHost tabHost = getTabHost();
TabHost.TabSpec spec;
Intent intent = new Intent(TabLayoutExampleActivity.this, LinearLayout.class);
spec = tabHost.newTabSpec("linear layout").setIndicator("Linear"
, null).setContent(intent); tabHost.addTab(spec); Intent intent = new Intent(TabLayoutExampleActivity.this, TableLayout.class);
spec = tabHost.newTabSpec("table layout").setIndicator("Table",null).setContent(intent);
tabHost.addTab(spec);
}
We're not using an image for the tabs, so null for this argumentSlide33
TabLayout
public class TabLayoutExampleActivity extends TabActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TabHost tabHost = getTabHost();
TabHost.TabSpec spec;
Intent intent = new Intent(TabLayoutExampleActivity.this, LinearLayout.class);
spec = tabHost.newTabSpec("linear layout").setIndicator("Linear"
, null).setContent(intent); tabHost.addTab(spec); Intent intent = new Intent(TabLayoutExampleActivity.this, TableLayout.class);
spec = tabHost.newTabSpec("table layout").setIndicator("Table",null).setContent(intent);
tabHost.addTab(spec);
}
Fill the FrameLayout to hold the Activity specified by this intentSlide34
TabLayout
public class TabLayoutExampleActivity extends TabActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TabHost tabHost = getTabHost();
TabHost.TabSpec spec;
Intent intent = new Intent(TabLayoutExampleActivity.this, LinearLayout.class);
spec = tabHost.newTabSpec("linear layout").setIndicator("Linear"
, null).setContent(intent); tabHost.addTab(spec); Intent intent = new Intent(TabLayoutExampleActivity.this, TableLayout.class);
spec = tabHost.newTabSpec("table layout").setIndicator("Table",null).setContent(intent);
tabHost.addTab(spec);
}
Add the tab to the tabHost, it will now show up in the UISlide35
TabLayout
public class TabLayoutExampleActivity extends TabActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TabHost tabHost = getTabHost();
TabHost.TabSpec spec;
Intent intent = new Intent(TabLayoutExampleActivity.this, LinearLayout.class);
spec = tabHost.newTabSpec("linear layout").setIndicator("Linear"
, null).setContent(intent); tabHost.addTab(spec);
Intent intent = new Intent(TabLayoutExampleActivity.this, TableLayout.class);
spec = tabHost.newTabSpec("table layout").setIndicator("Table",null).setContent(intent);
tabHost.addTab(spec);
}
To add another tab, let's do this all over again! Slide36
TabLayout - Rules
TabHost must have the id
@android:id/tabhost
The TabWidget must have the id
@android:id/tabs
The FrameLayout must have the id @android:id/tabcontentSlide37
TabHost - useful methods
Slide38
Activity LifeCycle
During the life of an activity, the system calls a core set of lifecycle methods in a
sequence
.
Implementing
your activity lifecycle methods properly ensures your app behaves
gracefully
in
many
ways, including that it:
Does not crash if the user receives a phone call or switches to another app while using your app.
Does not consume valuable system resources when the user is not actively using it. Does not lose the user's progress if they leave your app and return to it at a later time. Slide39
Activity LifecycleA nice picture of activity lifecycle
http://developer.android.com/reference/android/app/Activity.htmlSlide40
Activity LifeCycle - onCreate()
Called when the activity is first created.
this is where you should do all of your normal static set up: create views, bind data to lists, etc.
provides you with a
Bundle
containing the activity's previously frozen state, if there was one.
always followed by
onStart()
.Slide41
Activity LifeCycle - onStart()
Slide42
Activity LifeCycle - onRestart()
Slide43
called
when the activity will start interacting with the user
at this point your activity is at the top of the activity stack, with user input going to it
Always followed by
onPause()
Activity LifeCycle - onResume()Slide44
called
when the system is about to start resuming a previous activity
this is typically used to
commit unsaved changes to persistent data, stop animations and other things that may be consuming CPU
, etc
implementations of this method must be very quick because the next activity will not be resumed until this method returns
followed by
onResume()
if the activity returns back to the front
onStop()
if it becomes invisible to the user.
Activity LifeCycle - onPause()Slide45
called when the activity is no longer visible to the user because another activity has been resumed and is covering this one
this may happen either because a new activity is being started, an existing one is being brought in front of this one, or this one is being destroyed
followed by
onRestart()
if this activity is coming back to interact with the user
onDestroy()
if this activity is going away
Activity LifeCycle - onStop()Slide46
the
final call you receive before your activity is destroyed
this can happen either because
the activity is finishing (someone called
finish
()
)
the system is temporarily destroying this instance of the activity
due to low memory
you can distinguish between these two scenarios with the
isFinishing() method
Activity LifeCycle - onDestroy()Slide47
Reading Assignment Please read page
0 – 710
by next class. Pay more attention on the section of Large-Screen Strategies and Tactics.
We are going to talk about Fragment next week. Slide48
Configuration Changes
In your app, you
can detect when the configuration of the device changes
screen orientation, keyboard availability, and language
In default, the
system will try to handle the changes for you, unless you specify that you want to handle them yourselfSlide49
Configuration Changes - Manifest
to specify
that,
you want to handle orientation and keyboard availability changes
by yourself
open the manifest file and add the bold line
<activity
android:configChanges="orientation|keyboardHidden"
android:name=".OnConfigurationChangedExampleActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity>Slide50
Configuration Changes - Manifest
T
his specifies one or more configuration changes that the activity will handle itself
when the orientation changes and when keyboard availability
changes.
<activity
android:configChanges="
orientation|keyboardHidden
"
android:name=".OnConfigurationChangedExampleActivity"
android:label="@string/app_name" >
<intent-filter><action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>Slide51
Configuration Changes - Event
Then, to react to the orientation change event, add this method to your Activity
@
Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
/* ... */
}
else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
/* ... */
}}Slide52
Passing Data between Activities
When you start Activity B from Activity A, you may want to send data to Activity B
Activity A
Activity B
startActivity B
send some data to B alsoSlide53
Passing Data between Activities
Activity A - onCreate()
Intent intent = new Intent(this,
SecondActivity.class);
Bundle bundle = new Bundle();
bundle.putString("fname","John");
bundle.putString("lname", "Doe");
bundle.putInt("age", 18);
intent.putExtras(bundle);
startActivity(intent);
Activity B - onCreate()
Intent intent = getIntent();Bundle bundle = intent.getExtras(); if(bundle != null) { edit1.setText(bundle.getString("fname"));
edit2.setText(bundle.getString("lname"));
int age= bundle.getInt("age");
}Slide54
Explicit Intent vs Implicit Intent
An Intent encapsulates a request, made to Android, for some activity or
other receiver
to do something
.
If the activity you intend to launch is
one of your own
, you may find it simplest
to create
an explicit
Intent.
new Intent(this, MyListViewActivity.class);You can also start up activities from the operating system or third-party apps using implicit intent
.
Implicit intent works a lot like the Web HTTP. Slide55
Implicit Intent
Implicit Intent
Action + URI (“data”)
these
are almost exactly analogous to HTTP
verbs (POST, GET)
and URLs —
the action
is the verb, and the “ data” is a Uri, such as http://commonsware.com
android.intent.action:
MAIN
MUSIC_PLAYERVIEWWEB_SEARCHSlide56
URIs
Uniform Resource
Identifier
that identifies an abstract or physical resource, as specified by
RFC 2396
.
The
URI
class can both parse URI strings into parts and compose URI strings from
parts.
There are 4 main parts to a URIScheme, port, host, and path
http://developer.android.com/reference/java/net/URI.htmlSlide57
URIs - Examples - Hierarchical
http://
mobile.cs.fsu.edu/android
http://twitter.com
file
:///tmp/android.txt
scheme
host
port
path
http
mobile.cs.fsu.edu
80
android
http
twitter.com
file
/tmp/android.txtSlide58
URIs - Examples - Opaque
mailto:robots.example.com
scheme
scheme-specific part
mailto
robots.example.comSlide59
URIs - Parsing URIs
URI uri = Uri.parse("http://www.google.com");
String scheme = uri.getScheme();
String host = uri.getHost();
int port = uri.getPort();
String path = uri.getPath();
String schemeSpecificPart = uri.getSchemeSpecificPart();Slide60
Intent Filters
To inform the system which implicit intents they can handle, activities, services, and broadcast receivers can have one or more intent
filters
each filter describes a capability of the component, a set of intents that the component is willing to receive
it filters in intents of a desired type, while filtering out unwanted intents — but only unwanted implicit intents (those that don't name a target class)Slide61
Intent Filters
Slide62
Intent Filters
Slide63
Intent Filters
How does Android know that you may want to open the YouTube app when you try to watch a video on YouTube?
Using Intent Filters
We will create an app that can be used to launch links at
http://mobile.cs.fsu.eduSlide64
Intent Filters
Slide65
Intent Filters
Slide66
Intent Filters
Slide67
Intent Filters
Slide68
Intent Filters
Slide69
Intent Filters
Slide70
Intent Filters
Slide71
References
The Busy Coder's Guide to Android Development - Mark Murphy
Android Developers
The Mobile Lab at Florida State University