8/16/2019 Listas Android
1/62
Using lists in Android (ListView) -Tutorial
Lars Vogel
Version 4.7
Copyright © 2010-2015 vogella GmbH
29.09.2015
Using lists in Android with ListView and ListFragment
This tutorial describes how to use the ListView view together with activities and fragments in
Android. The tutorial is based on Android 5.0.
Table of Contents
1. Using lists in Android2. Android and the ListView widget
2.1. Views for handling lists2.2. Possible inut t!es for lists2.". Adaters2.#. Filtering and sorting2.$. %ata udates in the adater 2.&. Listener
". %efault adater ".1. %efault latform adater ".2. Using Arra!Adater ".". ListView e'amle with Arra!Adater
#. ustom adater imlementations#.1. %eeloing a *ustom adater #.2. Prearing a row for the list#.". +'amle for a *ustom adater #.#. Udating the data model from the adater
$. ListA*tiit! and ListFragment$.1. %efault *ontainer for using ListView
http://www.vogella.com/tutorials/AndroidListView/article.html#androidlists_overviewhttp://www.vogella.com/tutorials/AndroidListView/article.html#androidlistshttp://www.vogella.com/tutorials/AndroidListView/article.html#androidlists_viewhttp://www.vogella.com/tutorials/AndroidListView/article.html#androidlists_inputtypehttp://www.vogella.com/tutorials/AndroidListView/article.html#androidlists_adapterintrohttp://www.vogella.com/tutorials/AndroidListView/article.html#androidlists_filtersorthttp://www.vogella.com/tutorials/AndroidListView/article.html#adapterown_updateshttp://www.vogella.com/tutorials/AndroidListView/article.html#listview_adapterlistenerhttp://www.vogella.com/tutorials/AndroidListView/article.html#listview_defaultadapterhttp://www.vogella.com/tutorials/AndroidListView/article.html#listview_defaultadapterhttp://www.vogella.com/tutorials/AndroidListView/article.html#arrayAdapterhttp://www.vogella.com/tutorials/AndroidListView/article.html#listview_listviewexamplehttp://www.vogella.com/tutorials/AndroidListView/article.html#adapterownhttp://www.vogella.com/tutorials/AndroidListView/article.html#adapterown_customhttp://www.vogella.com/tutorials/AndroidListView/article.html#adapterown_inflatinghttp://www.vogella.com/tutorials/AndroidListView/article.html#adapterown_examplehttp://www.vogella.com/tutorials/AndroidListView/article.html#adapterown_interactionhttp://www.vogella.com/tutorials/AndroidListView/article.html#listactivityhttp://www.vogella.com/tutorials/AndroidListView/article.html#listactivity_overviewhttp://www.vogella.com/tutorials/AndroidListView/article.html#androidlistshttp://www.vogella.com/tutorials/AndroidListView/article.html#androidlists_viewhttp://www.vogella.com/tutorials/AndroidListView/article.html#androidlists_inputtypehttp://www.vogella.com/tutorials/AndroidListView/article.html#androidlists_adapterintrohttp://www.vogella.com/tutorials/AndroidListView/article.html#androidlists_filtersorthttp://www.vogella.com/tutorials/AndroidListView/article.html#adapterown_updateshttp://www.vogella.com/tutorials/AndroidListView/article.html#listview_adapterlistenerhttp://www.vogella.com/tutorials/AndroidListView/article.html#listview_defaultadapterhttp://www.vogella.com/tutorials/AndroidListView/article.html#listview_defaultadapterhttp://www.vogella.com/tutorials/AndroidListView/article.html#arrayAdapterhttp://www.vogella.com/tutorials/AndroidListView/article.html#listview_listviewexamplehttp://www.vogella.com/tutorials/AndroidListView/article.html#adapterownhttp://www.vogella.com/tutorials/AndroidListView/article.html#adapterown_customhttp://www.vogella.com/tutorials/AndroidListView/article.html#adapterown_inflatinghttp://www.vogella.com/tutorials/AndroidListView/article.html#adapterown_examplehttp://www.vogella.com/tutorials/AndroidListView/article.html#adapterown_interactionhttp://www.vogella.com/tutorials/AndroidListView/article.html#listactivityhttp://www.vogella.com/tutorials/AndroidListView/article.html#listactivity_overviewhttp://www.vogella.com/tutorials/AndroidListView/article.html#androidlists_overview
8/16/2019 Listas Android
2/62
$.2. ListA*tiit! and *ustom la!out$.". Pla*eholder for an emt! list
&. +'er*ise, Using ListView and ListA*tiit!. +'er*ise, ListA*tiit! with *ustom la!out. Tutorial, /mlementing !our *ustomer adater
0. ListViews and erforman*e0.1. otiation0.2. Time *onsuming oerations0.". Aoiding la!out inflation and obe*t *reation0.#. View holder attern0.$. +'amle
13. 4toring the sele*tion of a iew11. onte'tual a*tion mode for ListViews12. /mlementing undo for an a*tion
12.1. 5hen should !ou offer an undo a*tion612.2. +'amle
1". Performan*e 7timi8ation1#. Tutorial, 9ow to disla! two items in a ListView1$. 4ele*ting multile items in the ListView
1$.1. /ntera*tion between the model and Listiew1$.2. Tutorial, %omain odel and list iew rows intera*tion
1&. /mlementing an e'andable ListView1&.1. +'andableListView1&.2. +'andableListView e'amle
1. Tutorial, is*ellaneous1.1. Adding a long*li*: listener to the list items1.2. 9eader and footer
1. 4imleursorAdater 10. Additional 7en 4our*e libraries23. About this website21. Lin:s and Literature
21.1. ListView ;esour*es21.2. ogella
8/16/2019 Listas Android
3/62
Typically the user interacts with the list via the toolbar, for example, via a button which
refreshes the list. Individual list items can be selected. This selection can update the toolbar
or can trigger a detailed screen for the selection. The following graphic sketches that. On
the selection of a list item another activity is started.
2. Android and the ListView widget
2.1. Views for handling lists
Android provides theListView and theExpandableListView classes which is capable of
displaying a scrollable list of items. TheExpandableListView class supports a grouping of
items.
2.2. Possible inut t!es for lists
The input to the list (items in the list) can be arbitrary Java objects. The adapter extracts the
correct data from the data object and assigns this data to theviews in the row of
theListView.
These items are typically called thedata model of the list. An adapter can receive data as
input.
2.". Adaters
Anadapter manages the data model and adapts it to the individual entries in the widget. An
adapter extends theBaseAdapterclass.
Every line in the widget displaying the data consists of a layout which can be as complex as
you want. A typical line in a list has an image on the left side and two text lines in the middle
as depicted in the following graphic.
A layout file for a such a line might look like the following.
8/16/2019 Listas Android
4/62
8/16/2019 Listas Android
5/62
android:layout#ali%n'arent.op="true"
android:layout#ali%n6ith'arent($7issin%="true"
android:layout#toRi%ht0$=",id/ion"
android:%ravity="enter#vertial" android:text="Example appliation"
android:text4i2e="5*sp" /+
8/16/2019 Listas Android
6/62
listView!set0n(tem;liListener8new 0n(tem;liListener89
@Override
public void on(tem;li8AdapterView.)#L0>9
!show89?
@
@9?
". %efault adater
".1. %efault latform adater
Android provides default adapter implementations; the most important
areArrayAdapter and;ursorAdapter.ArrayAdaptercan handle data based
onArrays orava!util!List.4imple;ursorAdapter can handle database related
data.
".2. Using Arra!Adater
TheArrayAdapter class can handle a list or array of Java objects as input. Every Java
object is mapped to one row. By default, it maps theto4trin%89 method of the object to aview in the row layout.
You can define the ID of the view in the constructor of theArrayAdapter otherwise
theandroid!R!id!text5 ID is used as default.
TheArrayAdapter class allows to remove all elements in its underlying data structure with
thelear89 method call. You can then add new elements via theadd89 method or
a;olletion via theaddAll89 method.
You can also directly modify the underlying data structure and callthenoti$yata4et;han%ed89 method on the adapter to notify it about the changes in
data.
5arning
8/16/2019 Listas Android
7/62
If you want to change the data in your adapter, the underlying data structure must support this
operation. This is, for example, the case for theArrayList class, but not for arrays.
".". ListView e'amle with Arra!Adater
The following listing shows a layout file
calledactivity_listviewexampleactivity.xml which includes aListView.
8/16/2019 Listas Android
8/62
for 8int i = G? i < values!len%th? --i9
list!add8valuesiC9?
@
final 4tableArrayAdapter adapter = new 4tableArrayAdapter8this android!R!layout!simple#list#item#5 list9?
listview!setAdapter8adapter9?
listview!set0n(tem;liListener8new
AdapterView!0n(tem;liListener89
@Override
public void on(tem;li8AdapterView
8/16/2019 Listas Android
9/62
List
8/16/2019 Listas Android
10/62
Frequently you extendArrayAdapter to write a custom adapter, as this is simpler than
extendingBaseAdapter directly.
#.2. Prearing a row for the list
The adapter needs to create a layout for each row of the list. TheListView instance calls
the%etView89 method on the adapter for each data element. In this method the adapter
creates the row layout and maps the data to the views in the layout.
This root of the layout is typically aViewroup (layout manager) and contains several other
views , e.g., an(ma%eView and a.extView. The following graphic shows a list with
different layouts for odd and even rows.
Within the%etView89 method you would inflate an XML based layout and then set the
content of the individual views based on the Java object for this row. To inflate the XML
layout file, you can use theLayout(n$lator system service.
=ote
This layout inflator service can get accessed via the%etLayout(n$lator89 method of the
activity or via
theontext!%et4ystem4ervie8;ontext!LAH0D.#(>ILA.ER#4ERV(;E9 method call.
After the adapter inflated the layout, it searches for the relevant views in the layout and fills
them with the data. The individual elements in the layout can be found via
the$indViewBy(d89 method call on the top level view.
8/16/2019 Listas Android
11/62
#.". +'amle for a *ustom adater
The following code shows an implementation of a custom adapter. This adapter assumes
that you have two png files (no.png and ok.png) in one of yourres/drawable folders. The
coding inflates an XML layout file, finds the relevant views in the layout and sets their
content based on the input data.
package de!vo%ella!android!listativity?
import android!ontent!;ontext?
import android!view!Layout(n$later?
import android!view!View?
import android!view!Viewroup?
import android!wid%et!ArrayAdapter?
import android!wid%et!(ma%eView?
import android!wid%et!.extView?
public class 7y4impleArrayAdapter extends ArrayAdapterILA.ER#4ERV(;E9?
View rowView = in$later!in$late8R!layout!rowlayout parent $alse9?
.extView textView = 8.extView9 rowView!$indViewBy(d8R!id!label9?
(ma%eView ima%eView = 8(ma%eView9 rowView!$indViewBy(d8R!id!ion9?
8/16/2019 Listas Android
12/62
textView!set.ext8valuespositionC9?
// change the icon for Windows and iPhone
4trin% s = valuespositionC?
if 8s!starts6ith8"i'hone"99 ima%eView!set(ma%eResoure8R!drawable!no9?
@ else
ima%eView!set(ma%eResoure8R!drawable!o9?
@
return rowView?
@
@
#.#. Udating the data model from the adater
The row can also containviews which interact with the underlying data model via the
adapter. For example, you can have a;hebox in your row layout and if the;hebox is
selected, the underlying data is changed.
$. ListA*tiit! and ListFragment
$.1. %efault *ontainer for using ListView
Android provides specialized fragment and activity classes to simplify list handling.
The classes are theListAtivity class if you want to use lists in activities and
theListIra%ment class if you want to use lists in fragments.
You do not have to assign a layout to these elements. If you do not define a layout, the
activity or fragment contains a singleListView by
default.ListAtivity andListIra%ment also allow you to override
aonList(tem;li89 method for handling selection of list items.
Both classes allow you to set the adapter to the defaultListView via
thesetListAdapter89 method.
The following example code shows a simpleListIra%ment implementation.
8/16/2019 Listas Android
13/62
package de!vo%ella!android!$ra%ments?
import android!ontent!(ntent?
import android!os!Bundle?import android!view!View?
import android!wid%et!ArrayAdapter?
import android!wid%et!ListView?
import android!app!ListIra%ment?
public class 7yListIra%ment extends ListIra%ment
@Override
public void onAtivity;reated8Bundle saved(nstane4tate9
super!onAtivity;reated8saved(nstane4tate9?
4trin%C values = new 4trin%C "Android" "i'hone"
"6indows7obile"
"Blaberry" "6eb04" "Dbuntu" "6indows" "7ax 04 F"
"Linux" "04/1" @?
ArrayAdapter
8/16/2019 Listas Android
14/62
package de!vo%ella!android!listativity?
import android!app!ListAtivity?
import android!os!Bundle?import android!wid%et!ArrayAdapter?
public class 7yListAtivity extends ListAtivity
public void on;reate8Bundle iile9
super!on;reate8iile9?
4trin%C values = new 4trin%C "Android" "i'hone"
"6indows7obile"
"Blaberry" "6eb04" "Dbuntu" "6indows" "7ax 04 F"
"Linux" "04/1" @?
ArrayAdapter
8/16/2019 Listas Android
15/62
If you do not use this ID or do not include aListView into your layout, the application crashes
once you try to display the activity or the fragment.
$.". Pla*eholder for an emt! list
You can also use a view with the,android:id/empty ID in your layout. The
corresponding activity and fragment shows this view automatically if theListView is empty
and hides it otherwise. For example, you could display an error message in such a view.
&. +'er*ise, Using ListView andListA*tiit!
The following exercise demonstrates how to use aListView in anListAtivity. You use
the predefinedArrayAdapter class and an existing Android layout for the rows.
Create a new Android project calledde.vogella.android.listactivity with the activity
called7yListAtivity.
Change7yListAtivity class based on the following code example. Note that
theset;ontentView89 method is not used.
package de!vo%ella!android!listativity?
import android!app!ListAtivity?
import android!os!Bundle?
import android!view!View?
import android!wid%et!ArrayAdapter?
import android!wid%et!ListView?
import android!wid%et!.oast?
public class 7yListAtivity extends ListAtivity
public void on;reate8Bundle iile9 super!on;reate8iile9?
4trin%C values = new 4trin%C "Android" "i'hone"
"6indows7obile"
"Blaberry" "6eb04" "Dbuntu" "6indows" "7ax 04 F"
"Linux" "04/1" @?
8/16/2019 Listas Android
16/62
ArrayAdapter9!show89?
@
@
8/16/2019 Listas Android
17/62
. +'er*ise, ListA*tiit! with *ustomla!out
In our example your will define your layout for the rows and use it in your adapter.
Create therowlayot.xml layout file in theres/layot folder of
thede!vo%ella!android!listativity project.
8/16/2019 Listas Android
18/62
package de!vo%ella!android!listativity?
import android!app!ListAtivity?
import android!os!Bundle?import android!view!View?
import android!wid%et!ArrayAdapter?
import android!wid%et!ListView?
import android!wid%et!.oast?
public class 7yListAtivity extends ListAtivity
public void on;reate8Bundle iile9
super!on;reate8iile9?
4trin%C values = new 4trin%C "Android" "i'hone"
"6indows7obile"
"Blaberry" "6eb04" "Dbuntu" "6indows" "7ax 04 F"
"Linux" "04/1" @?
// se yor cstom layot
ArrayAdapter9!show89?
@
@
8/16/2019 Listas Android
19/62
. Tutorial, /mlementing !our *ustomeradater
The following uses two images "no.png" and "ok.png". I placed it in the "res/drawable-mdpi"
folder. You must create your own icons. In case you do not find any icons just copy
"icon.png" and use a drawing program to change it a little bit.
Create the class7y4impleArrayAdapter which will serve as our adapter.
package de!vo%ella!android!listativity?
import android!ontent!;ontext?
import android!view!Layout(n$later?
import android!view!View?
8/16/2019 Listas Android
20/62
import android!view!Viewroup?
import android!wid%et!ArrayAdapter?
import android!wid%et!(ma%eView?
import android!wid%et!.extView?
public class 7y4impleArrayAdapter extends ArrayAdapterILA.ER#4ERV(;E9?
View rowView = in$later!in$late8R!layout!rowlayout parent $alse9? .extView textView = 8.extView9 rowView!$indViewBy(d8R!id!label9?
(ma%eView ima%eView = 8(ma%eView9 rowView!$indViewBy(d8R!id!ion9?
textView!set.ext8valuespositionC9?
// !hange the icon for Windows and iPhone
4trin% s = valuespositionC?
if 8s!starts6ith8"6indows"9 MM s!starts6ith8"i'hone"9
MM s!starts6ith8"4olaris"99
ima%eView!set(ma%eResoure8R!drawable!no9?
@ else
ima%eView!set(ma%eResoure8R!drawable!o9?
@
return rowView?
8/16/2019 Listas Android
21/62
@
@
To use this adapter, change theactivity to the following.
package de!vo%ella!android!listativity?
import android!app!ListAtivity?
import android!os!Bundle?
public class 7yListAtivity extends ListAtivity
public void on;reate8Bundle iile9
super!on;reate8iile9?
4trin%C values = new 4trin%C "Android" "i'hone"
"6indows7obile"
"Blaberry" "6eb04" "Dbuntu" "6indows" "7ax 04 F"
"Linux" "04/1" @?
7y4impleArrayAdapter adapter = new 7y4impleArrayAdapter8this
values9?
setListAdapter8adapter9?
@
@
If you run this example you should get a list with different icons for the certain elements.
8/16/2019 Listas Android
22/62
0. ListViews and erforman*e0.1. otiation
Performance is especially important on Android as users expect fast reaction times.
Compared to desktop computers an Android device is relatively slow from the hardware
perspective.
This part describes how to reduce these operations to implement your custom list adapter
efficiently. The default Android adapters likeArrayAdapter are already performance
optimized.
0.2. Time *onsuming oerations
Every view which get inflated from an XML layout file will result in a Java object. Inflating
layouts and creating Java objects is expensive with regards to time and memory
consumption.
8/16/2019 Listas Android
23/62
In addition using the$indViewBy(d89 method is relatively time consuming, even though it
is not as bad as XML inflating.
0.". Aoiding la!out inflation and obe*t *reation
AListView typically contains more data than the number of displayed rows. If the user
scrolls the list, then rows and their associated views are being scrolled out of the visible
area. The Java objects which represents the rows can be reused for newly visible rows.
If Android determines that a row is not visible anymore, it allows the%etView89 of the
adapter method to reuse the associated view via theonvertView parameter.
The adapter can assign new data to the views contained in the view hierarchy of
theonvertView. This avoids inflating an XML file and creating new Java objects.
In case Android cannot reuse a row, the Android system passesnull totheonvertView parameter. Therefore the adapter implementation needs to check for this.
0.#. View holder attern
AViewHolder implementation allows to avoid the$indViewBy(d89 method in an adapter.
AView)older class is typically a static inner class in your adapter which holds references
to the relevant views. in your layout. This reference is assigned to the row view as a tag via
theset.a%89 method.
If we receive aonvertView object, we can get the instance of theView)older via
the%et.a%89 method and assign the new attributes to the views via
theView)older reference.
While this sounds complex this is approximately 15 % faster then using
the$indViewBy(d89 method.
0.$. +'amle
The following code shows a performance optimized adapter implementation which reuses
existing views and implements the holder pattern.
package de!vo%ella!android!listativity?
import android!app!Ativity?
8/16/2019 Listas Android
24/62
import android!view!Layout(n$later?
import android!view!View?
import android!view!Viewroup?
import android!wid%et!ArrayAdapter?import android!wid%et!(ma%eView?
import android!wid%et!.extView?
public class 7y'er$ormaneArrayAdapter extends ArrayAdapter
8/16/2019 Listas Android
25/62
view)older!ima%e = 8(ma%eView9 rowView
!$indViewBy(d8R!id!(ma%eViewG59?
rowView!set.a%8view)older9?
@
// fill data
View)older holder = 8View)older9 rowView!%et.a%89?
4trin% s = namespositionC?
holder!text!set.ext8s9?
if 8s!starts6ith8"6indows"9 MM s!starts6ith8"i'hone"9
MM s!starts6ith8"4olaris"99
holder!ima%e!set(ma%eResoure8R!drawable!no9?
@ else
holder!ima%e!set(ma%eResoure8R!drawable!o9?
@
return rowView?
@
@
13. 4toring the sele*tion of a iewBy default aListView has no selection mode active. You can activate it via
theset;hoie7ode89 method call. PassListView!;)0(;E#70E#7DL.('LE for multiple
selections orListView!;)0(;E#70E#4(>LE for single selections to this method.
To get the selected items of aListView, use the%et;heed(tem'osition89 for a
single selection method orlistView!%et;heed(tem'ositions89 for multiple
selections. . If you have stable ID, you could also use the%et;heed(tem(ds89 method to
get the selected IDs.
Android already provides a default layout for this:
theandroid!R!layout!simple#list#item#multiple#hoie layout which contains a
configured;heed.extView view.
The following activities demonstrate how to use these selection modes. If you use these
modes, theListView stores the selected values. It is not persisted in your data model.
8/16/2019 Listas Android
26/62
package om!vo%ella!android!listview!seletion!multi?
import android!app!ListAtivity?
import android!os!Bundle?import android!view!7enu?
import android!view!7enu(tem?
import android!wid%et!ArrayAdapter?
import android!wid%et!ListView?
import android!wid%et!.oast?
import om!vo%ella!android!listview!seletion!R?
public class 7ainAtivity extends ListAtivity
@Override
protected void on;reate8Bundle saved(nstane4tate9
super!on;reate8saved(nstane4tate9?
4trin%C values = new 4trin%C "a" "b" "" "d" "e" "$" "%"
"h" "i" "" "" "l" "m" "n" "o" "p" "3" "r" "s"
"t" "u" "w" "x" "y" "2" @?
ArrayAdapter
8/16/2019 Listas Android
27/62
public boolean on0ptions(tem4eleted87enu(tem item9
.oast!mae.ext8this
4trin%!value0$8%etListView89!%et;heed(tem;ount899
.oast!LE>.)#L0>9!show89? return true?
@
@
package om!vo%ella!android!listview!seletion!sin%le?
import android!app!ListAtivity?
import android!os!Bundle?
import android!view!7enu?
import android!view!7enu(tem?
import android!wid%et!ArrayAdapter?
import android!wid%et!ListView?
import android!wid%et!.oast?
public class 7ainAtivity extends ListAtivity
@Override protected void on;reate8Bundle saved(nstane4tate9
super!on;reate8saved(nstane4tate9?
4trin%C values = new 4trin%C "a" "b" "" "d" "e" "$" "%"
"h" "i" "" "" "l" "m" "n" "o" "p" "3" "r" "s"
"t" "u" "w" "x" "y" "2" @?
ArrayAdapter
8/16/2019 Listas Android
28/62
public boolean on;reate0ptions7enu87enu menu9
%et7enu(n$later89!in$late8R!menu!main menu9?
return true?
@
@Override
public boolean on0ptions(tem4eleted87enu(tem item9
.oast!mae.ext8this
4trin%!value0$8%etListView89!%et;heed(tem;ount899
.oast!LE>.)#L0>9!show89?
return true?
@
@
11. onte'tual a*tion mode for ListViews
The following assumes that you already familiar with the concept of the ActionBar and
contextual action mode in general. This part will explain how to use contextual action mode
for aListView selection.
To assign a contextual action mode to a long click on an individual item, use the
methodset0n(temLon%;liListener89 onListView. This methods includesinformation about the selected item. In this method you can start theAtion7ode.
The following examples demonstrate that. It assumes that you have a menu XML file
defined calledrowselection.xml and that this menu contains one entry with
the@"id/menitem#_show ID.
package de!vo%ella!android!listativity?
import android!app!ListAtivity?import android!os!Bundle?
import android!view!Ation7ode?
import android!view!7enu?
import android!view!7enu(n$later?
import android!view!7enu(tem?
8/16/2019 Listas Android
29/62
import android!view!View?
import android!wid%et!AdapterView?
import android!wid%et!AdapterView!0n(temLon%;liListener?
import android!wid%et!.oast?
public class 7yListAtivityAtionbar extends ListAtivity
implements Ation7ode!;allba
protected 0bet mAtion7ode?
public int seleted(tem = J5?
@Override
public void on;reate8Bundle iile9
super!on;reate8iile9?
4trin%C values = new 4trin%C "Android"
"i'hone" "6indows7obile"
"Blaberry" "6eb04" "Dbuntu"
"6indows" "7ax 04 F" "Linux" "04/1"
"Dbuntu" "6indows" "7ax 04 F"
"Linux" "04/1" "Dbuntu"
"6indows" "7ax 04 F""Linux" "04/1" @?
7y4impleArrayAdapter adapter = new 7y4impleArrayAdapter8this
values9?
setListAdapter8adapter9?
%etListView89!set0n(temLon%;liListener8new
0n(temLon%;liListener89
@Override
public boolean on(temLon%;li8AdapterView
8/16/2019 Listas Android
30/62
if 8mAtion7ode N= null9
return $alse?
@
seleted(tem = position?
// $tart the !%& sing the %ction'ode.!allbac( defined above
mAtion7ode =
7yListAtivityAtionbar!this!startAtion7ode87yListAtivityAtionbar!th
is9?
view!set4eleted8true9?
return true?
@
@9?
@
private void show89
.oast!mae.ext87yListAtivityAtionbar!this
4trin%!value0$8seleted(tem9 .oast!LE>.)#L0>9!show89?
@
// !alled when the action mode is created) start%ction'ode*+ wascalled
@Override
public boolean on;reateAtion7ode8Ation7ode mode 7enu menu9
// ,nflate a men resorce providing context men items
7enu(n$later in$later = mode!%et7enu(n$later89?
// %ssmes that yo have -contexal.xml- men resorces
in$later!in$late8R!menu!rowseletion menu9?
return true?
@
// !alled each time the action mode is shown. %lways called after
// on!reate%ction'ode bt
// may be called mltiple times if the mode is invalidated.
8/16/2019 Listas Android
31/62
@Override
public boolean on'repareAtion7ode8Ation7ode mode 7enu menu9
return $alse? // etrn false if nothing is done
@
// !alled when the ser selects a contextal men item
@Override
public boolean onAtion(tem;lied8Ation7ode mode 7enu(tem item9
switch 8item!%et(tem(d899
case R!id!menuitem5#show:
show89?
// %ction pic(ed so close the !%&
mode!$inish89?
return true?
default:
return $alse?
@
@
// !alled when the ser exits the action mode
@Override public void onestroyAtion7ode8Ation7ode mode9
mAtion7ode = null?
seleted(tem = J5?
@
@
If you start your application and long press on an item in the list, you get your contextual
action bar.
8/16/2019 Listas Android
32/62
12. /mlementing undo for an a*tion
12.1. 5hen should !ou offer an undo a*tion6
It is good practice to allow the user to undo critical actions. Such a critical action is, for
example, the deletion of list items.
A proven pattern to handle this undo option is to offer a selection at the end of the screen.
This selection vanishes after a predefined time or once the user continues to interact with
the application.
For example, the Gmail application implements such a behavior.
12.2. +'amle
8/16/2019 Listas Android
33/62
The following description contains an example for implementing an undo action. It uses an
animation to phase out the undo button automatically out after a while.
For this example create a new project calledcom.vogella.android.userinterface.undo based
on theBlankTemplate template.
Create the following layout for youractivity. It uses aIrameLayout to show two different
parts of the user interface. The button bar is initially hidden. The button uses a drawable.
Either add such a drawable to your project or remove the reference.
8/16/2019 Listas Android
34/62
android:divider'addin%="55dp"
android:paddin%="dp" +
8/16/2019 Listas Android
35/62
import android!view!7enu?
import android!view!7enu(tem?
import android!view!View?
import android!wid%et!ArrayAdapter?import android!wid%et!ListView?
import android!wid%et!.oast?
import om!vo%ella!android!ationbar!undo!R?
public class 7ainAtivity extends Ativity
private View view;ontainer?
@Override
protected void on;reate8Bundle saved(nstane4tate9
super!on;reate8saved(nstane4tate9?
set;ontentView8R!layout!ativity#main9?
ListView l = 8ListView9 $indViewBy(d8R!id!listview9?
4trin%C values = new 4trin%C "Dbuntu" "Android" "i'hone"
"6indows" "Dbuntu" "Android" "i'hone" "6indows" @?
ArrayAdapter
8/16/2019 Listas Android
36/62
@Override
public boolean on0ptions(tem4eleted87enu(tem item9
showDndo8view;ontainer9?
return true? @
public void on;li8View view9
.oast!mae.ext8this "eletion undone" .oast!LE>.)#L0>9!show89?
view;ontainer!setVisibility8View!0>E9?
@
public static void showDndo8final View view;ontainer9
view;ontainer!setVisibility8View!V(4(BLE9?
view;ontainer!setAlpha859?
view;ontainer!animate89!alpha8G!$9!seturation8QGGG9
!withEndAtion8new Runnable89
@Override
public void run89
view;ontainer!setVisibility8View!0>E9?
@ @9?
@
@
If you select the entry in the ActionBar, the button bar becomes visible for 5 seconds.
8/16/2019 Listas Android
37/62
1". Performan*e 7timi8ation
The following will implement a performance optimized version of the adapter from theprevious example.
Create the following7y'er$ormaneArrayAdapter class.
package de!vo%ella!android!listativity?
import android!app!Ativity?
import android!view!Layout(n$later?
import android!view!View?
import android!view!Viewroup?
import android!wid%et!ArrayAdapter?
import android!wid%et!(ma%eView?
import android!wid%et!.extView?
8/16/2019 Listas Android
38/62
public class 7y'er$ormaneArrayAdapter extends ArrayAdapter
8/16/2019 Listas Android
39/62
View)older holder = 8View)older9 rowView!%et.a%89?
4trin% s = namespositionC?
holder!text!set.ext8s9?
if 8s!starts6ith8"6indows"9 MM s!starts6ith8"i'hone"9 MM s!starts6ith8"4olaris"99
holder!ima%e!set(ma%eResoure8R!drawable!no9?
@ else
holder!ima%e!set(ma%eResoure8R!drawable!o9?
@
return rowView?
@
@
Use your new adapter in youractivity. If you run the application it should look the same but
it will be much faster, especially for large datasets.
package de!vo%ella!android!listativity?
import android!app!ListAtivity?
import android!os!Bundle?
public class 7yListAtivity extends ListAtivity
public void on;reate8Bundle iile9
super!on;reate8iile9?
4trin%C values = new 4trin%C "Android" "i'hone"
"6indows7obile"
"Blaberry" "6eb04" "Dbuntu" "6indows" "7ax 04 F"
"Linux" "04/1" @?
setListAdapter8new 7y'er$ormaneArrayAdapter8this values99?
@
@
8/16/2019 Listas Android
40/62
1#. Tutorial, 9ow to disla! two items ina ListView
You can use the4impleAdapter class to show the data of two elements. This class
expects a Array of Strings ($rom data) in which the fields of the input data are defined. It
also requires a Array of ints which defines the IDs of the widgets in the layout for the row to
which these fields are mapped.
The actual data is then a list of Maps. The Map defines for each field in the from data a
value.
The following shows an example which reuses an predefined layout from Android for the
row.
package de!vo%ella!android!listativity?
import ava!util!ArrayList?
import ava!util!)ash7ap?
import ava!util!7ap?
import android!app!ListAtivity?
import android!os!Bundle?
import android!wid%et!4impleAdapter?
public class 7y.woList(temsAtivity extends ListAtivity
protected void on;reate8Bundle saved(nstane4tate9
super!on;reate8saved(nstane4tate9?
ArrayList
8/16/2019 Listas Android
41/62
private ArrayList
8/16/2019 Listas Android
42/62
8/16/2019 Listas Android
43/62
Selection is just one possible example but you can imange other interaction between your
row and model.
To persist the selection you have to update your data model with the selected state.
To update the data model in yourListView you define your ownAdapter class. In thisadapter class you attach a listener to theView which is responsible for selecting the model
element. If selected you update the state in the model which you can add as a tag to the
View to have access to it.
The following example demonstrates how to use standard Java object and how to interact
from theViews with the model.
1$.2. Tutorial, %omain odel and list iew rows intera*tion
Continue to use thede!vo%ella!android!listativity project.
Create the following7odel which hold the name and the information if this element is
currently selected.
package de!vo%ella!android!listativity?
public class 7odel
private 4trin% name?
private boolean seleted?
public 7odel84trin% name9
this!name = name?
seleted = $alse?
@
public 4trin% %et>ame89 return name?
@
public void set>ame84trin% name9
this!name = name?
8/16/2019 Listas Android
44/62
@
public boolean is4eleted89
return seleted? @
public void set4eleted8 boolean seleted9
this!seleted = seleted?
@
@
Create the following new layout file calledrowbttonlayot.xml.
8/16/2019 Listas Android
45/62
android:layout#mar%inLe$t="px"
android:layout#mar%inRi%ht="5Gpx" +
8/16/2019 Listas Android
46/62
static class View)older
protected .extView text?
protected ;heBox hebox?
@
@Override
public View %etView8int position View onvertView Viewroup parent9
View view = null?
if 8onvertView == null9
Layout(n$later in$lator = ontext!%etLayout(n$later89?
view = in$lator!in$late8R!layout!rowbuttonlayout null9?
final View)older view)older = new View)older89?
view)older!text = 8.extView9 view!$indViewBy(d8R!id!label9?
view)older!hebox = 8;heBox9 view!$indViewBy(d8R!id!he9?
view)older!hebox
!set0n;heed;han%eListener8new
;ompoundButton!0n;heed;han%eListener89
@Override
public void on;heed;han%ed8;ompoundButton buttonView boolean is;heed9
7odel element = 87odel9 view)older!hebox
!%et.a%89?
element!set4eleted8buttonView!is;heed899?
@
@9?
view!set.a%8view)older9?
view)older!hebox!set.a%8list!%et8position99?
@ else
view = onvertView?
88View)older9 view!%et.a%899!hebox!set.a%8list!%et8position99?
@
8/16/2019 Listas Android
47/62
View)older holder = 8View)older9 view!%et.a%89?
holder!text!set.ext8list!%et8position9!%et>ame899?
holder!hebox!set;heed8list!%et8position9!is4eleted899?
return view? @
@
Finally change your activity to the following.
package de!vo%ella!android!listativity?
import ava!util!ArrayList?
import ava!util!List?
import android!app!ListAtivity?
import android!os!Bundle?
import android!wid%et!ArrayAdapter?
public class 7yList extends ListAtivity
/ ;alled when the ativity is $irst reated! /
public void on;reate8Bundle iile9
super!on;reate8iile9?
// create an array of $trings that will be pt to or 0ist%ctivity
ArrayAdapter
8/16/2019 Listas Android
48/62
list!add8%et8"Linux"99?
list!add8%et8"6indows"99?
list!add8%et8"4use"99?
list!add8%et8"Elipse"99? list!add8%et8"Dbuntu"99?
list!add8%et8"4olaris"99?
list!add8%et8"Android"99?
list!add8%et8"i'hone"99?
// ,nitially select one of the items
list!%et859!set4eleted8true9?
return list?
@
private 7odel %et84trin% s9
return new 7odel8s9?
@
@
If you start your app you should be able to flag items. These changes will be reflected in
your model.
1&. /mlementing an e'andableListView
1&.1. +'andableListView
TheExpandableListView is similar toListView but allow you to define groups and
details for this group.ExpandableListViewexpects and adapter of
typeBaseExpandableListAdapter.
In this case you have to define two layouts, one for the group and another one for the details
row.
1&.2. +'andableListView e'amle
8/16/2019 Listas Android
49/62
In the following example you create an expandable listview similar to the following
screenshot.
8/16/2019 Listas Android
50/62
8/16/2019 Listas Android
51/62
Create a project calledcom.vogella.android.listview.expandable with the activity
called7ainAtivity.
Create or adjust the following layout files. Firstlayot/activity_main.xml.
8/16/2019 Listas Android
52/62
android:drawableRi%ht=",drawable/i#launher"
android:%ravity="le$t"
android:paddin%Le$t="P1dp"
android:paddin%.op="Kdp" android:text=".est"
android:text4i2e="5sp"
android:textAli%nment="textEnd"
android:text4tyle="bold" /+
The last required layout islayot/listrow_details.xml.
8/16/2019 Listas Android
53/62
8/16/2019 Listas Android
54/62
import android!view!View?
import android!view!View!0n;liListener?
import android!view!Viewroup?
import android!wid%et!BaseExpandableListAdapter?import android!wid%et!;heed.extView?
import android!wid%et!.extView?
import android!wid%et!.oast?
public class 7yExpandableListAdapter extends BaseExpandableListAdapter
private final 4parseArray
8/16/2019 Listas Android
55/62
boolean isLast;hild View onvertView Viewroup parent9
final 4trin% hildren = 84trin%9 %et;hild8%roup'osition
hild'osition9?
.extView text = null? if 8onvertView == null9
onvertView = in$later!in$late8R!layout!listrow#details null9?
@
text = 8.extView9 onvertView!$indViewBy(d8R!id!textView59?
text!set.ext8hildren9?
onvertView!set0n;liListener8new 0n;liListener89
@Override
public void on;li8View v9
.oast!mae.ext8ativity hildren
.oast!LE>.)#4)0R.9!show89?
@
@9?
return onvertView?
@
@Override
public int %et;hildren;ount8int %roup'osition9 return %roups!%et8%roup'osition9!hildren!si2e89?
@
@Override
public 0bet %etroup8int %roup'osition9
return %roups!%et8%roup'osition9?
@
@Override
public int %etroup;ount89
return %roups!si2e89?
@
8/16/2019 Listas Android
56/62
@Override
public void onroup;ollapsed8int %roup'osition9
super!onroup;ollapsed8%roup'osition9?
@
@Override
public void onroupExpanded8int %roup'osition9
super!onroupExpanded8%roup'osition9?
@
@Override
public long %etroup(d8int %roup'osition9
return G?
@
@Override
public View %etroupView8int %roup'osition boolean isExpanded
View onvertView Viewroup parent9
if 8onvertView == null9
onvertView = in$later!in$late8R!layout!listrow#%roup null9?
@ roup %roup = 8roup9 %etroup8%roup'osition9?
88;heed.extView9 onvertView9!set.ext8%roup!strin%9?
88;heed.extView9 onvertView9!set;heed8isExpanded9?
return onvertView?
@
@Override
public boolean has4table(ds89
return $alse?
@
@Override
8/16/2019 Listas Android
57/62
public boolean is;hild4eletable8int %roup'osition int
hild'osition9
return $alse?
@@
package om!vo%ella!android!listview!expandable?
import ava!util!ArrayList?
import android!app!Ativity?
import android!os!Bundle?
import android!util!4parseArray?
import android!view!7enu?
import android!wid%et!ExpandableListView?
public class 7ainAtivity extends Ativity
// more efficient than 1ash'ap for mapping integers to ob2ects
4parseArray
8/16/2019 Listas Android
58/62
for 8int i = G? i < Q? i--9
%roup!hildren!add8"4ub (tem" - i9?
@
%roups!append8 %roup9? @
@
@
1. Tutorial, is*ellaneous
1.1. Adding a long*li*: listener to the list items
You can also add aLon%(tem;liListener to the list view via
theset0n(temLon%;liListener89 method.
package de!vo%ella!android!listativity?
import android!wid%et!AdapterView!0n(temLon%;liListener?
public class 7yList extends Ativity
/ ;alled when the ativity is $irst reated! /
public void on;reate8Bundle iile9
super!on;reate8iile9?
// configre yor list view as before
// 0ist3iew is assigned to local variable list...
list!set0n(temLon%;liListener8new 0n(temLon%;liListener89
@Override
public boolean on(temLon%;li8AdapterView
8/16/2019 Listas Android
59/62
int position long id9
.oast!mae.ext87yList!this
"(tem in position " - position - " lied"
.oast!LE>.)#L0>9!show89? // etrn tre to consme the clic( event. ,n this case the
// on0ist,tem!lic( listener is not called anymore.
return true?
@
@9?
@
@
1.2. 9eader and footer
You can of course put arbitrary views elements around your list view. For example you can
define a layout with two text views and a list view between them. In this case the two text
views will always be visible above the list (header) and the other will be visible below the list.
If you want to display a list header or list footer only at the see the beginning or end of the
list you can use theadd)eaderView89 method oraddIooterView89 method on
theListView class.
// configration as before
ListView listView = 8ListView9 $indViewBy(d8R!id!list9?
View header = %etLayout(n$later89!in$late8R!layout!header null9?
View $ooter = %etLayout(n$later89!in$late8R!layout!$ooter null9?
listView!add)eaderView8header9?
listView!addIooterView8$ooter9?
listView!setAdapter8new ArrayAdapter
8/16/2019 Listas Android
60/62
In case you work with a content provider or directly with the database you can use
the4imple;ursorAdapter to define the data for yourListView. The following will
demonstrates how to access the Contacts ContentProvider.
Create a new Android project called "de.vogella.android.listactivity.cursor" with
theactivity calledMyListActivity. Change7yListAtivity to the following.
package de!vo%ella!android!listativity!ursor?
import android!app!ListAtivity?
import android!database!;ursor?
import android!net!Dri?
import android!os!Bundle?
import android!provider!;ontats;ontrat?
import android!wid%et!ListAdapter?
import android!wid%et!4imple;ursorAdapter?
public class 7yListAtivity extends ListAtivity
/ ;alled when the ativity is $irst reated! /
@Override
public void on;reate8Bundle saved(nstane4tate9
super!on;reate8saved(nstane4tate9?
;ursor m;ursor = %et;ontats89?
start7ana%in%;ursor8m;ursor9?
// now create a new list adapter bond to the crsor.
// $imple0ist%dapter is designed for binding to a !rsor.
ListAdapter adapter = new 4imple;ursorAdapter8this // !ontext.
android!R!layout!two#line#list#item // $pecify the row
template
// to se *here two
// colmns bond to the
// two retrieved crsor
// rows+.
8/16/2019 Listas Android
61/62
m;ursor // Pass in the crsor to bind to.
// %rray of crsor colmns to bind to.
new 4trin%C ;ontats;ontrat!;ontats!#(
;ontats;ontrat!;ontats!(4'LAH#>A7E @ // Parallel array of which template ob2ects to bind to those
// colmns.
new intC android!R!id!text5 android!R!id!text1 @9?
// &ind to or new adapter.
setListAdapter8adapter9?
@
private ;ursor %et;ontats89
// n 4ery
Dri uri = ;ontats;ontrat!;ontats!;0>.E>.#DR(?
4trin%C proetion = new 4trin%C ;ontats;ontrat!;ontats!#(
;ontats;ontrat!;ontats!(4'LAH#>A7E @?
4trin% seletion = ;ontats;ontrat!;ontats!(>#V(4(BLE#R0D' - " =
S"
- 8"5"9 - "S"?
4trin%C seletionAr%s = null? 4trin% sort0rder = ;ontats;ontrat!;ontats!(4'LAH#>A7E
- " ;0LLA.E L0;AL(TE A4;"?
return mana%edUuery8uri proetion seletion seletionAr%s
sort0rder9?
@
@
Make sure you give your application the permission to read the contacts. (Uses Permissions
"android.permission.READ_CONTACTS" in AndroidManifest.xml)
10. Additional 7en 4our*e libraries
8/16/2019 Listas Android
62/62
Sometimes having to press a refresh button on the ActionBar to refresh data can be
annoying for the user. Chris Banes has implemented an Open Source library to implement
the pull to refresh pattern for aListview. https://github.com/chrisbanes/Android-
PullToRefresh.
Also you may want to use the swipe to dismiss gesture to delete items from a ListView.Roman Nurik provides an example for this atAndroid swipe-to-dismiss library which
Jake Wharton backported to earlier Android releases atSwipeToDismissNOA.
https://github.com/romannurik/android-swipetodismisshttps://github.com/romannurik/android-swipetodismisshttps://github.com/JakeWharton/SwipeToDismissNOAhttps://github.com/romannurik/android-swipetodismisshttps://github.com/JakeWharton/SwipeToDismissNOA