Android GridView a tutorial
A GridView
is simply a grid of views , it is a subclass of AbsListView, so the methods and fields defined for AbsListView
, apply to a GridView
. Another subclass of AbsListView
is Listview.
This tutorial will show how to create a GridView
, the final product is shown below .
Start by defining the layout of the MainActivity
activity_main.xml
, which contains a single child , the GridView
:
<!-- activity_main.xml in the layout folder .-->
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<GridView
android:id="@+id/gridView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="3"
android:stretchMode="columnWidth"
android:horizontalSpacing="8dp"
android:verticalSpacing="16dp"
android:listSelector="@drawable/grid_item_selected"
android:padding="8dp" >
</GridView>
</FrameLayout>
Theandroid:stretchMode
attribute is related to the remaining space , and is used to specify how the remaining available space is divided . By default it has a value of android:stretchMode="columnWidth"
, which is columns will be equally stretched . If set to android:stretchMode="none"
, then the remaining space is not stretched , if set to spacingWidth
, then the remaining space is stretched equally between columns , if set to spacingWidthUniform
, then the remaining space is divided equally around and between the columns .
Theandroid:numColumns
attribute is used to specify the number of columns . If set to android:numColumns="auto_fit"
, and no android:columnWidth
attribute is set , then the number of columns is set to 2
. If set to android:numColumns="auto_fit"
andandroid:columnWidth
is set to a value , as in android:columnWidth="20dp"
, then the number of column is calculated based on the available remaining space , while guarding the set horizontal spacing , in other words , factoring out horizontal spacing .
If the number of columns is set , then it is the set number of columns . If the number of columns is not set or is set to a negative value , then it is set to 1
.
android:stretchMode
is always applied as specified , so for example , setting a number of column , and no column width , if the stretchMode
is set to columnWidth
, then the available space , factoring out any horizontal spacing , is divided evenly between the set number of columns .
Horizontal spacing between columns , and vertical spacing between rows , can be set using android:horizontalSpacing
, and android:verticalSpacing
.
Theandroid:listSelector
is used to specify an effect , when an item in the grid is selected . In this example , a drawable android:listSelector="@drawable/grid_item_selected"
has been specified as the effect , which is setting the background color to orange . The drawable has been defined in the drawable folder , and has the following code :
<!-- grid_item_selected.xml in the drawable folder .-->
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="@android:color/holo_orange_light"/>
</selector>
Having defined the GridView
and its attributes , the layout for an item in the GridView
must be defined , as follows :
<!-- grid_item.xml in the layout folder .-->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/ivPhoto"
android:layout_width="match_parent"
android:layout_height="90dp"
android:background="@android:color/black" />
<TextView
android:id="@+id/tvLabel"
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp" />
</LinearLayout>
Having defined the layout for an item , a controller must be created , to manage the items of a GridView
, as for example , their creation , and data connection . This is done by extending the BaseAdapter
class , as follows :
/* GridView_Controller.java */
package com.twiserandom.mobileapps.demo.gridview;
import android .content .Context;
import android .view .View;
import android .view .ViewGroup;
import android .widget .BaseAdapter;
import android .widget .ImageView;
import android .widget .TextView;
public class
GridView_Controller
extends BaseAdapter {
private int image_ids [ ] = {R .drawable .img_001_forest , R .drawable .img_002_mountain ,
R .drawable .img_003_mountain_close_view ,
R .drawable .img_004_mountain_sea ,
R .drawable .img_005_sea_sand };
private String image_label [ ] = {"Forest" , "Mountain" ,
"Mountain Close View" ,
"Mountain Sea",
"Sea Sand" };
private Context context;
GridView_Controller
(Context context ){
this .context = context; }
class Image {
String image_name;
int image_id;
Image
(String image_name , int image_id ){
this .image_name = image_name ;
this .image_id = image_id ; } }
@Override
public int
getCount
( ){/* Return the data
Count */
return image_ids .length ; }
@Override
public Object
getItem
(int position ){/* Return an object
representing the data at the
given position , to be retrieved
later on , for example when
handling click events . Can
return null , if have nothing
to pass on .*/
return new Image (image_label [position ] , image_ids [position ] );}
@Override
public long
getItemId
(int position ){/* Can return -1 , or 0 ,
if do not have own ids to pass on .
If have own generated identifiers ,
they can be passed here , to be retrieved
later on , for example when handling
click events .*/
return image_ids [position ]; }
@Override
public View
getView
(int position , View convertView , ViewGroup parent ){/*
Return an item's View .*/
if (convertView == null ){/* Views are recyclable , so
this means they are reusable , so only inflate
a view if it is not null .*/
convertView = View .inflate (context , R .layout .grid_item , null ); }
ImageView ivPhoto = convertView .findViewById (R .id .ivPhoto );
ivPhoto .setImageResource (image_ids [position ] );
TextView tvLabel = convertView .findViewById (R .id .tvLabel );
tvLabel .setText (image_label [position ] );
return convertView; } }
Now it is time to create the MainActivity
class , in the MainActivity.java
file . This class will connect the controller to the GridView
, and it will set an OnItemClickListener
, for the GridView
.
/* MainActivity.java */
package com .twiserandom .mobileapps .demo .gridview;
import androidx .appcompat .app .AppCompatActivity;
import android .os .Bundle;
import android .view .View;
import android .widget .AdapterView;
import android .widget .GridView;
import android .widget .Toast;
public class
MainActivity
extends AppCompatActivity {
@Override
protected void
onCreate
(Bundle savedInstanceState ){
super .onCreate (savedInstanceState );
setContentView (R .layout .activity_main );
GridView gridView = findViewById (R .id .gridView );
gridView .setAdapter (new GridView_Controller (this ) ); /* Connect
the controller to the GridView .*/
gridView .setOnItemClickListener (new AdapterView .OnItemClickListener ( ){
@Override
public void
onItemClick
(AdapterView parent , View view , int position , long id ){
GridView_Controller .Image image =
(GridView_Controller .Image ) parent .getItemAtPosition (position );/*
Get the attached data .*/
Toast .makeText (MainActivity .this ,
image .image_name + " " + id , Toast.LENGTH_LONG )
.show ( ); /* Show
a toast , containing the attached data ,
and the generated ID .*/ } });}}
Originally published at https://difyel.com on March 11, 2021.