Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
8 views

Android Chapter05 ListBased Widgets

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views

Android Chapter05 ListBased Widgets

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 31

List-Based Widgets

GUI Design for Selection Making


• RadioButtons and CheckButtons are widgets suitable for selecting options
Lesson 5 offered by a small set of choices. They are intuitive and uncomplicated;
however they occupy a permanent space
on the GUI (which is not a problem when
only a few of them are shown)

List-Based Widgets: • When the set of values to choose from is large, other Android List-Based
Widgets are more appropriate.
Lists, Grids, and Scroll Views
• Example of List-Based Widgets include:
Victor Matos
• ListViews,
Cleveland State University
• Spinner,
• GridView
• Image Gallery
• ScrollViews, etc.

Portions of this page are reproduced from work created and shared by Google and used according to terms
described in the Creative Commons 3.0 Attribution License. 5-2

List-Based Widgets List-Based App = ListView + Data + DataAdapter


Showing a large set of choices on the GUI ListViews

The Android ListView widget


is the most common element
used to display data supplied
by a data adapter.

DATA ListViews are scrollable, each


Raw data Formatted
item from the base data set
& bound can be shown in an individual
data
row.
DATA
ADAPTER
Users can tap on a row to
make a selection.
• The Android DataAdapter class is used to feed a
collection of data items to a List-Based Widget.
A row could display one or more Destination layout
• The Adapter ‘s raw data may come from a variety Destination layout Holding a ListView
of sources, such as small arrays as well as large Holding a ListView lines of text as well as images.
databases. 5-3 5-4
List-Based App = ListView + Data + DataAdapter List-Based App = ListView + Data + DataAdapter
ArrayAdapter (A Data Beautifier) Output: ‘Pretty’ GUI
• An ArrayAdapter<T> accepts for input an array (or ArrayList) of objects
of some arbitrary type T. Input Data - array or java.util.List
{ object1, object2, …, objectn } object 1.toString()
• The adapter works on each object by (a) applying its toString()
method, and (b) moving its formatted output string to a TextView.
textviews…

• The formatting operation is guided by a user supplied XML layout


specification which defines the appearance of the receiving TextView. Array Adapter
object n.toString()
• For ListViews showing complex arrangement of visual elements –such as
text plus images- you need to provide a custom made adapter in which
the getView(…) method explains how to manage the placement of each Input XML Specification
data fragment in the complex layout. For a detailed sample see Example 8. <?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
...
/>

5-5 5-6

List-Based App = ListView + Data + DataAdapter Using ListActivity + ArrayAdapter


Using the ArrayAdapter<String> Class Example1A: ListView showing a simple list (plain text)
String[] items = { "Data-0", "Data-1", "Data-2", "Data-3", Assume a large collection of input data items is held in a String[] array.
"Data-4", "Data-5", "Data-6", "Data-7" }; Each row of the ListView must show a line of text taken from the array.
In our example, when the user makes a selection, you must display on a
ArrayAdapter<String> adapter = new ArrayAdapter<String>( TextView the selected item and its position in the list.
this,
android.R.layout.simple_list_item_1,
items );

Parameters:
1. The current activity’s context (this)
2. The TextView layout indicating how an individual row should be
written ( android.R.id.simple_list_item_1 ).
3. The actual data source (Array or Java.List containing items to be
shown).

5-7 5-8
Using ListActivity + ArrayAdapter Using ListActivity + ArrayAdapter
Example1A: Layout Example1A: MainActivity ( using a ListActivity ! )
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" package csu.matos;
xmlns:tools="http://schemas.android.com/tools" CAUTION:
android:layout_width="match_parent" import ... A ListActivity is not a “plain”
android:layout_height="match_parent"
android:orientation="vertical">
Pay attention to the use of predefined Activity. It is bound to a built-in
Android components: public class ListViewDemo extends ListActivity { ListView called @android:id/list
<TextView @android:id/list
android:id="@+id/txtMsg" TextView txtMsg;
android:layout_width="match_parent" @android:id/empty
android:layout_height="wrap_content" String[] items = { "Data-0", "Data-1", "Data-2", "Data-3",
android:background="#ffffff00" See Appendix A for a description of "Data-4", "Data-5", "Data-6", "Data-7" };
android:text="Using ListViews..."
android:textSize="16sp" /> @android:id/list
// next time try an empty list such as:
// String[] items = {};
<ListView
android:id="@android:id/list" Data
android:layout_width="match_parent"
Android’s built-in list layout
Source
android:layout_height="match_parent" >
</ListView>

<TextView
android:id="@android:id/empty" Used for empty lists
...
android:layout_width="match_parent" Fragment already defined in
<ListView
android:layout_height="wrap_content"
android:id="@android:id/list" Layout: activity_main.xml
android:background="#ffff0000"
android:layout_width="match_parent"
android:text="empty list" /> android:layout_height="match_parent" >
</ListView>
</LinearLayout> ...
5-9 5 - 10

Using ListActivity + ArrayAdapter Using ListActivity + ArrayAdapter


Example1A: MainActivity ( using a ListActivity ! ) Example1A: MainActivity ( using a ListActivity ! )
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
List
adapter
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, Selection seen
items));
by the listener
//getListView().setBackgroundColor(Color.GRAY); //try this idea later

txtMsg = (TextView) findViewById(R.id.txtMsg);


} List Click
Listener
@Override Background
protected void onListItemClick(ListView l, View v, int position, long id) { flashes blue to
super.onListItemClick(l, v, position, id); acknowledge
String text = " Position: " + position + " " + items[position];
txtMsg.setText(text); the users’s
} selection
}

5 - 11 ListView displayed on a device running SDK4.3 5 - 12


Using ListActivity + ArrayAdapter Using ListActivity + ArrayAdapter
A Comment on Example1A An experiment based on Example1A
Using Eclipse & ADT.
A simple way to add new code 1. Open the AndroidManifest.xml file. Under the <Application>
Assume you have NOT written the tag look for the clause
click listener yet. In order to easily android:theme="@style/AppTheme"
add a listener (or any other valid
method) to the ListActivity class 2. Change the previous line to the following value
under construction do this: android:theme="@android:style/Theme.Black"
1. Position the cursor in between the 3. Try some of the other styles, such as:
end of the onCreate method and
Theme.DeviceDefault
the end of the class.
2. On the Eclipse Tool Bar Menu click
Theme.Dialog
Source > Override/Implement Theme.Holo
Methods… > Theme.Light
3. A list of pertinent methods is Theme.Panel
shown. Theme.Translucent
4. Check onListItemClick > Ok Theme.Wallpaper
5. Add your actions to the selected etc.
method.
5 - 14

Using ListActivity + ArrayAdapter Using Activity + ArrayAdapter


Another code experiment based on Example1A Example1B: Using Activity & ArrayAdapter
• You may use a common Activity class instead of a ListActivity.
1. Open the AndroidManifest.xml file. Under the <Application> tag look for • The Layout below uses a ListView identified as @+id/my_list (instead
the clause android:theme="@style/AppTheme" of @android:id/list used in the previous Example1).

2. Now open the res/values/styles folder. Look for the entry <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
<style name="AppTheme" parent="android:Theme.Light" /> android:layout_width="match_parent"
android:layout_height="match_parent"
which indicates to use the “Light” theme (white background instead of android:orientation="vertical" >
black). <TextView
android:id="@+id/txtMsg"
android:layout_width="match_parent"
3. Remove from the manifest the entry android:theme. android:layout_height="wrap_content"
android:background="#ffffff00"
android:text="Using ListViews..."
4. Remove from the onCreate method the statement: android:textSize="16sp" />
getListView().setBackgroundColor(Color.GRAY); <ListView try:
android:id="@+id/my_list" wrap_content
android:layout_width="match_parent" to see limitations
3. Run the application again. Observe its new look. android:layout_height="match_parent" >
</ListView>

</LinearLayout>

5 - 15 5 - 16
Using Activity + ArrayAdapter Using Activity + ArrayAdapter
Example1B: Instead of using a ListActivity (as we did on the previous Example 1B – MainActivity 2 of 2
example) we now employ a regular Android Activity. Observe that you myListView.setOnItemClickListener(new OnItemClickListener() {
must ‘wired-up’ the ListView to a Java proxy, and later bind it to an Adapter. @Override
public void onItemClick(AdapterView<?> av, View v,
Example 1B – MainActivity 1 of 2 int position, long id) {

public class ListViewDemo2 extends Activity { String text = "Position: " + position
String[] items = { "Data-0", "Data-1", "Data-2", "Data-3", + "\nData: " + items[position];
"Data-4", "Data-5", "Data-6", "Data-7" };
ListView myListView;
txtMsg.setText(text);
TextView txtMsg;
}
@Override });
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myListView = (ListView) findViewById(R.id.my_list); To provide a listener to the ListView control add the fragment above to the
ArrayAdapter<String> aa = new ArrayAdapter<String>(this,
onCreate method.
android.R.layout.simple_list_item_1,
// R.layout.my_text, //try this later...
items);
myListView.setAdapter(aa);
txtMsg = (TextView) findViewById(R.id.txtMsg);
}//onCreate
} 5 - 17 5 - 18

