Tap on a photo to bring up a piece of
Toast
containing a bigger version of the photo.
The photos in the
GridView
,
and the
spacing
between them,
are the same size (measured in inches)
on each device.
The first two screenshots are on a Samsung Galaxy 5S in portrait orientation.
Its dimensions are 1080 × 1920 pixels at 480 pixels per inch,
so the screen width is 1080/480 inches
= 2¼ inches
= 160 * 2¼
dp
= 360
dp.
But the
GridView
is contained in a
RelativeLayout
that has a total of 32
dp
of padding on its left and right
(see
values/dimens.xml
),
leaving us with only
360 − 32 = 328
dp.
Each column is 60
dp
wide,
and the spacing bewteen the columns is 10
dp
wide,
so we have room for four (but not five) columns:
60 + 10 + 60 + 10 + 60 + 10 + 60 = 270 ≤ 328.
The third screenshot is on an Azpen A727 tablet in landscape orientation.
Its dimensions are 800 × 480 pixels at 120 pixels per inch,
so the screen width is 800/120 inches
= 6⅔ inches
= 160 * 6⅔
dp
= 1066⅔
dp.
But the
GridView
is contained in a
RelativeLayout
that has a total of 128
dp
of padding on its left and right
(see
values-w820dp/dimens.xml
),
leaving us with only
1066⅔ − 128 = 938⅔
dp.
Each column is 60
dp
wide,
and the spacing bewteen the columns is 10
dp
wide,
so we have room for 13 (but not 14) columns:
60 + 10 +
60 + 10 +
60 + 10 +
60 + 10 +
60 + 10 +
60 + 10 +
60 + 10 +
60 + 10 +
60 + 10 +
60 + 10 +
60 + 10 +
60 + 10 +
60
= 900 ≤ 938⅔
In
Spinner
and
ListView,
our
Adapter
was an off-the-shelf
ArrayAdapter
.
An
ArrayAdapter
converts each data item to a
String
(with the Java method
toString
)
and puts the result in a
TextView
.
But the data items in this app are images,
so we will have to use a different class of
Adapter
.
In fact, we will have to write our own class of
Adapter
.
ImageAdapter
.
The most important methods of the adapter are
getCount
,
which returns a number,
and
getView
,
which returns a
View
.
In this app, the
View
is an
ImageView
.
Class
ImageView
is a subclass of
View
specialized for displaying an image,
just as a
TextView
is specialized for displaying text.
The
getView
method receives a
position
argument in the range 0 to 99 inclusive.
How can it create 100
ImageView
s
when we have only eight photos?
We put
sample_0.jpg
into
ImageView
number 0, 8, 16, 24, 32, etc.
We put
sample_1.jpg
into
ImageView
number 1, 9, 17, 25, 33, etc.
We put
sample_2.jpg
into
ImageView
number 2, 10, 18, 26, 34, etc.
Et cetera.
getCount
and
getView
are called by the
AdapterView
.
In this app, the
AdapterView
is a
GridView
.
See
Grid
View.
One method that is not called is
getItem
,
but I wrote it anyway just for completeness.
getItem
calls the recently deprecated one-argument
getDrawable
rather than the newfangled two-argument
getDrawable
,
because I want my app to be able to run on older Android devices.
See the
minSdkVersion
in
build.gradle
.
In addition to plugging an
Adapter
into the
GridView
,
we also plug an
AdapterView.OnItemClickListener
into the
GridView
to make something happen when an image is clicked.
As usual, the “something”
will be to pop up a
Toast
.
Until now, our
Toast
s
have contained only text.
This time,
the
Toast
will contain an
ImageView
.
MainActivity.java
ImageAdapter.java
R.java
creates the
int
variables
R.drawable.sample_0
,
R.drawable.sample_1
,
etc.
activity_main.xml
.
The
RelativeLayout
that occupies the whole screen
has been replaced by a
GridView
that usually occupies the whole screen.
dp
are
density-independent
pixels,
160 per inch.
values/dimens.xml
values-w820dp/dimens.xml
.
In landcape oriention,
the screen width of my Azpen A727 tablet is 800 pixels =
800/120 inches = 6⅔ inches = 160 * 6⅔
dp
= 1066⅔
dp.
AndroidManifest.xml
build.gradle
(Module: app)
sample_0.jpg
(213 × 285)sample_1.jpg
(285 × 213)sample_2.jpg
(285 × 191)sample_3.jpg
(285 × 213)sample_4.jpg
(285 × 190)sample_5.jpg
(191 × 285)sample_6.jpg
(285 × 213)sample_7.jpg
(213 × 285)sample_thumb_0.jpg
(45 × 60).
These thumbnails are not used.
After I added them to the project,
I discovered they were too small for the contemporary number of dpi.
sample_thumb_1.jpg
(60 × 45)
sample_thumb_2.jpg
(60 × 40)
sample_thumb_3.jpg
(60 × 45)
sample_thumb_4.jpg
(60 × 40)
sample_thumb_5.jpg
(40 × 60)
sample_thumb_6.jpg
(60 × 45)
sample_thumb_7.jpg
(45 × 60)
In the Android Studio
project
view,
select the folder
app/java/edu.nyu.scps.gridview
.
File →
New… →
Java Class
Create New Class
Name: ImageAdapter
Kind: Class
OK
In the new file
ImageAdapter.java
,
click on the word
ImageAdapter
and pull down
Code → Implement Methods…
Select the four methods that need to be implemented and press OK.
In the Macintosh Finder,
control-click on each
.jpg
file and select Copy.
In the Android Studio
project
view, highlight
the folder
app/res/drawable
,
control-click on it,
and select Paste.
A
GridView
keeps its
View
s
in the order that you determine,
but it does not necessarily keep a
View
in the same row and column.
For example,
the number of columns can change when you switch devices
(see the above screenshots)
or when you change the orientation of a device.
Use a
TableLayout
when you want to keep each
View
in the same row and column.
Use a
GridView
when you don’t care about keeping a
View
in the same row and column.
Every row in a
GridView
contains the same number of
View
s,
except possibly the last.
But each row of a
TableLayout
can have a different number of
View
s.
TableLayout
in
ApiDemos:
Views → Layouts → TableLayout
GridView
of all the icons of all the apps on the Android device.
See
action.MAIN
and
category.LAUNCHER
in the
AndroidManifest.xml
file.
ApiDemos/src/com/example/android/apis/view/Grid1.java
BaseAdapter
named
Grid1.AppsAdapter
that puts each icon into an
ImageView
.
ApiDemos/res/layout/grid_1.xml
GridView
.
GridView
of small photos of dogs.
ApiDemos/src/com/example/android/apis/view/Grid2.java
BaseAdapter
named
Grid2.ImageAdapter
that puts each photo into an
ImageView
.
The photos come from resources.
ApiDemos/res/layout/grid_2.xml
GridView
.
ApiDemos/res/drawable/sample_thumb_0.jpg
(45 × 60)
ApiDemos/res/drawable/sample_thumb_1.jpg
(60 × 45)
ApiDemos/res/drawable/sample_thumb_2.jpg
(60 × 40)
ApiDemos/res/drawable/sample_thumb_3.jpg
(60 × 45)
ApiDemos/res/drawable/sample_thumb_4.jpg
(60 × 40)
ApiDemos/res/drawable/sample_thumb_5.jpg
(40 × 60)
ApiDemos/res/drawable/sample_thumb_6.jpg
(60 × 45)
ApiDemos/res/drawable/sample_thumb_7.jpg
(45 × 60)
GridView
of all the icons of all the apps on the Android device.
Hold down an icon for a second to select it;
the tap other icons to select them.
ApiDemos/src/com/example/android/apis/view/Grid3.java
BaseAdapter
named
Grid1.AppsAdapter
that puts each icon into an
ImageView
.
Also plugs a
AbsListView.MultiChoiceModeListener
into the
GridView
.
ApiDemos/res/layout/grid_1.xml
GridView
.
ApiDemos/res/values/colors.xml
blue
.
ImageView
in the
Toast
.
The
ImageView
and
TextView
are contained in the simplest type of
layout,
a
FrameLayout
.
After creating the
ImageView
,
insert the following code.
TextView textView = new TextView(MainActivity.this); textView.setBackgroundColor(Color.TRANSPARENT); textView.setTextColor(Color.GREEN); textView.setText(" position = " + position + ", id = " + id); FrameLayout frameLayout = new FrameLayout(MainActivity.this); frameLayout.addView(imageView); frameLayout.addView(textView); //Insert the FrameLayoutToast. Toast toast = new Toast(MainActivity.this); toast.setView(frameLayout); toast.show();