mobappdev (fall 2014): arrayadapters, listviews, & listactivities
TRANSCRIPT
MobAppDev
ArrayAdapters, ListViews, & ListActivities
Vladimir Kulyukin
www.vkedco.blogspot.com
Outline● Adapter Design Pattern ● Android Array Adapters
Adapter Design Pattern
Adapter Design Pattern● The intent of the Adapter Design Pattern is to convert
the interface of one class into another interface clients expect or require
● The purpose of Adapters is to make communication possible among classes with incompatible interfaces
● Adapters also provide a common interface to classes and objects with disparate (partially compatible) interfaces
● In Software Engineering, adapters are also called wrappers
Adapter DP Applicability
● Adapter DP is used when There is an existing class and its interface does not match
the one that is needed The objective is to create a reusable class that cooperates
with unpredictable interfaces There exist several subclasses and it is impractical to
subclass all of them to adapt their interfaces; in this case, an object adapter can adapt the interface of its parent class
Adapter DP Implementation: Inheritance
Client
SpecificRequest()
Target Adaptee
Adapter
Request()
Request()
SpecificRequest()
Target: Defines Domain-Specific InterfaceClient: Uses Target ObjectsAdaptee: Defines Interface that must be adaptedAdapter: Adapts the interface of Adaptee to Target
Adapter DP Implementation: CompositionClient
SpecificRequest()
Target Adaptee
Adapter
Request()
Request()
SpecificRequest()
Target: Defines Domain-Specific InterfaceClient: Uses Target ObjectsAdaptee: Defines Interface that must be adaptedAdapter: Adapts the interface of Adaptee to Target
Android Array Adapters
Android Adapters● Android adapters (Adapter) provide a common interfaces to
the data model behind containers● Three types of adapters on Android: ArrayAdapter,
CursorAdapter, SimpleCursorAdapter● More specifically, Android adapters provide child views for
specific containers● Android adapters are used with container controls that
extend android.widget.AdapterView: ListView, GridView, Spinner, Gallery
Creating & Binding Adapters
● Define a data source (e.g., a array of strings)● Create an adapter and bind it to the data source● Bind the adapter to a view that the adapter
populates
Blueprint for Creating & Binding Adapters// 1. Create a data source
String[] ary = { “string_0”, “string_1”, “string_2” };
// 2. Create & bind adapter
ArrayAdapter<String> adptr
= new ArrayAdapter<String>(this, android.R.layout_sipmle_list_item_1,
ary);
// 1st argument is Context (this)
// 2nd argument is the view layout
// 3rd argument is a sequence of objects
ListView
● ListViewis a View group used to display a scrollable list of items
● Individual items are inserted into a ListView by an Adapter bound to a data source
● An Adapter adopts each item to a View● ListActivity is an Activity that hosts a ListView
Sample Applications
Pascal's Works● We will develop several applications that demonstrate various
uses of ArrayAdapters● All applications use ListViews and ArrayAdapters to display fives
works by Blaise Pascal● The titles of Pascal's works are placed into a String array● Selection of an item in the ListView toasts the details of the item
selected
Pascal's Works 01: Screenshots
Pascal's Works 01● Develop an application that uses a ListActivity to display the
titles of five books by Pascal 1) Discourses on the Condition of the Great; 2) The Art of Persuasion; 3) Of the Geometrical Spirit; 4) Preface to the Treatise on Vacuum; 5) New Fragment of the Treatise on Vacuum
● The titles are placed into a String array● An ArrayAdapter is bound to the string array and attached to
the ListView of the ListActivity● Selection of an item in the ListView toasts the details of the item
selected
Source Code Highlights
Defining & Populating Data Source// 1. Create a data source
this.mPascalsWorks = new String[NUM_WORKS];
this.mRes = this.getResources();
// 2. Populate the data source
this.mPascalsWorks[0] = this.mRes.getString(R.string.discourses);
this.mPascalsWorks[1] = this.mRes.getString(R.string.geometrical_spirit);
this.mPascalsWorks[2] = this.mRes.getString(R.string.persuasion);
this.mPascalsWorks[3] = this.mRes.getString(R.string.vacuum_01);
this.mPascalsWorks[4] = this.mRes.getString(R.string.vacuum_02);
Creating & Binding ArrayAdapter// 1. Get the ListView of the ListActivity
ListView lv = this.getListView();
// 2. Create and bind an ArrayAdapter
ArrayAdapter<String> adptr =
new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
mPascalsWorks);
// 3. Bind the adapter to the list view
lv.setAdapter(adptr);
Attach and Implement OnItemClickListenerlv.setOnItemClickListener(this);
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String msg = "PARENT = " + parent.toString() + "\n";
msg += "VIEW = " + view.toString() + "\n";
msg += "VIEW'S TEXT = " + ((TextView)view).getText().toString() + "\n";
msg += "POSITION = " + Integer.toString(position) + "\n";
msg += "ID = " + Long.toString(id);
// Make a toast and display it on the screen
Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
}
Pascal's Works 02● Develop an application that uses a ListActivity to display the
titles of five works by Blaise Pascal● The titles are placed into a String array● An ArrayAdapter is bound to the string array and attached to
the ListActivity directly, thereby bypassing the creation of a ListView reference
● The ArraAdapter uses a custom view layout defined in list_item_layout.xml
Pascal's Works 01: Screenshots
Source Code Highlights
Custom TextView Item Layout
<!-- This is saved in /res/layout/list_item_layoutxml -->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="11dp"
android:textSize="10sp">
</TextView>
Creating & Binding ArrayAdapter
// Attach an anonymous ArrayAdapter
// to the ListView of the ListActivity
this.setListAdapter(
new ArrayAdapter<String>(this,
R.layout.list_item_layout,
mPascalsWorks)
);
Pascal's Works 03● Develop an application that uses a ListActivity to display the titles of five
works by Blaise Pascal and their fictional years● Unlike in Pascal's Works 01 and Pascal's Works 02, the titles and years are
defined as XML arrays (pascals_works.xml) and are inflated into String arrays at run time
● An ArrayAdapter is bound to the to the title string array and attached to the ListActivity directly bypassing the creation of a ListView reference
● At run time, the OnItemClickListener attached to ListView uses the TextView's position to retrieve the appropriate year from the array of fictional publication years
Pascal's Works 03: Screenshot
Source Code Highlights
Defining XML Arrays
<!-- This is saved in /res/layout/pascals_works.xml -->
<resources>
<array name="pascals_titles">
<item>Discourses on the Condition of the Great</item>
<item>The Art of Persuasion</item>
<item>Of the Geometrical Spirit</item>
<item>Preface to the Treatise on Vacuum</item>
<item>New Fragment of the Treatise on Vacuum</item>
</array>
</resources>
Defining XML Arrays
<!-- This is saved in /res/layout/pascals_works.xml -->
<resources>
<array name="pascals_titles_years">
<item>1651</item>
<item>1652</item>
<item>1653</item>
<item>1654</item>
<item>1655</item>
</array>
</resources>
Inflating XML Arrays at Run Time
static String[] mPascalsWorks = null;
static int[] mPascalsYears = null;
Resources res = this.getResources();
mPascalsWorks = res.getStringArray(R.array.pascals_titles);
mPascalsYears = res.getIntArray(R.array.pascals_titles_years);
Pascal's Works 04
● This application UI and logic is the same as Pascal's Works 03● At run time, the OnItemClickListener attached to ListView
uses the TextView's position to retrieve the appropriate year from the array of fictional years
● The difference is in the construction of ArrayAdapter through a static method that takes a reference to the XML array of Pascal's titles and binds the constructed adapter to it
Adaptor Construction
ArrayAdapter<CharSequence> adptr
= ArrayAdapter.createFromResource(this,
R.array.pascals_titles,
R.layout.list_item_layout);