Using Activity + ArrayAdapter Using Activity + ArrayAdapter


Example1C: Custom ListView Example1C: Custom ListView
You may also create the ArrayAdapter with more parameters. For
You may want to modify the ListView control to use your
instance, the following statement:
own GUI design. For instance, you may replace
android.R.layout.simple_list_item_1 with ArrayAdapter<String> adapter = new ArrayAdapter<String>(
R.layout.my_custom_text. getApplication(),
R.layout.my_custom_line3,
R.id.my_custom_textview3,
Where my_custom_text is the Layout specification listed below (held in the res/layout data );
folder). It defines how each row is to be shown. Defines a custom list and textview layout to show the contents of
the data array.
<?xml version="1.0" encoding="utf-8"?>
<TextView <!-- my_custom_line3 -->
xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_margin="2dp" android:orientation="vertical"
android:paddingTop="5dp" android:padding="6dp" >
android:padding="5dp" <TextView
android:textColor="#ffff0000" android:id="@+id/my_custom_textview3"
android:background="#22ff0000" android:layout_width="match_parent"
android:textSize="35sp" /> android:layout_height="wrap_content"
android:background="#220000ff"
android:padding="1dp"
android:textColor="#ffff0000"
Note: As of SDK4.0 a TextView could also include an image (For example .setDrawableLeft(some_image) ) android:textSize="35sp" />
5 - 19 </LinearLayout> 5 - 20
The Spinner Widget Example2: Using the Spinner Widget
Example 2. A list of options named ‘Data-0’, ‘Data-1’, ‘Data-2’ and so on, should
be displayed when the user taps on the ‘down-arrow’ portion of the spinner.

3. Selected
• Android’s Spinner is equivalent to a drop-down selector. value

• Spinners have the same functionality of a ListView but take less screen
space.

• An Adapter is used to supply its data using setAdapter(…)


1. Click Drop-
down button
• A listener captures selections made from the list with
setOnItemSelectedListener(…).
2. Select this option
• The setDropDownViewResource(…) method shows the drop-down
multi-line window

Images taken from a


device running SDK
5 - 21 JellyBean 4.3 5 - 22

Using the Spinner Widget Using the Spinner Widget


Example2: Spinner Demo - Layout Example2: Spinner Demo - MainActivity 1 of 2
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" public class MainActivity extends Activity
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" implements AdapterView.OnItemSelectedListener{
android:layout_height="match_parent" // GUI objects
android:orientation="vertical" TextView txtMsg;
android:padding="3dp" Spinner spinner;
tools:context=".MainActivity" >
// options to be offered by the spinner
<TextView String[] items = { "Data-0", "Data-1", "Data-2", "Data-3", "Data-4",
android:id="@+id/txtMsg" "Data-5", "Data-6", "Data-7" };
android:layout_width="match_parent"
android:layout_height="wrap_content" @Override
android:background="#ffffff00" protected void onCreate(Bundle savedInstanceState) {
android:text="@string/hello_world" /> super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
<Spinner txtMsg = (TextView) findViewById(R.id.txtMsg);
android:id="@+id/spinner1"
android:layout_width="match_parent" spinner = (Spinner) findViewById(R.id.spinner1);
android:layout_height="wrap_content" />

</LinearLayout> // use adapter to bind items array to GUI layout


ArrayAdapter<String> adapter = new ArrayAdapter<String>(
this,
android.R.layout.simple_spinner_dropdown_item,
items);

5 - 23 5 - 24
Using the Spinner Widget The GridView Widget
Example2: Spinner Demo - MainActivity 2 of 2

// bind everything together


spinner.setAdapter(adapter);
GridView
// add spinner a listener so user can meake selections by tapping an item
spinner.setOnItemSelectedListener(this); GridView is a ViewGroup that
displays items in a
}
// next two methods implement the spinner's listener two-dimensional, scrollable grid.
@Override
public void onItemSelected(AdapterView<?> parent, View v, int position,
long id) { Data items shown
// echo on the textbox the user's selection by the grid are supplied
txtMsg.setText(items[position]);
} by a data adapter.
@Override
public void onNothingSelected(AdapterView<?> arg0) { Grid cells can show
// TODO do nothing – needed by the interface
text and/or images
}

5 - 25 5 - 26

The GridView Widget The GridView Widget


GridView: Useful Properties GridView: Fitting the View to the Screen
Some properties used to determine the number of columns and their sizes: Suppose the screen is 320 (dip) pixels wide, and we have

• android:numColumns android:columnWidth set to 100dip and


indicates how many columns to show. When used with option “auto_fit”, android:horizontalSpacing set to 5dip.
Android determines the number of columns based on available space and
the properties listed below. The user would see three columns taking 310 pixels (three columns of 100
pixels and two separators of 5 pixels).
• android:verticalSpacing and android:horizontalSpacing
indicate how much free space should be set between items in the grid. With android:stretchMode set to columnWidth, the three columns will each
expand by 3-4 pixels to use up the remaining 10 pixels.
• android:columnWidth
column width in dips. With android:stretchMode set to spacingWidth, the two internal whitespaces
will each grow by 5 pixels to consume the remaining 10 pixels.
• android:stretchMode
indicates how to modify image size when there is available space not
taken up by columns or spacing .

5 - 27 5 - 28
The GridView Widget The GridView Widget
Example3A: GridView Demo - Layout Example3A: GridView Demo – MainActivity 1 of 2
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LinearLayout1" public class ArrayAdapterDemo3 extends Activity {
android:layout_width="match_parent"
android:layout_height="match_parent" TextView txtMsg;
android:orientation="vertical"
android:padding="2dp" String[] items = { "Data-0", "Data-1", "Data-2", "Data-3",
tools:context=".MainActivity" >
<TextView
"Data-4", "Data-5", "Data-6", "Data-7" };
android:id="@+id/txtMsg" @Override
android:layout_width="match_parent" public void onCreate(Bundle savedInstanceState) {
android:layout_height="wrap_content" super.onCreate(icicle);
android:background="#ff0000ff" setContentView(R.layout.activity_main);
android:textSize="24sp"
android:textStyle="bold"
android:textColor="#ffffffff"
txtMsg = (TextView) findViewById(R.id.txtMsg);
android:padding="2dip" />

<GridView
android:id="@+id/grid"
android:background="#77ffff00"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:verticalSpacing="5dip"
android:horizontalSpacing="5dip"
android:numColumns="auto_fit"
android:columnWidth="100dip"
android:stretchMode="spacingWidth" />
</LinearLayout>
5 29
- 29 5 - 30

The GridView Widget The AutoComplete TextView Widget


Example3A: GridView Demo – MainActivity 2 of 2 AutoComplete TextView
GridView grid = (GridView) findViewById(R.id.grid); • An AutoComplete box is a more specialized version of the EditText view.
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
this, • Characters typed so far are compared with the beginning of words held in
android.R.layout.simple_list_item_1,
items ); a user-supplied list of suggested values.

grid.setAdapter(adapter);
• Suggestions matching the typed prefix are shown in a selection list.
grid.setOnItemClickListener(new OnItemClickListener() {
• The user can choose from the suggestion list or complete typing the
@Override
public void onItemClick(AdapterView<?> container, View v, word.
int position, long id) {
txtMsg.setText(items[position]);
} • The android:completionThreshold property is used to trigger the
}); displaying of the suggestion list. It indicates the number of characters to
}//onCreate
watch for in order to match prefixes.

}// class
NOTE: For other features of the TextView control see Appendix B

5 - 31 5 - 32
The AutoComplete TextView Widget The AutoComplete TextView Widget
Example4: AutoComplete Demo - Layout
Example 4.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
A list of selected xmlns:tools="http://schemas.android.com/tools"
words beginning android:layout_width="match_parent"
android:layout_height="match_parent" >
with “wor” or “set”
Tap to select
is being watched. <TextView
this option android:id="@+id/txtMsg"
android:layout_width="match_parent"
If any of these android:layout_height="wrap_content"
prefixes (3 letters) android:textSize="20sp"
android:textColor="#ffffffff"
are entered the android:background="#ff0000ff" >
TextWatcher </TextView>
mechanism shows <AutoCompleteTextView
an option list. android:id="@+id/autoCompleteTextView1"
android:hint="type here..."
android:completionThreshold="3" Wait 3 chars to work
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/txtMsg"
android:layout_marginTop="15dp"
android:ems="10" />

5 - 33 </RelativeLayout> 5 - 34

The AutoComplete TextView Widget The AutoComplete TextView Widget


Example4: AutoComplete Demo – MainActivity 1 of 2 Example4: AutoComplete Demo – MainActivity 2 of 2

