2. UI
Overview
• All
UI
elements
are
either
View
or
ViewGroup
– View
=
Something
on
the
screen
(widget)
– ViewGroup
=
Container
for
other
Views
or
ViewGroups
• UI
is
a
combinaGon
of
Views
and
ViewGroups
• Most
effecGve
way
to
declare
UI
is
in
XML
– You
can,
however,
implement
everything
in
code
4. Why
Layouts?
• UI
is
built
on
top
of
layout
• Android
diverse
ecosystem
– Several
different
resoluGons
and
densiGes!
• Layout
helps
to
create
layout
for
different
screen
sizes
5. Common
Layouts
• LinearLayout
– Views
in
line,
either
verGcally
or
horizontally
• RelativeLayout
– Define
posiGons
of
each
other
child
view
relaGve
to
each
other
and
screen
boundaries
• TableLayout
– Rows
and
Columns
• FrameLayout
– FrameLayout
is
designed
to
display
a
single
item
at
a
Gme.
You
can
have
mulGple
elements
within
a
FrameLayout
but
each
element
will
be
posiGoned
based
on
the
top
leV
of
the
screen.
Elements
that
overlap
will
be
displayed
overlapping.
• AbsoluteLayout (Depricated)
– Use
coordinates
• And
others…
7. Width
and
Height
• Fixed
– 42dp,
17px,
etc
• Match
the
parent’s
size
– “As
big
as
my
parent”
– MATCH_PARENT
(in
older
version
FILL_PARENT)
• Best
fit
– “As
big
as
needed
for
my
content”
– WRAP_CONTENT
8. Defining
Layout
• Portrait
mode:
– res/layout/main.xml
• Landscape
mode:
– res/layout-land/main.xml
• Each
AcGvity
can
have
it's
own
layout
– setContentView(R.layout.main);
9. Example
of
Layout
<?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">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
</LinearLayout>
10. Common
Acributes
A)ribute
Descrip4on
Notes
layout_width
Specifies
the
width
of
the
View
or
ViewGroup
layout_height
Specifies
the
height
of
the
View
or
ViewGroup
layout_marginTop
Specifies
extra
space
on
the
top
side
of
the
View
or
ViewGroup
layout_marginBocom
Specifies
extra
space
on
the
bocom
side
of
the
View
or
ViewGroup
layout_marginLeV
Specifies
extra
space
on
the
leV
side
of
the
View
or
ViewGroup
layout_marginRight
Specifies
extra
space
on
the
right
side
of
the
View
or
ViewGroup
layout_gravity
Specifies
how
child
Views
are
posiGoned
Only
in
LinearLayout
or
TableLayout
layout_weight
Specifies
the
raGo
of
Views
Only
in
LinearLayout
or
TableLayout
11. Example
of
Layout
with
Gravity
and
Weight
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button A"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="0dip"
android:text="Button B"
android:layout_gravity="right"
android:layout_weight="0.5"
/>
<Button
android:layout_width="match_parent"
android:layout_height="0dip"
android:text="Button C"
android:layout_weight="0.5"
/>
</LinearLayout>
14. RelaGveLayout
• RelaGveLayout
lays
out
elements
based
on
their
relaGonships
with
one
another,
and
with
the
parent
container.
• It’s
possible
to
put
TextView
center
of
the
screen
and
other
Views
related
to
that
21. Styles
and
Themes
• Way
of
building
formaeng
and
layout
to
your
app
• Style
has
formaeng
acributes
to
several
elements
• Theme
has
formaeng
acributes
to
all
acGviGes
– Create
the
theme
in
xml
(styles.xml)
– Apply
the
theme
in
manifest
23. Some
Common
Widgets
• TextView
– Label
• EditText
– Editable
text
• ListView
– View
group
that
manages
a
group
of
Views.
• Spinner
– TextView
associated
with
ListView.
Let's
you
select
an
item
from
a
list.
• Button
– Standard
push
bucon
• CheckBox
– Standard
checkbox
• RadioButton
– Standard
radiobucon
• See
documentaGon
how
to
use
these!
28. About
Menus
• Common
UI
component
in
many
types
of
apps
– Beginning
from
Android
3.0
(API
Level
11)
android
devices
may
not
hold
a
dedicated
menu
–
buDon!
• Menus
are
in
ActionBar
• Hopefully
implemenGng
ActionBar
is
really
simple
and
99%
same
than
menus
• You
can
build
the
menus
using
Java
or
XML
• There
are
three
different
menu
types
1. OpGons
Menu
(AcGonBar)
2. Context
Menu
3. Popup
Menu
29. Menus?
• Android
no
longer
requires
Menu
bucon!
• Android
3.0
introduced
concept
of
AcGonBar
– No
need
for
physical
menu
bucon
• You
should
migrate
your
designs
away
from
using
the
Menu
bucon
• You
can
support
both
menu
and
acGonbar
30. AcGonBar
• AcGonBar
was
introduced
in
Android
3.0
but
also
available
for
2.1
using
Support
Library
• If
supporGng
only
API
level
11
and
higher
– import android.app.ActionBar
• If
supporGng
lower
than
11
– import android.support.v7.app.ActionBar
• You
must
set
up
a
appcombat
v7
support
library
for
lower
than
11
31. Menus
• Op4ons
menu
/
Ac4onBar
– Compact
menu
bocom
of
the
screen
or
acGon
bar
• Context
Menu
– Long
press
• Submenus
– Submenu
opens
in
a
new
window
32. CreaGng
Menus
in
Java
public class MenuExample extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
...
}
// Modify menu items dynamically. Disable/enable menuitems.
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
...
}
// Create your menu here
@Override
public boolean onCreateOptionsMenu(Menu menu) {
...
}
// When menuitem is selected
@Override
public boolean onOptionsItemSelected(MenuItem item) {
...
}
}
33. CreaGng
Menus
in
Java
public class MenuExample extends Activity {
// You can increment this for additional menuitems
static final private int MENU_ITEM1 = Menu.FIRST;
static final private int MENU_ITEM2 = Menu.FIRST + 1;
// Create your menu here
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
// Specify group value to separate Menu Items for batch processing and
// ordering. NONE = No group
int groupId = Menu.NONE;
// Unique identifier for each menu item (used for event handling)
int menuItemId1 = MENU_ITEM1;
int menuItemId2 = MENU_ITEM2;
// Order value. Menu.NONE = I don't care
int menuItemOrder = Menu.NONE;
// Menu Text
int menuItemText1 = R.string.menu_item1;
int menuItemText2 = R.string.menu_item2;
menu.add(groupId, menuItemId1, menuItemOrder, menuItemText1);
menu.add(groupId, menuItemId2, menuItemOrder, menuItemText2);
return true;
}
}
34. Event
Handling
in
Menus
public class MenuExample extends Activity {
static final private int MENU_ITEM1 = Menu.FIRST;
static final private int MENU_ITEM2 = Menu.FIRST + 1;
// Event Handling
@Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
switch (item.getItemId()) {
case (R.id.menu_item1):
// Do something
return true;
}
return false;
}
....
}
35. Changing
Menu
Dynamically
public class MenuExample extends Activity {
static final private int MENU_ITEM1 = Menu.FIRST;
static final private int MENU_ITEM2 = Menu.FIRST + 1;
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
MenuItem menuItem = menu.findItem(MENU_ITEM1);
menuItem.setEnabled(false);
return true;
}
....
}
37. Submenu
• A
sub
menu
can
be
added
within
any
menu
• Can
be
defined
in
XML
or
in
Java
• In
XML,
real
easy
<menu>
<item title="Reset" />
<item title="Sub menu">
<menu>
<item title="Example sub menu item" />
</menu>
</item>
</menu>
38. Opening
the
Menu
in
Java
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.mymenu, menu);
return true;
}
39. Context
Menu
• Context
Menu
=
Long
press
• Override
two
methods
on
a
AcGvity
– onCreateContextMenu()
– onContextItemSelected()
• Register
the
context
menu
to
the
view
– registerForContextMenu(view)
40. Example
public class MyContextMenu extends Activity {
private TextView tv;
@Override
public void onCreate(Bundle savedInstanceState) {
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
}
@Override
public boolean onContextItemSelected(MenuItem item) {
}
}
41. OnCreate
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
tv = new TextView(this);
tv.setText("Context Menu!");
registerForContextMenu(tv);
setContentView(tv);
}
47. Toast
• Simple
Feedback
about
an
operaGon
in
a
small
popup
– No
user
response
– Also
very
good
for
debugging
purposes!
48. How?
It's
simple…
Toast toast =
Toast.makeText(this, "Reset",
Toast.LENGTH_SHORT);
toast.show();
// in one line
Toast.makeText(this, "Reset",
Toast.LENGTH_SHORT).show();
49. Dialogs
• A
dialog
is
a
small
window
that
prompts
the
user
to
make
a
decision
or
enter
addiGonal
informaGon
50. Dialogs
• You
can
use
subclasses
of
Dialog:
– AlertDialog
• dialog
with
Gtle,
up
to
three
bucons,
a
list
of
selectable
items
or
a
custom
layout.
– DatePickerDialog
• Predefined
layout
– TimePickerDialog
• Predefined
layout
51. DialogFragment
• DialogFragment
class
helps
you
to
manage
correctly
lifecycle
events
such
as
back-‐bu)on
pressing
– Class
also
allows
reusing
of
dialog's
UI
as
an
embeddable
component
in
larger
UI
52. public void showDialog(View v) {
MyDialogFragment dialog = new MyDialogFragment();
// Tag is a unique name that the system uses to save and restore the
// fragment state when necessary. You can also get a reference to
// the fragment by calling findFragmentByTag()
dialog.show(getFragmentManager(), "fragmentTagName");
}
public static class MyDialogFragment extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage("What do you want to do?");
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
return builder.create();
}
}
53. Passing
Events
to
Host
AcGvity
public class MyDialogFragment extends DialogFragment {
public interface NoticeDialogListener {
public void onDialogPositiveClick(DialogFragment dialog);
public void onDialogNegativeClick(DialogFragment dialog);
}
private NoticeDialogListener host;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// My crash, use try .. catch
host = (NoticeDialogListener) activity;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage("What do you want to do?");
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
host.onDialogPositiveClick(MyDialogFragment.this);
}
});
54. Passing
Events
to
Host
AcGvity
public class MainActivity extends Activity implements
MyDialogFragment.NoticeDialogListener {
public void showDialog(View v) {
MyDialogFragment dialog = new MyDialogFragment();
// Tag is a unique name that the system uses to save and restore the
// fragment state when necessary. You can also get a reference to
// the fragment by calling findFragmentByTag()
dialog.show(getFragmentManager(), "fragmentTagName");
}
public void onDialogPositiveClick(DialogFragment dialog) {
this.setTitle("Ok");
}
public void onDialogNegativeClick(DialogFragment dialog) {
this.setTitle("Cancel");
}
55. To
Build
an
Alert
// 1. Instantiate an AlertDialog.Builder with its constructor
AlertDialog.Builder builder = new
AlertDialog.Builder(getActivity());
// 2. Chain together various setter methods to set the dialog
// characteristics
builder.setMessage(R.string.dialog_message)
.setTitle(R.string.dialog_title);
// 3. Get the AlertDialog from create()
AlertDialog dialog = builder.create();
56. List
Example
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.pick_color)
.setItems(R.array.colors_array, new
DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// The 'which' argument contains the index position
// of the selected item
}
});
return builder.create();
}
58. NoGficaGons
• Message
for
user
outside
of
your
app's
normal
UI
• NoGficaGon
shows
in
no4fica4on
area
• More
details
can
be
seen
when
user
opens
no4fica4on
drawer
59. Normal
View
• Normal
view
appears
in
area
up
to
64dp
tall
• Holds
1)
Content
Gtle,
2)
Large
icon,
3)
Content
text,
4)
Content
info,
5)
Small
icon,
6)
Time
noGficaGon
was
issued
60. Big
View
• Big
View
appears
when
noGficaGon
is
expanded
• Available
4.1
-‐>
• Difference:
7)
Details
area
61. The
Basics
• Specify
your
noficaGon
using
NotificationCompat.Builder
object
• Use
NotificationCompat.Builder.build()
for
building
the
noGficaGon
object
• call
notify() when
needed
• NoGficaGon
must
contain:
1)
small
icon,
2)
Gtle
and
3)
detail
text
• Service
can
launch
status
bar
no4fica4on!
62. Building
the
NoGficaGon
// Building the notification
Notification.Builder mBuilder =
new Notification.Builder(this);
// Drag icon.png to drawable/ folder
// Small icon, content title and text are minimum.
mBuilder.setSmallIcon(R.drawable.icon);
mBuilder.setContentTitle("Notification Title");
mBuilder.setContentText("Notification Text");
// You should create also a pending intent
// createPendingIntent is a method that you have to implement.
// PendingIntent pi = createPendingIntent();
// mBuilder.setContentIntent(pi);
Notification notification = mBuilder.build();
// Displaying the notification using notification manager
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(this.NOTIFICATION_SERVICE);
int mId = 1;
// mId allows you to update the notification later on.
mNotificationManager.notify(mId , notification);
63. NoGficaGon
AcGons
• Although
opGonal,
you
should
provide
one
acGon
to
noGficaGon
– Allows
user
to
go
to
your
app
from
the
noGficaGon
– StarGng
an
acGvity
when
the
user
clicks
the
noGficaGon
is
the
most
common
scenario
• NoGficaGonManager
is
different
app
from
your
app
and
it
needs
special
permissions
to
open
your
acGvity.
– Instead
of
using
Intent,
you
use
PendingIntent.
• See:
hcp://developer.android.com/guide/topics/
ui/noGfiers/noGficaGons.html
65. Basic
Approach
• CreaGng
custom
views
is
really
easy:
1. Extend
exiGng
View
–
class
2. Override
some
of
the
View
–
classes
methods
• onDraw(), onMeasure(), onKeyDown() ..
3. Use
your
class
in
XML
–
layout
file
66. class MyCustomWidget extends View {
// You will get here information implemented in the xml – file
// This is mandatory
public MyCustomWidget(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// How to draw? Paint. Where to draw? Canvas
// It would be wise to initialize the Paint one time instead
// of every draw iteration
Paint p = new Paint();
p.setTextSize(20);
p.setColor(0xFFFF0000);
p.setAntiAlias(true);
canvas.drawText("Hello World", 0, 20, p);
}
}
68. Define
own
Custom
Acributes
• You
can
define
your
own
custom
acributes
• Create
custom
acribute
in
values/acrs.xml
• Add
the
acribute
to
the
view
in
layout.xml
• Read
the
acribute
in
View's
constructor