Lecture 6 - Florida State University

Download Report

Transcript Lecture 6 - Florida State University

Mobile
Programming
Lecture 6
Fragments, Permissions,
BroadcastReceivers
Agenda
•
Dynamic UI
•
LayoutInflater
•
Fragments
•
Permissions
•
BroadcastReceiver
Building the UI Dynamically
So far we've been creating UIs that are defined
before runtime
There are some cases where you will need to
build the UI dynamically
Consider this XML layout file
Building the UI Dynamically
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium" />
</TableRow>
<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</TableRow>
</TableLayout>
Building the UI Dynamically
Now let's look at Java code that can build a
similar UI at runtime
Building the UI Dynamically
<TableLayout
android:layout_width="match_parent"
public void onCreate(Bundle state) {
super.onCreate(savedInstanceState);
android:layout_height="match_parent" >
<TableRow
TableLayout layout = new TableLayout(this);
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
TableRow row = new TableRow(this);
<TextView
android:layout_width="wrap_content"
TextView tv = new TextView(this);
android:layout_height="wrap_content"
tv.setText("Medium Text");
android:text="Medium Text"/>
</TableRow>
row.addView(tv);
<TableRow
layout.addView(row);
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
row = new TableRow(this);
</TableRow>
layout.addView(row);
</TableLayout>
setContentView(layout);
}
Building the UI Dynamically
<TableLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
This argument asks for a Context,
e.g.
public void onCreate(Bundle
state) {
this or getApplicationContext()
super.onCreate(savedInstanceState);
<TableRow
TableLayout layout = new TableLayout(this);
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
TableRow row = new TableRow(this);
<TextView
android:layout_width="wrap_content"
TextView tv = new TextView(this);
android:layout_height="wrap_content"
tv.setText("Medium Text");
android:text="Medium Text"/>
</TableRow>
row.addView(tv);
<TableRow
layout.addView(row);
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
row = new TableRow(this);
</TableRow>
layout.addView(row);
</TableLayout>
setContentView(layout);
}
Building the UI Dynamically
<TableLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
"this" refers to the instance of
whichever class
the{ code is currently
public void onCreate(Bundle
state)
in!
super.onCreate(savedInstanceState);
<TableRow
TableLayout layout = new TableLayout(this);
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
TableRow row = new TableRow(this);
<TextView
android:layout_width="wrap_content"
TextView tv = new TextView(this);
android:layout_height="wrap_content"
tv.setText("Medium Text");
android:text="Medium Text"/>
</TableRow>
row.addView(tv);
<TableRow
layout.addView(row);
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
row = new TableRow(this);
</TableRow>
layout.addView(row);
</TableLayout>
setContentView(layout);
}
Building the UI Dynamically
<TableLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
In this case, it would refer to your
Activity (sincestate)
you know
that
public void onCreate(Bundle
{
onCreate() is a method of an Activity)
super.onCreate(savedInstanceState);
<TableRow
TableLayout layout = new TableLayout(this);
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
TableRow row = new TableRow(this);
<TextView
android:layout_width="wrap_content"
TextView tv = new TextView(this);
android:layout_height="wrap_content"
tv.setText("Medium Text");
android:text="Medium Text"/>
</TableRow>
row.addView(tv);
<TableRow
layout.addView(row);
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
row = new TableRow(this);
</TableRow>
layout.addView(row);
</TableLayout>
setContentView(layout);
}
Building the UI Dynamically
You can't add the same child element twice!
This is an easy way to get a Force Close
LayoutInflater
•
•
instantiates a layout XML file into its
corresponding View objects
use getLayoutInflater()
LayoutInflater
@Override
@Override
public void onCreate(Bundle state) {
public void onCreate(Bundle state) {
super.onCreate(savedInstanceState);
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LayoutInflater inflater =
getLayoutInflater();
}
setContentView(
inflater.inflate(R.layout.main, null));
}
LayoutInflater
@Override
@Override
public void onCreate(Bundle state) {
public void onCreate(Bundle state) {
super.onCreate(savedInstanceState);
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LayoutInflater inflater =
getLayoutInflater();
}
setContentView(
inflater.inflate(R.layout.main, null));
}
Gives you the same
result
LayoutInflater
@Override
@Override
public void onCreate(Bundle state) {
public void onCreate(Bundle state) {
super.onCreate(savedInstanceState);
super.onCreate(savedInstanceState);
Second
argument
is of
LayoutInflater
inflater
=
type ViewGroup
getLayoutInflater();
setContentView(R.layout.main);
}
setContentView(
inflater.inflate(R.layout.main, null));
}
LayoutInflater
@Override
@Override
public void onCreate(Bundle state) {
public void onCreate(Bundle state) {
super.onCreate(savedInstanceState);
super.onCreate(savedInstanceState);
Use it if you want to
LayoutInflater
inflater
= argument
embed
the first
into the second argument
getLayoutInflater();
setContentView(R.layout.main);
}
setContentView(
inflater.inflate(R.layout.main, null));
}
Fragments
Fragments
•
•
•
•
A Fragment represents a behavior or a portion of user
interface in an Activity.
Add multiple fragments to a screen to avoid switching
activities
Fragments have their own lifecycle, state, and back
stack
Fragments require API Level 11 or greater
Fragments - Lifecycle
A fragment must always be embedded in an
activity and the fragment's lifecycle is directly
affected by the host activity's lifecycle.
• http://developer.android.com/guide/compone
nts/fragments.html
onCreateView() is the one we'll be focusing on for now ...
Fragments - Steps for Creating One
1. You must create a subclass of Fragment
1.
Fragment, ListFragment, etc
2. You must implement onCreateView()
1. onCreateView() must return a View
i.e. @Override public View onCreateView( /* required args */)
Fragments - onCreateView()
There are two ways to return a view in your
implementation of onCreateView()
Fragments - onCreateView()
1. Use the LayoutInflater argument to
instantiate a predefined layout XML file
e.g.
public class MyFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
state)
{
return inflater.inflate(R.layout.example_fragment, container, false);
}
}
Fragments - onCreateView()
1. Use the LayoutInflater argument to
instantiate a predefined layout XML file
extend Fragment, not
Activity
e.g.
public class MyFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
state)
{
return inflater.inflate(R.layout.example_fragment, container, false);
}
}
Fragments - onCreateView()
1. Use the LayoutInflater argument to
instantiate a predefined layout XML file
e.g.
The
XML layout
file
public class MyFragment extends
Fragment
{
to instantiate
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
state)
{
return inflater.inflate(R.layout.example_fragment, container, false);
}
}
Fragments - onCreateView()
1. Use the LayoutInflater argument to
instantiate a predefined layout XML file
e.g.
public class MyFragment extends Fragment {
The ViewGroup to
insert it into
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
state)
{
return inflater.inflate(R.layout.example_fragment, container, false);
}
}
Fragments - onCreateView()
1. Use the LayoutInflater argument to
instantiate a predefined layout XML file
e.g.
public class MyFragment extends Fragment {
Passing true would
create a redundant
ViewGroup, so pass false
for now
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
state)
{
return inflater.inflate(R.layout.example_fragment, container, false);
}
}
Fragments - onCreateView()
2. Build a UI dynamically and return the root
View
public class MyFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
state)
{
ScrollView scroller = new ScrollView(getActivity());
TextView text = new TextView(getActivity());
scroller.addView(text);
text.setText("Sample Text");
return scroller;
}
}
Fragments - onCreateView()
2. Build a UI dynamically and return the root
View
public class MyFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
state)
You've seen most
of this before!
{
ScrollView scroller = new ScrollView(getActivity());
TextView text = new TextView(getActivity());
scroller.addView(text);
text.setText("Sample Text");
return scroller;
}
}
Fragments - onCreateView()
2. Build a UI dynamically and return the root
View
public class MyFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
Last time we used the
state)
keyword this to get the
{
Context
ScrollView scroller = new ScrollView(getActivity());
TextView text = new TextView(getActivity());
scroller.addView(text);
text.setText("Sample Text");
return scroller;
}
}
Fragments - onCreateView()
2. Build a UI dynamically and return the root
View
public class MyFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
Since we're in a
state)
Fragment here, and not
{
an Activity ...
ScrollView scroller = new ScrollView(getActivity());
TextView text = new TextView(getActivity());
scroller.addView(text);
text.setText("Sample Text");
return scroller;
}
}
Fragments - onCreateView()
2. Build a UI dynamically and return the root
View
public class MyFragment extends Fragment {
public View onCreateView(LayoutInflater
inflater,
ViewGroup container, Bundle
We can get
the
controlling Activity from
state)
within the Fragment
{
using getActivity()
ScrollView scroller = new ScrollView(getActivity());
TextView text = new TextView(getActivity());
scroller.addView(text);
text.setText("Sample Text");
return scroller;
}
}
Fragments - onCreateView()
2. Build a UI dynamically and return the root
View
public class MyFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
This is how we get the Context.
state)
Alternatively, we can say
{
getActivity().getApplicationContext()
ScrollView scroller = new ScrollView(getActivity());
TextView text = new TextView(getActivity());
scroller.addView(text);
text.setText("Sample Text");
return scroller;
}
}
Fragments - Adding a Fragment
There are 2 ways to add a Fragment
Fragments - Adding a Fragment
1. Declare the Fragment inside of the Activity's layout file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment android:name="edu.fsu.cs.mobile.example.MyFragment"
android:id="@+id/list"
android:tag="list_fragment"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<fragment android:name="edu.fsu.cs.mobile.example.MyOtherFragment"
android:id="@+id/viewer"
android:tag="viewer_fragment"
android:layout_weight="2"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Fragments - Adding a Fragment
1. Declare the Fragment inside of the Activity's layout file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
<fragment>
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment android:name="edu.fsu.cs.mobile.example.MyFragment"
android:id="@+id/list"
android:tag="list_fragment"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<fragment android:name="edu.fsu.cs.mobile.example.MyOtherFragment"
android:id="@+id/viewer"
android:tag="viewer_fragment"
android:layout_weight="2"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Fragments - Adding a Fragment
1. Declare the Fragment inside of the Activity's layout file
<?xml version="1.0" encoding="utf-8"?>
absolute reference to
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
your Fragment class,
android:orientation="horizontal"
which includes the
android:layout_width="match_parent"package name
android:layout_height="match_parent">
<fragment android:name="edu.fsu.cs.mobile.example.MyFragment"
android:id="@+id/list"
android:tag="list_fragment"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<fragment android:name="edu.fsu.cs.mobile.example.MyOtherFragment"
android:id="@+id/viewer"
android:tag="viewer_fragment"
android:layout_weight="2"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Fragments - Adding a Fragment
1. Declare the Fragment inside of the Activity's layout file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
Fragment id
<fragment android:name="edu.fsu.cs.mobile.example.MyFragment"
android:id="@+id/list"
android:tag="list_fragment"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<fragment android:name="edu.fsu.cs.mobile.example.MyOtherFragment"
android:id="@+id/viewer"
android:tag="viewer_fragment"
android:layout_weight="2"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Fragments - Adding a Fragment
1. Declare the Fragment inside of the Activity's layout file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment android:name="edu.fsu.cs.mobile.example.MyFragment"
Fragment TAG
android:id="@+id/list"
android:tag="list_fragment"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<fragment android:name="edu.fsu.cs.mobile.example.MyOtherFragment"
android:id="@+id/viewer"
android:tag="viewer_fragment"
android:layout_weight="2"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Fragments - Adding a Fragment
1. Declare the Fragment inside of the Activity's layout file
This works because you return a View object in your
onCreateView() method for the specified Fragment
The View then gets embedded into the UI
Fragments - Adding a Fragment
2. Programmatically add the Fragment to an existing ViewGroup
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
Use a FrameLayout as
a container
for your
android:layout_width="fill_parent"
Fragment
android:layout_height="wrap_content" />
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
</LinearLayout>
Fragments - Adding a Fragment
2. Programmatically add the Fragment to an existing ViewGroup
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
Remember the id of the
android:layout_height="wrap_content"
container ... />
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
</LinearLayout>
Fragments - Adding a Fragment
2. Programmatically add the Fragment to an existing ViewGroup
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
</LinearLayout>
This is main.xml layout file
Fragments - Adding a Fragment
2. Programmatically add the Fragment to an existing ViewGroup
public class MyActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
FragmentManager manager = getFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
MyFragment fragment = new MyFragment();
trans.add(R.id.fragment_container, fragment, "my_fragment");
trans.commit();
}
}
Fragments - Adding a Fragment
2. Programmatically add the Fragment to an existing ViewGroup
public class MyActivity extends Activity {
@Override
This XML layout file
public void onCreate(Bundle
savedInstanceState)
{
contains the
FrameLayout
container
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
FragmentManager manager = getFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
MyFragment fragment = new MyFragment();
trans.add(R.id.fragment_container, fragment, "my_fragment");
trans.commit();
}
}
Fragments - Adding a Fragment
2. Programmatically add the Fragment to an existing ViewGroup
public class MyActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FragmentManager allows you
to interact with Fragments that
setContentView(R.layout.main);
are in an Activity
FragmentManager manager = getFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
MyFragment fragment = new MyFragment();
trans.add(R.id.fragment_container, fragment, "my_fragment");
trans.commit();
}
}
Fragments - Adding a Fragment
2. Programmatically add the Fragment to an existing ViewGroup
public class MyActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
FragmentTransaction allows you to
perform operations on Fragments
(add, remove, replace)
FragmentManager manager = getFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
MyFragment fragment = new MyFragment();
trans.add(R.id.fragment_container, fragment, "my_fragment");
trans.commit();
}
}
Fragments - Adding a Fragment
2. Programmatically add the Fragment to an existing ViewGroup
public class MyActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Our Fragment doesn't exist at
this point (was not specified in
FragmentManager
= getFragmentManager();
XML), let's createmanager
an instance
of it
FragmentTransaction
trans = manager.beginTransaction();
MyFragment fragment = new MyFragment();
trans.add(R.id.fragment_container, fragment, "my_fragment");
trans.commit();
}
}
Fragments - Adding a Fragment
2. Programmatically add the Fragment to an existing ViewGroup
public class MyActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
FragmentManager manager = getFragmentManager();
Add our Fragment to the
FragmentTransaction
FrameLayout
containertrans = manager.beginTransaction();
MyFragment fragment = new MyFragment();
trans.add(R.id.fragment_container, fragment, "my_fragment");
trans.commit();
}
}
Fragments - Adding a Fragment
2. Programmatically add the Fragment to an existing ViewGroup
public class MyActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
The unique TAG for your
FragmentManager manager = getFragmentManager();
Fragment, so that you can
FragmentTransaction trans = manager.beginTransaction();
reference it later
MyFragment fragment = new MyFragment();
trans.add(R.id.fragment_container, fragment, "my_fragment");
trans.commit();
}
}
Fragments - Adding a Fragment
2. Programmatically add the Fragment to an existing ViewGroup
public class MyActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
FragmentManager manager = getFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
Update
the UI fragment = new MyFragment();
MyFragment
trans.add(R.id.fragment_container, fragment, "my_fragment");
trans.commit();
}
}
Fragments - Passing data to
You will often want to pass data from your Activity to your Fragment. You can
do this several ways. From within the Activity ...
public class MyActivity extends Activity {
@Override
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
setContentView(R.layout.main);
MyFragment fragment = new MyFragment();
fragment.my_custom_field = value;
fragment.setMyCustomField(value);
FragmentManager manager = getFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
trans.add(R.id.fragment_container, fragment, "my_fragment");
trans.commit();
}
}
Fragments - Passing data to
You will often want to pass data from your Activity to your Fragment. You can
do this several ways. From within the Activity ...
Fragments - Passing data to
You will often want to pass data from your Activity to your Fragment. You can
do this several ways. From within the Activity ...
public class MyActivity extends Activity {
@Override
public void onCreate(Bundle savedInstance) {
You will need to have my_custom_field as
super.onCreate(savedInstance);
a public field in your Fragment, and
setContentView(R.layout.main);
setMyCustomField() as a public method
MyFragment fragment = new MyFragment();
fragment.my_custom_field = value;
fragment.setMyCustomField(value);
FragmentManager manager = getFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
trans.add(R.id.fragment_container, fragment, "my_fragment");
trans.commit();
}
}
Fragments - Passing data to
Alternatively, you can use Fragments setArguments(Bundle) and
getArguments() methods.
Fragments - Passing data to
Alternatively, you can use Fragments setArguments(Bundle) and
getArguments() methods.
public class MyActivity extends Activity {
@Override
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
setContentView(R.layout.main);
MyFragment fragment = new MyFragment();
Bundle extras = new Bundle();
extras.putInt("selected",15);
fragment.setArguments(extras);
FragmentManager manager = getFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
trans.add(R.id.fragment_container, fragment, "my_fragment");
trans.commit();
}
}
Fragments - Passing data to
Alternatively, you can use Fragments setArguments(Bundle) and
getArguments() methods.
public class MyActivity extends Activity {
@Override
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
You've seen
Bundle before!
setContentView(R.layout.main);
MyFragment fragment = new MyFragment();
Bundle extras = new Bundle();
extras.putInt("selected",15);
fragment.setArguments(extras);
FragmentManager manager = getFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
trans.add(R.id.fragment_container, fragment, "my_fragment");
trans.commit();
}
}
Fragments - Passing data to
Alternatively, you can use Fragments setArguments(Bundle) and
getArguments() methods.
public class MyActivity extends Activity {
@Override
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
setContentView(R.layout.main);
setArguments() takes a
Bundle as fragment
an argument.
MyFragment
= new MyFragment();
This is a standard
Fragment method
Bundle extras = new Bundle();
extras.putInt("selected",15);
fragment.setArguments(extras);
FragmentManager manager = getFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
trans.add(R.id.fragment_container, fragment, "my_fragment");
trans.commit();
}
}
Fragments - Passing data to
Then, in your Fragment, you can get the arguments using getArguments()
Fragments - Passing data to
Then, in your Fragment, you can get the arguments using getArguments()
public class MyFragment extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state) {
Bundle args = getArguments();
...
return new TextView(getActivity());
}
@Override
public void onActivityCreated(Bundle state) {
super.onActivityCreated(state);
Bundle args = getArguments();
}
}
Fragments - Passing data to
Then, in your Fragment, you can get the arguments using getArguments()
public class MyFragment extends Fragment{
@Override
Bundle args and Bundle
state are two separate
Bundles. Ignore Bundle state
for now
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state) {
Bundle args = getArguments();
...
return new TextView(getActivity());
}
@Override
public void onActivityCreated(Bundle state) {
super.onActivityCreated(state);
Bundle args = getArguments();
}
}
Fragments - Passing data to
Then, in your Fragment, you can get the arguments using getArguments()
public class MyFragment extends Fragment{
@Override
get the arguments that were
passed by the Activity
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state) {
Bundle args = getArguments();
...
return new TextView(getActivity());
}
@Override
public void onActivityCreated(Bundle state) {
super.onActivityCreated(state);
Bundle args = getArguments();
}
}
Fragments - Passing data to
Then, in your Fragment, you can get the arguments using getArguments()
public class MyFragment extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state) {
onCreateView must return a
Bundle args =
getArguments();
View
...
return new TextView(getActivity());
}
@Override
public void onActivityCreated(Bundle state) {
super.onActivityCreated(state);
Bundle args = getArguments();
}
}
Fragments - Passing data to
Then, in your Fragment, you can get the arguments using getArguments()
public class MyFragment extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state) {
Bundle args = getArguments();
...
return new TextView(getActivity());
You may need to get the
arguments at this point in the
Lifecycle instead
}
@Override
public void onActivityCreated(Bundle state) {
super.onActivityCreated(state);
Bundle args = getArguments();
}
}
Fragments - Passing data to
Then, in your Fragment, you can get the arguments using getArguments()
public class MyFragment extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state) {
Bundle args = getArguments();
...
return new TextView(getActivity());
This is usually if you extended
ListFragment instead
}
@Override
public void onActivityCreated(Bundle state) {
super.onActivityCreated(state);
Bundle args = getArguments();
}
}
Fragments - How to Reference
•
•
•
•
A Fragment is not a View!
You can't call findViewById() in order to reference a Fragment within an
Activity
use getFragmentManager().findFragmentById() or
getFragmentManager().findFragmentByTag() instead
of course, an instance of your Fragment Manager needs to already be a
part of your Activity
FragmentManager manager = getFragmentManager();
MyFragment fragment = (MyFragment) manager.findFragmentById(R.id.fragment_id);
MyFragment fragment = (MyFragment) manager.findFragmentByTag("my_fragment");
Fragments - Removing a Fragment
You can also remove Fragments from the UI
Fragments - Removing a Fragment
You can also replace one Fragment with another
public class MyActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
FragmentManager manager = getFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
MyFragment fragment = manager.findFragmentById(R.id.my_fragment);
trans.remove(fragment);
trans.commit();
}
}
Fragments - Removing a Fragment
You can also replace one Fragment with another
public class MyActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
You can only remove it if it was
added somehow. This gets a
FragmentManager
manager
= getFragmentManager();
reference to
a Fragment
that
was already added.
FragmentTransaction trans = manager.beginTransaction();
MyFragment fragment = manager.findFragmentById(R.id.my_fragment);
trans.remove(fragment);
trans.commit();
}
}
Fragments - Removing a Fragment
You can also replace one Fragment with another
public class MyActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
FragmentManager manager = getFragmentManager();
Remove the Fragment from
FragmentTransaction
trans = manager.beginTransaction();
this Activity
MyFragment fragment = manager.findFragmentById(R.id.my_fragment);
trans.remove(fragment);
trans.commit();
}
}
Fragments - Replacing a Fragment
You can replace a Fragment by removing an existing
Fragment and adding an new one. But an easier way to
do this is to call replace() instead
Fragments - Replacing a Fragment
You can also replace Fragments
public class MyActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
FragmentManager manager = getFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
MyFragment fragment = new MyFragment();
trans.replace(R.id.fragment_container, fragment);
trans.commit();
}
}
Fragments - Replacing a Fragment
You can also replace Fragments
public class MyActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Reference the Fragment (if you
don't already have a reference
FragmentManager manager = getFragmentManager();
to it)
FragmentTransaction trans = manager.beginTransaction();
MyFragment fragment = new MyFragment();
trans.replace(R.id.fragment_container, fragment);
trans.commit();
}
}
Fragments - Replacing a Fragment
You can also replace Fragments
public class MyActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
FragmentManager manager = getFragmentManager();
Remove Fragment from the
FragmentTransaction
trans = manager.beginTransaction();
Activity
MyFragment fragment = new MyFragment();
trans.replace(R.id.fragment_container, fragment);
trans.commit();
}
}
Fragments - Reference the Activity
•
You can reference the controlling Activity from within
the Fragment
e.g, in the onCreateView() method of the Fragment class:
View listView = getActivity().findViewById(R.id.list);
Permissions
•
no application, by default, has
permission to perform any
operations that would adversely
impact
o other applications
o the operating system
o the user
•
How does the system know that
this app uses these
permissions?
Using Permissions
Permissions requested by your application must be specified in the Android
Manifest file.
For example, here we request permission to access the Internet
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.app.myapp" >
<uses-permission android:name="android.permission.INTERNET" />
...
</manifest>
How to Request Permissions
Your app doesn't request to use any permissions by default
To request to use a permission
1. Open AndroidManifest.xml
2. Click the Permissions tab at the bottom of the Editor
3. Click Add ...
4. Select Uses Permission
5. Select the permission you want to request from the drop-down list
6. Save AndroidManifest.xml
Permissions - WebView Example
A WebView is a View that allows you to load
and display web page content to the user
Permissions - WebView Example
@Override
public void onCreate(Bundle savedInstanceState) {
Of course, this is in
our XML layout file
somewhere
WebView webview = (WebView) findViewById(R.id.webView1);
webview.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
});
webview.loadUrl("http://www.google.com");
}
Permissions - WebView Example
@Override
public
voidofonCreate(Bundle
This block
code prevents the savedInstanceState) {
system from
opening webview
the URL in= (WebView) findViewById(R.id.webView1);
WebView
the default browser
webview.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
});
webview.loadUrl("http://www.google.com");
}
Permissions - WebView Example
@Override
public void onCreate(Bundle savedInstanceState) {
WebView webview = (WebView) findViewById(R.id.webView1);
webview.setWebViewClient(new
WebViewClient() {
It has to return false, in order to
load the URL in our webview
@Override
instead of the default browser
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
});
webview.loadUrl("http://www.google.com");
}
Permissions - WebView Example
@Override
public void onCreate(Bundle savedInstanceState) {
WebView webview = (WebView) findViewById(R.id.webView1);
webview.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
The WebView will not load the
false;
URL if return
you don't
have INTERNET
permissions!, i.e.
}
}); android.permissions.INTERNET
webview.loadUrl("http://www.google.com");
}
Permissions
There are many more permissions that can be
used
You can find a list of them here
Android Application Components
1. Activity
1.
Broadcast Receiver
1. Content Provider
1. Service
Broadcast Receiver
•
•
•
—component that responds to system wide
a
broadcast announcements
o —
Incoming SMS, MMS, Email, phone call
o Battery low, Screen has turned off, or a picture was
captured.
think of a Broadcast receiver as a “gateway” to the
—
other components.
intended to very little work
o Depending on the incoming event to the receiver, it
could start a Service or Activity.
Broadcast Receiver
To add a new Broadcast Receiver
•
•
•
•
•
•
•
open the AndroidManifest.xml file
click on the Application tab at the bottom of the window
under the Application Nodes section, click Add ...
select Receiver
in the Attributes for Receiver section, click on the
Name* link
Enter the name of your Broadcast Receiver
o e.g. "MyBroadcastReceiver"
Finish
Broadcast Receiver - Manifest File
If you view AndroidManifest.xml in the XML editor, you
should see something like this
<receiver
android:name="MyBroadcastReceiver"></receiver>
Broadcast Receiver
Your new Broadcast Receiver file should look something like this
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
}
}
Broadcast Receiver
public class
Event listener for when
MyBroadcastReceiver
a broadcast has been
received.
extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
}
}
Broadcast Receiver
How do you know which
public class MyBroadcastReceiver
broadcasts to listen for? extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
}
}
Registering BroadcastReceiver
There are two ways to register a BroadcastReceiver to
listen for a broadcast
1 . Adding an <intent-filter> to the Manifest file
2. Programmatically
Registering BroadcastReceiver
1. To add an <intent-filter> to the Manifest and listen for a
Broadcast ...
1. Open AndroidManifest.xml and click on the Application Tab at the bottom
of the Window
2. Select your BroadcastReceiver
3. Click Add ...
4. Make sure "Create new element in the selected element ... " is selected,
then choose Intent Filter
5. Click Add ...
6. Choose Action
7. Select the appropriate permission in the Name drop-down list
a. e.g. android.intent.action.TIME_SET
8. Save AndroidManifest.xml
Registering BroadcastReceiver
Alternatively, if you view AndroidManifest.xml in the XML
editor, you should see something like this
<receiver android:name="MyBroadcastReceiver">
</receiver>
Registering BroadcastReceiver
We need to tell the system which broadcast(s) we want to
listen for. First we need to add an <intent-filter> tag
<receiver android:name="MyBroadcastReceiver">
</receiver>
Registering BroadcastReceiver
We need to tell the system which broadcast(s) we want to
listen for. First we need to add an <intent-filter> tag
Place the cursor here
and press
Ctrl + Space
<receiver android:name="MyBroadcastReceiver">
</receiver>
Registering BroadcastReceiver
We need to tell the system which broadcast(s) we want to
listen for. First we need to add an <intent-filter> tag
Select <intent-filter>
<receiver android:name="MyBroadcastReceiver">
</receiver>
Registering BroadcastReceiver
We need to tell the system which broadcast(s) we want to
listen for. First we need to add an <intent-filter> tag
<receiver android:name="MyBroadcastReceiver">
<intent-filter>
</intent-filter>
</receiver>
Registering BroadcastReceiver
We need to tell the system which broadcast(s) we want to
listen for. First we need to add an <intent-filter> tag
an <intent-filter>
<receiver
android:name="MyBroadcastReceiver">
describes what
this
receiver should listen for
<intent-filter>
</intent-filter>
</receiver>
Registering BroadcastReceiver
We need to tell the system which broadcast(s) we want to
listen for. First we need to add an <intent-filter> tag
Place the cursor here
<receiver
and press android:name="MyBroadcastReceiver">
Ctrl + Space
<intent-filter>
</intent-filter>
</receiver>
Registering BroadcastReceiver
We need to tell the system which broadcast(s) we want to
listen for. First we need to add an <intent-filter> tag
<receiver
android:name="MyBroadcastReceiver">
Select <action/>
<intent-filter>
</intent-filter>
</receiver>
Registering BroadcastReceiver
We need to tell the system which broadcast(s) we want to
listen for. First we need to add an <intent-filter> tag
<receiver
Press Ctrl + Space
android:name="MyBroadcastReceiver">
again
<intent-filter>
<action
</intent-filter>
</receiver>
/>
Registering BroadcastReceiver
We need to tell the system which broadcast(s) we want to
listen for. First we need to add an <intent-filter> tag
Select android:name
<receiver android:name="MyBroadcastReceiver">
<intent-filter>
<action
</intent-filter>
</receiver>
/>
Registering BroadcastReceiver
We need to tell the system which broadcast(s) we want to
listen for. First we need to add an <intent-filter> tag
Let's try receiving a
broadcast for when the
<receiver android:name="MyBroadcastReceiver">
screen has been turned
on
<intent-filter>
<action android:name=" "/>
</intent-filter>
</receiver>
Registering BroadcastReceiver
We need to tell the system which broadcast(s) we want to
listen for. First we need to add an <intent-filter> tag
Press Ctrl + Space
<receiver android:name="MyBroadcastReceiver">
again
<intent-filter>
<action android:name=" "/>
</intent-filter>
</receiver>
Registering BroadcastReceiver
We need to tell the system which broadcast(s) we want to
listen for. First we need to add an <intent-filter> tag
Select android.intent.action.TIME_SET
<receiver android:name="MyBroadcastReceiver">
<intent-filter>
<action android:name=" "/>
</intent-filter>
</receiver>
Registering BroadcastReceiver
We need to tell the system which broadcast(s) we want to
listen for. First we need to add an <intent-filter> tag
<receiver android:name="MyBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.TIME_SET"/>
</intent-filter>
</receiver>
Registering BroadcastReceiver
We need to tell the system which broadcast(s) we want to
listen for. First we need to add an <intent-filter> tag
<receiver android:name="MyBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.TIME_SET"/>
</intent-filter>
</receiver>
Registering BroadcastReceiver
2. To register a BroadcastReceiver programmatically ...
Registering BroadcastReceiver
public class MainActivity extends Activity {
MyBroadcastReceiver receiver;
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
receiver = new MyBroadcastReceiver();
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
registerReceiver(receiver, filter);
}
}
Registering BroadcastReceiver
public class MainActivity extends Activity {
MyBroadcastReceiver receiver;
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Create a new instance
setContentView(R.layout.main);
of your receiver
receiver = new MyBroadcastReceiver();
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
registerReceiver(receiver, filter);
}
}
Registering BroadcastReceiver
public class MainActivity extends Activity {
MyBroadcastReceiver receiver;
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Create an intent filter
receiver = new MyBroadcastReceiver();
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
registerReceiver(receiver, filter);
}
}
Registering BroadcastReceiver
public class MainActivity extends Activity {
MyBroadcastReceiver receiver;
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
receiver = new MyBroadcastReceiver();
The receiver is now
IntentFilter
filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
registered
registerReceiver(receiver, filter);
}
}
BroadcastReceiver - onReceive()
Now let's look at our
BroadcastReceiver
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent myIntent = new Intent(context, ActivityToBeLaunched.class);
Toast.makeText(
context,
"Broadcast Received!",
Toast.LENGTH_LONG).show();
myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(myIntent);
}
}
BroadcastReceiver - onReceive()
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public
At this point, the
void
onReceive(Context
broadcast
has been
received
context, Intent intent) {
Intent myIntent = new Intent(context,
ActivityToBeLaunched.class);
Toast.makeText(
context,
"Broadcast Received!",
Toast.LENGTH_LONG).show();
myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(myIntent);
}
BroadcastReceiver - onReceive()
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
Let's say we want to
launch a new Activity
public void
onReceive(Context context, Intent intent) {
when we receive the
broadcast
Intent myIntent = new Intent(context,
ActivityToBeLaunched.class);
Toast.makeText(
context,
"Broadcast Received!",
Toast.LENGTH_LONG).show();
myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(myIntent);
}
BroadcastReceiver - onReceive()
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
And we
want to show
a
Intent
myIntent
= new
Intent(context, ActivityToBeLaunched.class);
Toast
Toast.makeText(
context,
"Broadcast Received!",
Toast.LENGTH_LONG).show();
myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(myIntent);
}
}
BroadcastReceiver - onReceive()
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent myIntent = new Intent(context, ActivityToBeLaunched.class);
Toast.makeText(
context,
"Broadcast Received!",
You need to add flags
Toast.LENGTH_LONG).show();
to your intent
this time
myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(myIntent);
}
}
BroadcastReceiver - onReceive()
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent myIntent = new Intent(context, ActivityToBeLaunched.class);
Toast.makeText(
context,
"BroadcastCalling
Received!",
startActivity() from outside of
an Activity context requires the
Toast.LENGTH_LONG).show();
FLAG_ACTIVITY_NEW_TASK flag
myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(myIntent);
}
}
Unregistering BroadcastReceiver
Sometimes after you start listening for a Broadcast, you
may want to STOP listening for it at some point
To UNregister a BroadcastReceiver programmatically ...
Unregistering BroadcastReceiver
public class MainActivity extends Activity {
@Override
public void onPause() {
unregisterReceiver(receiver);
super.onPause();
}
}
Unregistering BroadcastReceiver
public class MainActivity extends Activity {
You will want to unregister before
@Override
calling a super.onSomething()
method,
you may
public
voidotherwise
onPause()
{ get
Force Close
unregisterReceiver(receiver);
super.onPause();
}
}
Unregistering BroadcastReceiver
If you register a BroadcastReceiver
programmatically, you should unregister
it before your Activity is destroyed!
otherwise you will have a "leaked" receiver
Please call unregisterReceiver in
•
•
onPause()
o onStop()
o or onDestroy()
o
This is important
Code Examples
•
•
•
•
•
•
•
•
•
BroadcastReceiverExample
SimpleFragmentUsingXml
SimpleFragmentProgrammatically
FragmentActivityReferenceExample
FragmentTransitionExample
LayoutInflaterExample
PermissionsExample
ComplexFragmentsExample
DynamicUiExample
References
•
The Busy Coder's Guide to Android
Development - Mark Murphy
•
Android Developers
•
The Mobile Lab at Florida State University
•
Code Examples