txtAutoComplete = (AutoCompleteTextView) findViewById(


public class ArrayAdapterDemo4 extends Activity implements TextWatcher { R.id.autoCompleteTextView1);
txtAutoComplete.addTextChangedListener(this);
TextView txtMsg;
txtAutoComplete.setAdapter(new ArrayAdapter<String>(
AutoCompleteTextView txtAutoComplete; this,
android.R.layout.simple_list_item_single_choice,
String[] items = { "words", "starting", "with", "set", "Setback", items));
"Setline", "Setoffs", "Setouts", "Setters", "Setting", }//onCreate
"Settled", "Settler", "Wordless", "Wordiness", "Adios" };
public void onTextChanged(CharSequence s, int start, int before, int count) {
@Override txtMsg.setText(txtAutoComplete.getText());
public void onCreate(Bundle savedInstanceState) { }
super.onCreate(savedInstanceState);
public void beforeTextChanged(CharSequence s, int start, int count,int after) {
setContentView(R.layout.activity_main); // needed for interface, but not used
}
txtMsg = (TextView) findViewById(R.id.txtMsg);
public void afterTextChanged(Editable s) {
// needed for interface, but not used
}

}//class

5 - 35 5 36
- 36
The HorizontalScrollView Widget The HorizontalScrollView Widget
Example5: HorizontalScrollView Demo
HorizontalScrollViews allow the user to
graphically select an option from a set of • In this example we place a
small images called thumbnails +. HorizontalScrollView
at the top of the screen, this view will
The user interacts with the viewer using show a set of thumbnail options.
two simple actions:
1. Scroll the list (left ⟷ right)
2. Click on a thumbnail to pick the option
• The user may scroll through the images and
it offers. finally tap on a particular selection.

In our example, when the user clicks on a • A better quality version of the selected
thumbnail the app responds by displaying a picture will be displayed in an ImageView
high-resolution version of the image widget placed below the horizontal scroller.

+. A typical thumbnail size is 100x100 pixels


(or less).
5 - 37 5 - 38

The HorizontalScrollView Widget The HorizontalScrollView Widget


Example5: How to make a thumbnail ? Example5: How to make a thumbnail ?
• Option-1. The 100x100 thumbnails shown below were made visiting the site: GRAPHICAL RESOURCES
http://makeathumbnail.com
• Option-2. Upload individual images to the Android_Asset_Studio_Tool High-quality Pictures – Free distribution
http://android-ui-utils.googlecode.com/hg/asset-studio/dist/index.html Pixabay ©. Available at https://pixabay.com/
Last visited June 30, 2017.

Thumbnail makers
MakeAThumbnail ©. Available at http://makeathumbnail.com
Last visited June 30, 2017.

Android Asset Studio ©. Available at https://romannurik.github.io/AndroidAssetStudio/


Last visited June 30, 2017

The free high quality images used in this example were obtained from https://pixabay.com/

5 - 39 5 - 40
The HorizontalScrollView Widget The HorizontalScrollView Widget
Example5: Populating The HorizontalScrollView Widget Example5: HorizontalScrollView Demo – Layout 1 of 2
<?xml version="1.0" encoding="UTF-8"?>
1. Our HorizontalScrollView will expose a list of frames, each containing an <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
icon and a caption below the icon. android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffffffff"
android:orientation="vertical"
2. The frame_icon_caption.xml layout describes the formatting of icon and android:padding="2dp" >
its caption. This layout will be inflated in order to create run-time GUI <TextView
objects. android:id="@+id/txtMsg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
3. After the current frame is filled with data, it will be added to the growing android:background="#ff00ff00"
android:text="scroll and click to select ..."
set of views hosted by the scrollViewgroup container (scrollViewgroup is android:textAppearance="?android:attr/textAppearanceLarge" />
nested inside the horizontal scroller). <HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
4. Each frame will receive an ID (its current position in the scrollViewgroup) android:background="#44aaaaaa" >
as well as an individual onClick listener. <LinearLayout
android:id="@+id/viewgroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dip" >
</LinearLayout>
5 - 41 </HorizontalScrollView> 5 - 42

The HorizontalScrollView Widget The HorizontalScrollView Widget


Example5: HorizontalScrollView Demo – Layout 2 of 2 Example5: Layout: frame_icon_caption.xml
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/imageSelected" android:layout_width="match_parent"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:padding="2dp"
android:layout_weight="2" /> android:orientation="vertical" >
</LinearLayout> <ImageView
android:id="@+id/icon"
android:layout_width="100dp"
android:layout_height="80dp"
android:scaleType="fitXY"
android:src="@mipmap/ic_launcher" />

<TextView
android:id="@+id/caption"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:background="#33ffff00"
android:gravity="center"
android:textSize="20sp" />

</LinearLayout>

This layout will be used by an inflater to dynamically create new views. These views will
5 - 43 be added to the linear layout contained inside the HorizontalScrollerView. 5 - 44
The HorizontalScrollView Widget The HorizontalScrollView Widget
Example5: App’s Structure - Eclipse’s Package Explorer Example5: App’s Structure - Android Studio Package Explorer

5 - 45 5 - 46

The HorizontalScrollView Widget The HorizontalScrollView Widget


Example5: HorizontalScrollView Demo – MainActivity 1 of 5 Example5: HorizontalScrollView Demo – MainActivity 2 of 5
//frame-icons ( 100X100 thumbnails )
public class MainActivity extends Activity { Integer[] thumbnails = {R.drawable.small_blossom_918453_1280
, R.drawable.small_building_922529_1280
//GUI controls , R.drawable.small_cat_914110_1280
TextView txtMsg; , R.drawable.small_church_648430_1280
ViewGroup scrollViewgroup; , R.drawable.small_coffee_744151_1280
, R.drawable.small_coffee_917613_1280
//each frame in the HorizontalScrollView has [icon, caption] , R.drawable.small_dubrovnik_512798_1280
ImageView icon; , R.drawable.small_egg_943413_1280
TextView caption; , R.drawable.small_firefighters_696167_1280
, R.drawable.small_flower_870557_1280
//large image frame for displaying high-quality selected image , R.drawable.small_football_888015_1280
ImageView imageSelected; , R.drawable.small_isolated_219954_1280
, R.drawable.small_jetty_593401_1280
//frame captions , R.drawable.small_jetty_598198_1280
String[] items = {"Photo-1", "Photo-2", "Photo-3", "Photo-4", "Photo-5", , R.drawable.small_paraglider_701440_1280
"Photo-6", "Photo-7", "Photo-8", "Photo-9", "Photo-10", "Photo-11", , R.drawable.small_pelican_336583_1280
"Photo-12", "Photo-13", "Photo-14", "Photo-15", "Photo-16", "Photo-17", , R.drawable.small_pelican_901004_1280
"Photo-18", "Photo-19", "Photo-20", "Photo-21", "Photo-22", "Photo-23", , R.drawable.small_pier_440339_1280
"Photo-24", "Photo-25", "Photo-26", }; , R.drawable.small_purpursonnenhut_861592_1280
, R.drawable.small_roofs_919460_1280
, R.drawable.small_south_africa_927281_1280
, R.drawable.small_stone_arch_828730_1280
, R.drawable.small_sunset_815270_1280
, R.drawable.small_tangerine_850432_1280
, R.drawable.small_travel_857086_1280
, R.drawable.small_tree_779827_1280
, R.drawable.small_turtle_863336_1280};
5 - 47 5 - 48
The HorizontalScrollView Widget The HorizontalScrollView Widget
Example5: HorizontalScrollView Demo – MainActivity 3 of 5 Example5: HorizontalScrollView Demo – MainActivity 4 of 5
//frame-icons ( 100X100 thumbnails ) @Override
Integer[] largeImages = {R.drawable.large_blossom_918453_1280 protected void onCreate(Bundle savedInstanceState) {
, R.drawable.large_building_922529_1280 super.onCreate(savedInstanceState);
, R.drawable.large_cat_914110_1280 setContentView(R.layout.activity_main);
, R.drawable.large_church_648430_1280
, R.drawable.large_coffee_744151_1280 //bind GUI controls to Java classes
, R.drawable.large_coffee_917613_1280 txtMsg = (TextView) findViewById(R.id.txtMsg);
, R.drawable.large_dubrovnik_512798_1280 imageSelected = (ImageView) findViewById(R.id.imageSelected);
, R.drawable.large_egg_943413_1280
, R.drawable.large_firefighters_696167_1280 // this layout goes inside the HorizontalScrollView
, R.drawable.large_flower_870557_1280 scrollViewgroup = (ViewGroup) findViewById(R.id.viewgroup);
, R.drawable.large_football_888015_1280
, R.drawable.large_isolated_219954_1280 // populate the ScrollView
, R.drawable.large_jetty_593401_1280 for (int i = 0; i < items.length; i++) {
, R.drawable.large_jetty_598198_1280 //create single frames [icon & caption] using XML inflater
, R.drawable.large_paraglider_701440_1280 final View singleFrame = getLayoutInflater().inflate(
, R.drawable.large_pelican_336583_1280 R.layout.frame_icon_caption, null);
, R.drawable.large_pelican_901004_1280 //frame: 0, frame: 1, frame: 2, ... and so on
, R.drawable.large_pier_440339_1280 singleFrame.setId(i);
, R.drawable.large_purpursonnenhut_861592_1280 //internal plumbing to reach elements inside single frame
, R.drawable.large_roofs_919460_1280 TextView caption = (TextView) singleFrame.findViewById(R.id.caption);
, R.drawable.large_south_africa_927281_1280 ImageView icon = (ImageView) singleFrame.findViewById(R.id.icon);
, R.drawable.large_stone_arch_828730_1280
, R.drawable.large_sunset_815270_1280 //put data [icon, caption] in each frame
, R.drawable.large_tangerine_850432_1280 icon.setImageResource(thumbnails[i]);
, R.drawable.large_travel_857086_1280 caption.setText(items[i]);
, R.drawable.large_tree_779827_1280 caption.setBackgroundColor(Color.YELLOW);
, R.drawable.large_turtle_863336_1280};
//add frame to the scrollView
5 - 49 scrollViewgroup.addView(singleFrame); 5 - 50

The HorizontalScrollView Widget Image-Based GridViews (again…)


Example5: HorizontalScrollView Demo – MainActivity 5 of 5
Perhaps a more interesting version of the
//each single frame gets its own click listener
singleFrame.setOnClickListener(new View.OnClickListener() {
GridView control involves the displaying of
@Override images instead of text.
public void onClick(View v) {

String text = "Selected position: " + singleFrame.getId()


+ " " + items[singleFrame.getId()];
The following example illustrates how to use
txtMsg.setText(text); this control:
showLargeImage(singleFrame.getId());
}
});// listener
1. A screen shows an array of thumbnails.
}// for – populating ScrollView 2. The user makes her selection by tapping
}//onCreate on one of them.
//display a high-quality version of the image selected using thumbnails
3. The app displays on a new screen a bigger
protected void showLargeImage(int frameId) { & better image of the selected option.
Drawable selectedLargeImage = getResources()
.getDrawable(largeImages[frameId], getTheme()); //API-21 or newer 4. The programmer must provide a custom
imageSelected.setBackground(selectedLargeImage);
data adapter to manage the displaying of
//ALTERNATIVE SOLUTION (for APIs prior to API-21) thumbnails from the data set.
Drawable selectedLargeImage = ContextCompat.getDrawable(getApplication(),
largeImages[position]);
largeImageSelected.setImageDrawable(selectedLargeImage);

} This example is based on the tutorial:


} 5 - 51 5 - 52
http://developer.android.com/guide/topics/ui/layout/gridview.html
Using The GridView Widget to Show Images Using The GridView Widget to Show Images
Example6: GridView Images Demo – Layout1 (activity_main) Example6: GridView Images Demo – Layout2 (solo_picture)
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:padding="3dp"
android:padding="3dp" > android:orientation="vertical" >

<TextView <TextView
android:layout_width="match_parent" android:id="@+id/txtSoloMsg"
android:layout_height="wrap_content" android:layout_width="match_parent"
android:background="#ff0000ff" android:layout_height="wrap_content"
android:padding="3dp" android:textColor="@android:color/white"
android:text="Scrool screen, tap to choose" android:background="#ff0000ff" />
android:textColor="#ffffffff"
android:textSize="20sp" /> <ImageView
android:id="@+id/imgSoloPhoto"
<GridView android:layout_width="match_parent"
android:id="@+id/gridview" android:layout_height="0dip"
android:layout_width="match_parent" android:layout_gravity="center|fill"
android:layout_height="match_parent" android:layout_weight="2" />
android:layout_margin="1dp"
android:columnWidth="100dp" <Button
android:gravity="center" android:id="@+id/btnSoloBack"
android:horizontalSpacing="5dp" android:layout_width="100dip"
android:numColumns="auto_fit" android:layout_height="wrap_content"
android:stretchMode="columnWidth" android:layout_gravity="center_horizontal"
android:verticalSpacing="10dp" /> android:text="Back" />
</LinearLayout> </LinearLayout>

5 - 53 5 - 54

Using The GridView Widget to Show Images Using The GridView Widget to Show Images
Example6: GridView Images Demo – res/values/dimens/ Example6: App’s Structure – Eclipse’s Package Explorer
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>

<dimen name="gridview_size">100dp</dimen>
</resources>

Best Practice: Defining the GridView’s high and width dimensions on dips is safer than in pixels.
Later on, images can be automatically scaled to devices of various densities.

On the left:
int gridsize = context.getResources()
.getDimensionPixelOffset(R.dimen.gridview_size);
imageView.setLayoutParams(new
GridView.LayoutParams(gridsize, gridsize));

On the right:
imageView.setLayoutParams(new
GridView.LayoutParams(100, 100));

(see class MyImageAdapter) 5 - 55 5 - 56


Using The GridView Widget to Show Images Using The GridView Widget to Show Images
Example6: App’s Structure – Android Studio Example6: MainActivity 1 of 5
public class MainActivity extends Activity {

//GUI control bound to screen1 (holding GidView)


GridView gridview;

//GUI controls bound to screen2 (holding single ImageView)


TextView txtSoloMsg;
ImageView imgSoloPhoto;
Button btnSoloBack;

//in case you want to use-save state values


Bundle myOriginalMemoryBundle;

//frame captions
String[] items = {"Photo-1", "Photo-2", "Photo-3", "Photo-4", "Photo-5",
"Photo-6", "Photo-7", "Photo-8", "Photo-9", "Photo-10", "Photo-11",
"Photo-12", "Photo-13", "Photo-14", "Photo-15", "Photo-16", "Photo-17",
"Photo-18", "Photo-19", "Photo-20", "Photo-21", "Photo-22", "Photo-23",
"Photo-24", "Photo-25", "Photo-26", };

5 - 57 5 - 58

Using The GridView Widget to Show Images Using The GridView Widget to Show Images
Example6: MainActivity 2 of 5 Example6: MainActivity 3 of 5
//frame-icons ( 100X100 thumbnails ) //large images (high quality pictures)
Integer[] thumbnails = {R.drawable.small_blossom_918453_1280 Integer[] largeImages = {R.drawable.large_blossom_918453_1280
, R.drawable.small_building_922529_1280 , R.drawable.large_building_922529_1280
, R.drawable.small_cat_914110_1280 , R.drawable.large_cat_914110_1280
, R.drawable.small_church_648430_1280 , R.drawable.large_church_648430_1280
, R.drawable.small_coffee_744151_1280 , R.drawable.large_coffee_744151_1280
, R.drawable.small_coffee_917613_1280 , R.drawable.large_coffee_917613_1280
, R.drawable.small_dubrovnik_512798_1280 , R.drawable.large_dubrovnik_512798_1280
, R.drawable.small_egg_943413_1280 , R.drawable.large_egg_943413_1280
, R.drawable.small_firefighters_696167_1280 , R.drawable.large_firefighters_696167_1280
, R.drawable.small_flower_870557_1280 , R.drawable.large_flower_870557_1280
,R.drawable.small_football_888015_1280 ,R.drawable.large_football_888015_1280
,R.drawable.small_isolated_219954_1280 ,R.drawable.large_isolated_219954_1280
,R.drawable.small_jetty_593401_1280 ,R.drawable.large_jetty_593401_1280
,R.drawable.small_jetty_598198_1280 ,R.drawable.large_jetty_598198_1280
,R.drawable.small_paraglider_701440_1280 ,R.drawable.large_paraglider_701440_1280
,R.drawable.small_pelican_336583_1280 ,R.drawable.large_pelican_336583_1280
,R.drawable.small_pelican_901004_1280 ,R.drawable.large_pelican_901004_1280
,R.drawable.small_pier_440339_1280 ,R.drawable.large_pier_440339_1280
,R.drawable.small_purpursonnenhut_861592_1280 ,R.drawable.large_purpursonnenhut_861592_1280
,R.drawable.small_roofs_919460_1280 ,R.drawable.large_roofs_919460_1280
,R.drawable.small_south_africa_927281_1280 ,R.drawable.large_south_africa_927281_1280
,R.drawable.small_stone_arch_828730_1280 ,R.drawable.large_stone_arch_828730_1280
,R.drawable.small_sunset_815270_1280 ,R.drawable.large_sunset_815270_1280
,R.drawable.small_tangerine_850432_1280 ,R.drawable.large_tangerine_850432_1280
,R.drawable.small_travel_857086_1280 ,R.drawable.large_travel_857086_1280
,R.drawable.small_tree_779827_1280 ,R.drawable.large_tree_779827_1280
,R.drawable.small_turtle_863336_1280 }; ,R.drawable.large_turtle_863336_1280 };

5 - 59 5 - 60
Using The GridView Widget to Show Images Using The GridView Widget to Show Images
Example6: MainActivity 4 of 5 Example6: MainActivity 5 of 5

protected void onCreate(Bundle savedInstanceState) { private void showBigScreen(int position) {


super.onCreate(savedInstanceState); // show the selected picture as a single frame in the second layout
setContentView(R.layout.activity_main); setContentView(R.layout.solo_picture);
myOriginalMemoryBundle = savedInstanceState;
// plumbing – second layout
// setup GridView with its custom adapter and listener txtSoloMsg = (TextView) findViewById(R.id.txtSoloMsg);
gridview = (GridView) findViewById(R.id.gridview); imgSoloPhoto = (ImageView) findViewById(R.id.imgSoloPhoto);

gridview.setAdapter(new MyImageAdapter(this, thumbnails)); // set caption-and-large picture


txtSoloMsg.setText(" Position= " + position + " " + items[position]);
gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() { imgSoloPhoto.setImageResource( largeImages[position] );
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // set GO BACK button to return to layout1 (GridView)
showBigScreen(position); btnSoloBack = (Button) findViewById(R.id.btnSoloBack);
} btnSoloBack.setOnClickListener(new View.OnClickListener() {
});
@Override
public void onClick(View v) {
}//onCreate // redraw the main screen showing the GridView
onCreate(myOriginalMemoryBundle);
}

});

}// showBigScreen

}//Activity

5 - 61 5 - 62

Using The GridView Widget to Show Images Using The GridView Widget to Show Images
Example6: Custom Adapter - MyImageAdapter 1 of 2 Example6: Custom Adapter - MyImageAdapter 2 of 2
// This custom adapter populates the GridView with a visual
// representation of each thumbnail in the input data set. // create a view for each thumbnail in the data set
// It also implements a method -getView()- to access public View getView(int position, View convertView, ViewGroup parent) {
// individual cells in the GridView.

public class MyImageAdapter extends BaseAdapter{ ImageView imageView;

private Context context; // main activity’s context // if possible, reuse (convertView) image already held in cache
Integer[] smallImages; // thumbnail data set if (convertView == null) {
// new image in GridView formatted to:
public MyImageAdapter(Context mainActivityContext,
// 100x75 pixels (its actual size)
Integer[] thumbnails) {
// center-cropped, and 5dp padding all around
context = maiActivityContext;
smallImages = thumbnails;
imageView = new ImageView(context);
}
imageView.setLayoutParams( new GridView.LayoutParams(100, 75) );
// how many entries are there in the data set? imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
public int getCount() { imageView.setPadding(5, 5, 5, 5);
return smallImages.length;
} } else {
imageView = (ImageView) convertView;
// what is in a given 'position' in the data set? }
public Object getItem(int position) {
return smallImages[position]; imageView.setImageResource(smallImages[position]);
}
// what is the ID of data item in given 'position‘? return imageView;
public long getItemId(int position) { }
return position;
} }//MyImageAdapter
5 - 63 5 - 64
Using The GridView Widget to Show Images Using The GridView Widget to Show Images
Example6: Custom Adapter - MyImageAdapter 2 of 2 Results generated by Example6 running on different devices
// create a view for each thumbnail in the data set, add it to gridview
public View getView(int position, View convertView, ViewGroup parent) {

ImageView imageView;

// if possible, reuse (convertView) image already held in cache


if (convertView == null) {
// no previous version of thumbnail held in the scrapview holder
// define entry in res/values/dimens.xml for grid height,width in dips
// <dimen name="gridview_size">100dp</dimen>
// setLayoutParams will do conversion to physical pixels

imageView = new ImageView(context);


int gridsize = context.getResources().getDimensionPixelOffset(R.dimen.gridview_size);
imageView.setLayoutParams(new GridView.LayoutParams(gridsize, gridsize));
//imageView.setLayoutParams(new GridView.LayoutParams(100, 100));//NOT a good practice
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setPadding(5, 5, 5, 5);

} else {
imageView = (ImageView) convertView;
} Image taken from the Image displayed on a Nexus7 (1028x728) tablet.
imageView.setImageResource(smallImages[position]);
Emulator The GridView’s clause:
imageView.setId(position);
android:numColumns="auto_fit"
return imageView;
}//getView determines the best way to fill up each row.
5 - 65 5 - 66
}//MyImageAdapter

Using The GridView Widget to Show Images Using The GridView Widget to Show Images
Example6B: Example6B:
An Experiment - Changing from GridView to ListView An Experiment - Changing from GridView to ListView
Modify the previous example to show the set of thumbnails The new app should
in a ListView instead of a GridView. As before when a display the following
thumbnail is tapped a high-quality image is shown in a new screen. screens.

STEPS Observe the main


1. Modify the layout activity_main.xml. Change the tag <GridView … to screen arranges the
thumbnails in a
<ListView. Leave the rest unchanged.
ListView container.
2. In the main Java class, replace each reference to the GridView type with ListView.
The new statements should be: More on this issue on
ListView gridview; Example 8.
...
gridview = (ListView) findViewById(R.id.gridview);

3. In the custom Image adapter make the following change to indicate the new
imageView should be added to a ListView (instead that a GridView)
imageView.setLayoutParams(new ListView
.LayoutParams(100, 75) );
4. Keep the rest of the adapter code unchanged. 5 - 67 5 - 68
Using The Spinner Widget (again…) Using The Spinner Widget (again…)
Example7: Spinner Demo2 - Layout1 (activity_main)
This is a simple variation of the
<?xml version="1.0" encoding="utf-8"?>
previous example. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
A list of choices is offered through a android:orientation="vertical"
drop-down spinner control. android:padding="3dp" >

<TextView
android:layout_width="match_parent"
The user taps on a row and an android:layout_height="wrap_content"
image for the selected choice is android:background="#ff0000ff"
android:text="Car selector"
displayed on a new screen. android:textColor="#ffffffff"
android:textSize="20sp"
android:textStyle="bold" />

<Spinner
android:id="@+id/spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dip" />

</LinearLayout>

5 - 70

Using The Spinner Widget (again…) Using The Spinner Widget (again…)
Example7: Spinner Demo2 - Layout2 (solo_picture) Example7: Spinner Demo2 - MainActivity 1 of 3
<?xml version="1.0" encoding="utf-8"?> public class MainActivity extends Activity implements
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" AdapterView.OnItemSelectedListener {
android:layout_width="match_parent" // GUI controls in the main screen
android:layout_height="match_parent" Spinner spinner;
android:padding="3dp"
android:orientation="vertical" >
// GUI controls in the solo_picture screen
<TextView TextView txtSoloMsg;
android:id="@+id/txtSoloMsg" ImageView imageSelectedCar;
android:layout_width="match_parent" Button btnBack;
android:layout_height="wrap_content"
android:textStyle="bold" // captions to be listed by the spinner
android:textColor="#FFFFFFFF" String[] items = { "Select a vehicle", "car1", "car2", "car3", "car4",
android:padding="3dp" "car5", "car6", "car7", "car8" };
android:background="#ff0000ff" /> // object IDs of car pictures
Integer[] carImageArray = new Integer[] { R.drawable.car_photo_1,
<ImageView
android:id="@+id/imgSoloPhoto"
R.drawable.car_photo_2, R.drawable.car_photo_3,
android:layout_width="match_parent" R.drawable.car_photo_4, R.drawable.car_photo_5,
android:layout_height="0dip" R.drawable.car_photo_6, R.drawable.car_photo_7,
android:layout_gravity="center|fill" R.drawable.car_photo_8, };
android:layout_weight="2" /> Bundle myStateInfo;

<Button @Override
android:id="@+id/btnBack" protected void onCreate(Bundle savedInstanceState) {
android:layout_width="100dip" super.onCreate(savedInstanceState);
android:layout_height="wrap_content" myStateInfo = savedInstanceState;
android:layout_gravity="center_horizontal"
android:text="Back" /> setContentView(R.layout.activity_main);
</LinearLayout>
5 - 71 5 - 72
Using The Spinner Widget (again…) Using The Spinner Widget (again…)
Example7: Spinner Demo2 - MainActivity 2 of 3 Example7: Spinner Demo2 - MainActivity 3 of 3
spinner = (Spinner) findViewById(R.id.spinner);
spinner.setAdapter(new ArrayAdapter<String>(this, // next two methods implement the spinner listener
android.R.layout.simple_spinner_dropdown_item, @Override
items)); public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
spinner.setOnItemSelectedListener(this);
//ignore position 0. It holds just a label ("SELECT A VEHICLE...")
}// onCreate if (position > 0) {
// display screen showing image of the selected car showBigImage(position - 1);
private void showBigImage(int position) { }
// show the selected picture as a single frame }
setContentView(R.layout.solo_picture);
txtSoloMsg = (TextView) findViewById(R.id.txtSoloMsg); @Override
imageSelectedCar = (ImageView) findViewById(R.id.imgSoloPhoto); public void onNothingSelected(AdapterView<?> parent) {
txtSoloMsg.setText("Car selected: car-" + position); // DO NOTHING - needed by the interface
}
imageSelectedCar.setImageResource(carImageArray[position]);
}
btnBack = (Button) findViewById(R.id.btnBack);
btnBack.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// redraw the main screen showing the spinner
onCreate(myStateInfo);
}
});
}// showBigScreen

5 - 73 5 - 74

Custom-made ListViews Custom-made ListViews


Example8: Defining your own ListViews Example8: Create your own DataAdapter
• Android provides several predefined row layouts for displaying simple In order to customize a Data Adapter, you need to:
lists (such as: 1. Create a class extending the concrete ArrayAdapter class
android.R.layout.simple_list_item_1, 2. Override its getView(), and
android.R.layout.simple_list_item_2, etc ). 3. Construct (inflate) your rows yourself.
For each data
• However, there are occasions in which you want a particular disposition element supplied by
and formatting of elements displayed in each list-row. the adapter, the
method getView()
returns its ‘visible’
• In those cases, you should create your own subclass of a Data Adapter. public class MyCustomAdapter extends ArrayAdapter{
View.
// class variables go here ...
• The next example shows how to do that.
public MyCustomAdapter(...) { }

public View getView(...) { }

}//MyCustomAdapter

5 - 75 5 - 76
Custom-made ListViews Custom-made ListViews
Example8: Designing Custom-Rows Example8: Designing Custom-Rows
In our example each UI row will show an icon (on the left side) and text
following the icon to its right side.

Custom row consists


of icon & text

Custom row

Icon Text

5 - 77 5 - 78

Custom-made ListViews Custom-made ListViews


Example8: Custom ListView Demo - App’s Structure Example8: Layout1 – activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="3dp"
android:orientation="vertical" >

<TextView
android:id="@+id/txtMsg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ff0000ff"
android:text="Your selection is ..."
android:textColor="#ffffffff"
android:textSize="24sp"
android:textStyle="bold" />

<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>

</LinearLayout>
5 - 79 5 - 80
Custom-made ListViews Custom-made ListViews
Example8: Layout2 – custom_row_icon_label.xml Example8: Custom ListView Demo – MainActivity 1 of 3
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" public class MainActivity extends ListActivity {
android:layout_width="fill_parent" TextView txtMsg;
android:layout_height="wrap_content" // The n-th row in the list will consist of [icon, label]
android:orientation="horizontal" > // where icon = thumbnail[n] and label=items[n]
String[] items = { "Data-1", "Data-2", "Data-3", "Data-4", "Data-5",
<ImageView "Data-6", "Data-7", "Data-8", "Data-9", "Data-10", "Data-11",
android:id="@+id/icon" "Data-12", "Data-13", "Data-14", "Data-15" };
android:layout_width="100dp"
android:layout_height="75dp" Integer[] thumbnails = { R.drawable.pic01_small, R.drawable.pic02_small,
android:layout_marginRight="3dp" R.drawable.pic03_small, R.drawable.pic04_small,
android:src="@drawable/ic_launcher" /> R.drawable.pic05_small, R.drawable.pic06_small,
R.drawable.pic07_small, R.drawable.pic08_small,
<TextView R.drawable.pic09_small, R.drawable.pic10_small,
android:id="@+id/label" R.drawable.pic11_small, R.drawable.pic12_small,
android:layout_width="match_parent" R.drawable.pic13_small, R.drawable.pic14_small,
android:layout_height="75dp" R.drawable.pic15_small };
android:background="#22ffff00"
android:textSize="20sp" /> @Override
protected void onCreate(Bundle savedInstanceState) {
</LinearLayout> super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtMsg = (TextView) findViewById(R.id.txtMsg);

5 - 81 5 - 82

Custom-made ListViews Custom-made ListViews


Example8: Custom ListView Demo – MainActivity 2 of 3 Example8: Custom ListView Demo – MainActivity 3 of 3
// the arguments of the custom adapter are: class CustomIconLabelAdapter extends ArrayAdapter <String> {
// activityContex, layout-to-be-inflated, labels, icons Context context;
CustomIconLabelAdapter adapter = new CustomIconLabelAdapter( Integer[] thumbnails;
this, String[] items;
R.layout.custom_row_icon_label,
public CustomIconLabelAdapter( Context context, int layoutToBeInflated,
items,
String[] items, Integer[] thumbnails) {
thumbnails);
super(context, R.layout.custom_row_icon_label, items);
// bind intrinsic ListView to custom adapter
this.context = context;
setListAdapter(adapter);
this.thumbnails = thumbnails;
this.items = items;
}//onCreate
}
@Override
// react to user's selection of a row
public View getView(int position, View convertView, ViewGroup parent) {
@Override
protected void onListItemClick(ListView l, View v, int position, long id) { LayoutInflater inflater = ((Activity) context).getLayoutInflater();
super.onListItemClick(l, v, position, id); View row = inflater.inflate(R.layout.custom_row_icon_label, null);
String text = " Position: " + position + " " + items[position];
TextView label = (TextView) row.findViewById(R.id.label);
txtMsg.setText(text);
ImageView icon = (ImageView) row.findViewById(R.id.icon);
}//listener
label.setText(items[position]);
}//class icon.setImageResource(thumbnails[position]);
return (row);
}

5 - 83 }// CustomAdapter 5 - 84
Custom-made ListViews Using the SD card
Example8: The LayoutInflater Class Example 9: Storing Images on the SD card
(A Variation on Example5)

• The LayoutInflater class converts an XML layout specification into an In previous examples, images were kept in
actual tree of View objects. The objects inflated by code are appended main storage using the application’s
to the selected UI view. It typically works in cooperation with an memory space.
ArrayAdapter.
This time we will use the external disk
(SD-card) to store the app’s data (arguably
• A basic ArrayAdapter requires three arguments: current context, layout
a better space/speed tradeoff practice).
on which output rows are shown, source data items (data to feed the
rows). Assume the user has already transferred a
copy of the pictures to the SD folder
• The overridden getView() method inflates the row layout by
/Pictures/thumbnails/
custom allocating icons and text taken from data source in the user
designed row.
• Once assembled, the View (row) is returned.
• This process is repeated for each item supplied by the ArrayAdapter.
• See Appendix C for an example of a better built custom-adapter
using the ViewHolder design strategy.
5 - 85 5 - 86

Using the SD card Using the SD card In this app we use the
same layouts already
introduced in Example5

Example 9: Storing Images on the SD card Example 9: SD card Demo – MainActivity 1 of 4


(A Variation on Example5)
public class MainActivity extends Activity {

//GUI controls
The folder /Pictures/large/ contains a TextView txtMsg;
high-quality image for each thumbnail. ViewGroup scrollViewgroup;

These larger pictures are shown after the //each frame in the HorizontalScrollView has [icon, caption]
ImageView icon;
user makes a selection using the scroller. TextView caption;

//large image frame for displaying high-quality selected image


The text file /Pictures/names.txt contains ImageView imageSelected;
the caption associated to each picture. String[] items;
Data has been entered as a single line of int index;

comma separated strings (Something like @Override


protected void onCreate(Bundle savedInstanceState) {
Blossom, Building, Cat, Church, Coffee, ... ).
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

//plumbing: bind GUI controls to Java classes


txtMsg = (TextView) findViewById(R.id.txtMsg);
imageSelected = (ImageView) findViewById(R.id.imageSelected);

// this layout goes inside the HorizontalScrollView


scrollViewgroup = (ViewGroup) findViewById(R.id.viewgroup);

5 - 87 5 - 88
Using the SD card In this app we use the
same layouts already Using the SD card In this app we use the
same layouts already
introduced in Example5 introduced in Example5

Example 9: SD card Demo – MainActivity 2 of 4 Example 9: SD card Demo – MainActivity 3 of 4

try { TextView caption = (TextView) frame.findViewById(R.id.caption);


// Environment class allows access to your ‘MEDIA’ variables ImageView icon = (ImageView) frame.findViewById(R.id.icon);
String absolutePath2SdCard = Environment.getExternalStorageDirectory()
.getAbsolutePath(); // convert (jpg, png,...) file into a drawable
icon.setImageDrawable(Drawable.createFromPath(
//photo captions are held in a single-line comma-separated file singleThumbnailFile.getAbsolutePath()));
String pathPictureCaptionFile = absolutePath2SdCard + "/Pictures/names.txt";
File nameFile = new File(pathPictureCaptionFile); caption.setText(items[index]); A ViewGroup is a special view that can
Scanner scanner = new Scanner(nameFile); scrollViewgroup.addView(frame); contain other views (called children). The
String line = scanner.nextLine(); superclass ViewGroup is the base class for
items = line.split(","); frame.setId(index); layouts and views containers [From Android
Documentation].
//get access to the small thumbnails - polulate the horizontal scroller frame.setOnClickListener(new View.OnClickListener() {
String pathThumbnailsFolder = absolutePath2SdCard + "/Pictures/thumbnails/"; @Override
public void onClick(View v) {
File sdPictureFiles = new File(pathThumbnailsFolder); String text = "Selected position: " + frame.getId();
File[] thumbnailArray = sdPictureFiles.listFiles(); txtMsg.setText(text);
showLargeImage(frame.getId());
txtMsg.append("\nNum files: " + thumbnailArray.length); }
}); // listener
File singleThumbnailFile;
}// for
for (index = 0; index < thumbnailArray.length; index++) {
} catch (Exception e) {
singleThumbnailFile = thumbnailArray[index];
final View frame = getLayoutInflater().inflate(R.layout.frame_icon_caption, null); txtMsg.append("\nError: " + e.getMessage());
}

5 - 89 }//onCreate 5 - 90

Using the SD card In this app we use the


same layouts already
introduced in Example5

Example 9: SD card Demo – MainActivity 4 of 4


List-Based Widgets
//display a high-quality version of the selected thumbnail image
protected void showLargeImage(int frameId) {

String pathLargePictureFolder = Environment.getExternalStorageDirectory()


.getAbsolutePath() + "/Pictures/large/";

// convert SD image file(jpg, png,...) into a drawable, then show into ImageView
File sdLargePictureFolder = new File(pathLargePictureFolder);
File[] largePictureArray = sdLargePictureFolder.listFiles();
File largeImageFile = largePictureArray[frameId];

imageSelected.setImageDrawable(Drawable.createFromPath(
largeImageFile.getAbsolutePath()));

}//ShowLargeImage

}//Activity

Images made with the “Device Frame Generator Tool”, available at


http://android-ui-utils.googlecode.com/hg/asset-studio/dist/device-frames.html
5 - 91
Appendix A: Predefined Android Resources Appendix A: Predefined Android Resources
Android SDK includes a number of predefined layouts & styles. Some of those Android’s Predefined Layouts
resources can be found in the folders: This is the definition of: simple_spinner_dropdown_item in which a single
C:\ Your-Path \Android\android-sdk\platforms\android-xx\data\res\layout row holding a radio-button and text is shown.
C:\ Your-Path \Android\android-sdk\platforms\android-xx\data\res\values\styles.xml Link:
http://code.google.com/p/pdn-slatedroid/source/browse/trunk/eclair/frameworks/base/core/res/res/layout/
Example: simple_spinner_dropdown_item.xml?r=44
The following is the definition of the layout called:
<?xml version="1.0" encoding="utf-8"?>
android.R.layout.simple_list_item_1. It consists of a single TextView field <!--
named “text1”, its contents are centered, large font, and some padding. ** Copyright 2008, The Android Open Source Project
** etc...
<!-- Copyright (C) 2006 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file -->
except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
<CheckedTextView
CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the xmlns:android="http://schemas.android.com/apk/res/android"
License. -->
android:id="@android:id/text1"
<?xml version="1.0" encoding="utf-8"?> style="?android:attr/spinnerDropDownItemStyle"
<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:singleLine="true"
android:id="@android:id/text1" android:layout_width="match_parent"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:layout_height="wrap_content"
android:gravity="center_vertical" android:ellipsize="marquee" />
android:minHeight="?android:attr/listPreferredItemHeight"
android:paddingLeft="6dip"
android:textAppearance="?android:attr/textAppearanceLarge" /> 5 - 93 5 - 94

Appendix B: EditText Boxes & Keyboarding Appendix B: EditText Boxes & Keyboarding

When the user taps on an


Keyboarding data into Android’s
EditText box, the Input Media
applications is functionally dependent of
Framework (IMF) provides
the hardware present in the actual device.
access to

1. a hard (or real) keyboard (if


one is present) or

2. a soft (or virtual) keyboard


known as IME that is the
most appropriated for the
current input type.
Sliding Window in This device has a
this unit exposes a permanently You may close the virtual
hard keyboard. exposed hard keyboard by tapping the
keyboard and
Input accepted from Virtual keyboard hardware BackArrow key.
Stylus pen IME: Input Media Editor
and/or voice recognition IME Soft
appropriate for Keyboard
handwriting 5 - 95 5 - 96
Appendix B: EditText Boxes & Keyboarding Appendix B: EditText Boxes & Keyboarding
Java Usage – inpuType Classes
Telling Android what data to expect editTextBox.setInputType( android.text.InputType.XXX );

TextViews can use either XML elements or Java code to tell the type of
textual data they should accept. For example:
XML
android:inputType="phone"

Java

editTextBox.setInputType(
android.text.InputType.TYPE_CLASS_PHONE);

Knowing the inputType has an impact on virtual keyboards (the software can
expose the best layout for the current input class)

5 - 97 5 - 98

Appendix B: EditText Boxes & Keyboarding Appendix B: EditText Boxes & Keyboarding
Example10: Using multiple XML attributes
XML Usage – inputType Classes android:inputType="text|textCapWords"
<EditText
... <?xml version="1.0" encoding="utf-8"?>
<LinearLayout Use “pipe” symbol |
android:inputType=“numberSigned|numberDecimal” android:layout_width="match_parent" to separate the
... /> android:layout_height="match_parent"
android:background="#ffcccccc" options.
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android" >
In this example a
<TextView soft text keyboard
android:layout_width="match_parent"
android:layout_height="wrap_content" will be used.
android:background="#ff0000ff"
android:text="inputType: text|textCapWords"
android:textStyle="bold" Each word will be
android:textSize="22sp" />
capitalized.
<EditText
android:id="@+id/editTextBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dip"
android:textSize="18sp"
Reference: android:inputType="text|textCapWords" />
http://developer.android.com/reference/and </LinearLayout>
roid/R.styleable.html#TextView_inputType 5 - 99 5 - 100
Appendix B: EditText Boxes & Keyboarding Appendix B: EditText Boxes & Keyboarding

Example10: Using android:inputType= " text|textCapWords" Example10: Using android:inputType= " text|textCapWords"

After tapping the EditText After first letter is typed the After entering space the English and Spanish are the You may speed up typing by Selected word is introduced in
box to gain focus, a soft keyboard automatically keyboard repeats cycle user’s selected languages tapping on an option from the EditText box
keyboard appears showing switches to LOWER case mode beginning with UPPER case, in this device the list of suggested words
CAPITAL letters then LOWER case letters. 5 - 101 (bilingual choices) 5 - 102

Appendix B: EditText Boxes & Keyboarding Appendix B: EditText Boxes & Keyboarding
Example 11: Using
Example 12: Using Example 13: Using
android:inputType="number|numberSigned|numberDecimal"
android:inputType="textPassword" android:inputType="textEmailAddress"

1. The keyboard displays numbers. Soft keyboard


2. Non-numeric keys (such as !@#$%&*?/_) are shows characters
used in email
visible but disable. addresses (such as
3. Only valid numeric expressions can be entered. letters, @, dot).
4. Type number|numberSigned accepts integers.
5. Type numberDecimal accepts real numbers. Click on [?123 ]
key (lower-left) for
additional
characters
Assume the EditText field is named: editTextBox,
In Java code we could at run-time set the input
method by issuing the command:
editTextBox.setInputType(
android.text.InputType.TYPE_CLASS_NUMBER | • The keyboard displays all possible keys.
android.text.InputType.TYPE_NUMBER_FLAG_SIGNED); • Current character is briefly displayed for verification purposes.
• The current character is hidden and a heavy-dot is displayed.
5 - 103 5 - 104
Appendix B: EditText Boxes & Keyboarding Appendix B: EditText Boxes & Keyboarding

Example 14: Using android:inputType="phone" Example 15: Using android:inputType="time"


Soft keyboard displays
the layout of a typical
phone keypad plus
additional non digit Soft keyboard displays a numerical layout.
symbols such as:
( ) . / Pause Wait # - + Only digits and colon-char “:“ can be used.

Additional symbols

5 - 105 5 - 106

Appendix B: EditText Boxes & Keyboarding Appendix B: EditText Boxes & Keyboarding
Example 16: Using android:inputType="time" Example 16: Using android:inputType="time"
When clicked, the Auxiliary button DONE Other options for
will removed the keyboard from the screen android:imeAction=“. . .”
(default behavior).
are
You may change the button’s caption and
set a listener to catch the click event on the
Auxiliary button. To do that add the
following entry to your XML specification of
the EditText box:

android:imeAction="actionSend"

Later, your Java code could provide an


implementation of the method:

editTextBox
.setOnEditorActionListener()
to do something with the event.

5 - 107 5 - 108
Appendix B: EditText Boxes & Keyboarding Appendix B: EditText Boxes & Keyboarding
Disable Soft Keyboarding on an EditText View
Example 17: Using android:inputType="datetime"
• To disable the action of the soft keyboard on an EditText
you should set its input type to null, as indicated below:
editTextBox.setInputType( InputType.TYPE_NULL );
• To temporarily hide the virtual keyboard, call the following method:
Soft keyboard displays a numerical layout.
public void hideVirtualKeyboard() {
Context context = getActivity().getApplicationContext();
Only digits and date/time valid characters ((InputMethodManager) context
are allowed. .getSystemService(Activity.INPUT_METHOD_SERVICE))
.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);
Examples of valid dates are: }
12/21/2012 12:12
• To display the virtual keyboard, call the method:
12/31/2011
12:30 public void showVirtualKeyboard() {
Context context = getActivity().getApplicationContext();
((InputMethodManager) context
.getSystemService(Activity.INPUT_METHOD_SERVICE))
.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);
}
5 - 109 5 - 110

Appendix C. Custom List Supported by a BaseAdapter Appendix C. Custom List Supported by a BaseAdapter
In this example a list holding rows showing multiple lines of text and images, is
populated with a custom made BaseAdapter that uses the ViewHolder strategy for
better performance.
An onClick listener is set to recognize the
user’s tapping on the image to the right side,
and another listener is set for clicking
anything from the rest of the row.
Click
on
Click image
on
row

The app consists of two classes: MainActivity and


CustomBaseAdapter. It has two layouts:
activity_main showing the list (see image on the
right) and list_row_gui describing the structure of
individual rows. Test data is placed in a separate
class called DATABASE.
5 - 111 5 - 112
Appendix C. Custom List – ViewHolder Pattern Appendix C. Custom List – activity_main.xml
The figure below is from “Performance Tips for Android’s ListView” by Lucas Rocha Layout activity_main.xml shows a ListView.
http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/ [Dec, 2014].
It shows a set of rows presented to the user inside a ListView container. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
When a row gets out of sight, android:layout_height="match_parent"
the memory of its layout is android:orientation="vertical"
android:padding="16dp" >
saved in a scrapview collection
silently kept by the ListView. <ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
If the row comes back to a android:layout_height="wrap_content" >
</ListView>
visible state, you may reuse its
scrapview skeleton instead of </LinearLayout>

redoing the row from scratch.

The strategy of reusing these scrapviews is known as the ViewHolder Design Pattern.
It cuts down on the number of times you have to inflate a row-layout and then get
access to its internal widgets by calling the ‘findViewById()’ method.
When reusing the scrapviews (made available as ‘convertView’) all you need to do is
move the appropriate data to the internal widgets and set their onClick listeners.
5 - 113 5 - 114

Appendix C. Custom List – list_row_gui.xml 1 of 2 Appendix C. Custom List – list_row_gui.xml 2 of 2

Layout list_gui_row.xml shows a custom-made row holding two lines of text and two Layout list_gui_row.xml shows a custom-made row holding two lines of text and two
images. images.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" <TextView
android:layout_width="match_parent" android:id="@+id/rowTextView2"
android:layout_height="match_parent" android:layout_width="wrap_content"
android:orientation="horizontal" android:layout_height="wrap_content"
android:padding="16dp" > android:text="@string/text2"
android:textAppearance="?android:attr/textAppearanceSmall" />
<ImageView </LinearLayout>
android:id="@+id/rowImageView1"
android:layout_width="50dp" <ImageView
android:layout_height="50dp" android:id="@+id/rowImageView2"
android:contentDescription="@string/image_left" android:layout_width="50dp"
android:src="@drawable/ic_pic_left" /> android:layout_height="50dp"
<LinearLayout android:contentDescription="@string/image_right"
android:layout_width="0dp" android:src="@drawable/ic_launcher" />
android:layout_height="match_parent"
android:layout_marginLeft="20dp" </LinearLayout>
android:layout_weight="2"
android:orientation="vertical" >
<TextView
android:id="@+id/rowTextView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/text1"
android:textAppearance="?android:attr/textAppearanceLarge" /> 5 - 115 5 - 116
Appendix C. Custom List – MainActivity.java 1 of 1 Appendix C. Custom List – CustomBaseAdapter.java 1 of 5

The main activity exposes a ListView. A custom adapter is tied to the ListView. The The getView method in this extended BaseAdapter inflates a supplied row layout, gets
adapter gets a reference to a test ‘database’ and the custom row layout. access to its internal widgets, fills them with data and set listeners on some of them.
public class CustomBaseAdapter extends BaseAdapter {
public class MainActivity extends ActionBarActivity {
DATABASE database_records; Context context;
int layoutToBeInflated;
@Override List<DATABASE.DbRecord> dbList;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); public CustomBaseAdapter(Context context, List<DATABASE.DbRecord>
setContentView(R.layout.activity_main); databaseList, int resource) {
this.context = context;
ListView listview = (ListView) findViewById(R.id.listView1); this.dbList = databaseList;
layoutToBeInflated = resource;
//create an instance of our fake database: {[text1, text2, icon]} }
List database = new DATABASE().dbList;
@Override
CustomBaseAdapter adapter = new CustomBaseAdapter( this, public int getCount() {
database, return dbList.size();
R.layout.list_row_gui }
);
listview.setAdapter(adapter); @Override
public DATABASE.DbRecord getItem(int position) {
return dbList.get(position);
}//onCreate }
5 - 117 5 - 118

Appendix C. Custom List – CustomBaseAdapter.java 2 of 5 Appendix C. Custom List – CustomBaseAdapter.java 3 of 5

@Override // plumbing - provide access to each widget in the inflated layout


public long getItemId(int position) { // (two images & two lines of text)
return position; holder = new MyViewHolder();
} holder.textview1 = (TextView) row.findViewById(R.id.rowTextView1);
holder.textview2 = (TextView) row.findViewById(R.id.rowTextView2);
@Override holder.imageview1 = (ImageView) row.findViewById(R.id.rowImageView1);
public View getView(final int position, View convertView, ViewGroup parent) { holder.imageview2 = (ImageView) row.findViewById(R.id.rowImageView2);

// use View-Holder pattern to reduce calls to inflate, findViewById // identify this row with the POJO holder just created
// holder is a POJO for the GUI rows [textview1,textview2, img1, img2] row.setTag(holder);
MyViewHolder holder;
} else {
// hopefully convertView is a scrapview already made (but out of sight) // row was already created- no need to inflate and invoke findViewById
View row = convertView; // getTag() returns the object originally stored in this view
holder = (MyViewHolder) row.getTag();
// has this row-layout been already created? }
if (row == null) {
// first time this row has to be created: (1) inflate custom layout // enter(or restore) data that goes in this frame (from database 'position')
// holding images and text, (2) invoke findViewById to access its DATABASE.DbRecord dbRec = getItem(position);
// sub-components holder.textview1.setText(dbRec.text1);
LayoutInflater inflater = ((Activity) context).getLayoutInflater(); holder.textview2.setText(dbRec.text2);
holder.imageview1.setImageResource(dbRec.img1);
row = inflater.inflate(layoutToBeInflated, null); holder.imageview2.setImageResource(R.drawable.ic_launcher);

holder = new MyViewHolder();


5 - 119 5 - 120
Appendix C. Custom List – CustomBaseAdapter.java 4 of 5 Appendix C. Custom List – CustomBaseAdapter.java 5 of 5

// EXTRA: individual listeners go here - if you need only a single


// listener for the entire row, put it into ActivityMain. // A humble POJO holding references to GUI widgets that are part of rows
// shown by the list. They have already been made and their IDs are known,
// This is a CLICK listener on top of the right icon (imageview2) // therefore there is no need to issue 'findViewById' calls again.
// (for example, here you start an intent to call phone[position])
holder.imageview2.setOnClickListener(new OnClickListener() { public class MyViewHolder {
@Override TextView textview1;
public void onClick(View v) { TextView textview2;
Toast.makeText(context, ImageView imageview1;
"(RIGHT) IMAGE CLICKED - " + position, 1).show(); ImageView imageview2;
} }
});

// row listener (user clicks on any other part of the row) }// CustomMadeListener
row.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context,
"ROW CLICKED - " + position, 1).show();
}
});

return row;

}// getView
5 - 121 5 - 122

Appendix C. Custom List – DATABASE.java 1 of 2 Appendix C. Custom List – DATABASE.java 2 of 2

public class DATABASE { // TEST DATABASE


public String[] text1array = { "data-item1-01", "data-item1-02", public class DbRecord {
"data-item1-03", "data-item1-04", "data-item1-05", "data-item1-06", public String text1;
"data-item1-07", "data-item1-08", "data-item1-09", "data-item1-10", public String text2;
"data-item1-11", "data-item1-12", "data-item1-13", "data-item1-14", public Integer img1;
"data-item1-15" };
public String[] text2array = { "data-item2-01", "data-item2-02", public DbRecord(String text1, String text2, Integer img1) {
"data-item2-03", "data-item2-04", "data-item2-05", "data-item2-06", this.text1 = text1;
"data-item2-07", "data-item2-08", "data-item2-09", "data-item2-10", this.text2 = text2;
"data-item2-11", "data-item2-12", "data-item2-13", "data-item2-14", this.img1 = img1;
"data-item2-15" }; }
public Integer[] icon1array = { csu.matos.custom2.R.drawable.pic01_small, }//dbRecord
csu.matos.custom2.R.drawable.pic02_small,
csu.matos.custom2.R.drawable.pic03_small, // dbList is a 'database' holding a list of DbRecods:[string,string,int]
csu.matos.custom2.R.drawable.pic04_small, public ArrayList<DbRecord> dbList = new ArrayList<DbRecord>();
csu.matos.custom2.R.drawable.pic05_small,
csu.matos.custom2.R.drawable.pic06_small, // populate the 'database' with data items
csu.matos.custom2.R.drawable.pic07_small, public DATABASE () {
csu.matos.custom2.R.drawable.pic08_small, for(int i=0; i<text1array.length; i++){
csu.matos.custom2.R.drawable.pic09_small, dbList.add(new DbRecord(text1array[i], text2array[i], icon1array[i]) );
csu.matos.custom2.R.drawable.pic10_small, }
csu.matos.custom2.R.drawable.pic11_small, }
csu.matos.custom2.R.drawable.pic12_small,
csu.matos.custom2.R.drawable.pic13_small, }// DATABASE
csu.matos.custom2.R.drawable.pic14_small,
csu.matos.custom2.R.drawable.pic15_small, }; 5 - 123 5 - 124

You might also like