1 page.title=Grid View 2 parent.title=Hello, Views 3 parent.link=index.html 4 @jd:body 5 6 <p>{@link android.widget.GridView} is a {@link android.view.ViewGroup} that displays items in a 7 two-dimensional, 8 scrollable grid. The grid items are automatically inserted to the layout using a {@link 9 android.widget.ListAdapter}.</p> 10 11 <p>In this tutorial, you'll create a grid of image thumbnails. When an item is selected, a 12 toast message will display the position of the image.</p> 13 14 15 <ol> 16 <li>Start a new project named <em>HelloGridView</em>.</li> 17 <li>Find some photos you'd like to use, or <a 18 href="{@docRoot}shareables/sample_images.zip">download these sample images</a>. Save the image files 19 into the project's 20 <code>res/drawable/</code> directory.</li> 21 <li>Open the <code>res/layout/main.xml</code> file and insert the following: 22 <pre> 23 <?xml version="1.0" encoding="utf-8"?> 24 <GridView xmlns:android="http://schemas.android.com/apk/res/android" 25 android:id="@+id/gridview" 26 android:layout_width="fill_parent" 27 android:layout_height="fill_parent" 28 android:columnWidth="90dp" 29 android:numColumns="auto_fit" 30 android:verticalSpacing="10dp" 31 android:horizontalSpacing="10dp" 32 android:stretchMode="columnWidth" 33 android:gravity="center" 34 /> 35 </pre> 36 <p>This {@link android.widget.GridView} will fill the entire screen. The attributes are rather 37 self explanatory. For more information about valid attributes, see the {@link 38 android.widget.GridView} reference.</p> 39 </li> 40 <li>Open <code>HelloGridView.java</code> and insert the following code for the 41 {@link android.app.Activity#onCreate(Bundle) onCreate()} method: 42 <pre> 43 public void onCreate(Bundle savedInstanceState) { 44 super.onCreate(savedInstanceState); 45 setContentView(R.layout.main); 46 47 GridView gridview = (GridView) findViewById(R.id.gridview); 48 gridview.setAdapter(new ImageAdapter(this)); 49 50 gridview.setOnItemClickListener(new OnItemClickListener() { 51 public void onItemClick(AdapterView<?> parent, View v, int position, long id) { 52 Toast.makeText(HelloGridView.this, "" + position, Toast.LENGTH_SHORT).show(); 53 } 54 }); 55 } 56 </pre> 57 <p>After the {@code main.xml} layout is set for the content view, the 58 {@link android.widget.GridView} is captured from the layout with {@link 59 android.app.Activity#findViewById(int)}. The {@link 60 android.widget.GridView#setAdapter(T) setAdapter()} method then sets a custom adapter ({@code 61 ImageAdapter}) as the source for all items to be displayed in the grid. The {@code ImageAdapter} is 62 created in the next step.</p> 63 <p>To do something when an item in the grid is clicked, the {@link 64 android.widget.AdapterView#setOnItemClickListener(OnItemClickListener) setOnItemClickListener()} 65 method is passed a new {@link android.widget.AdapterView.OnItemClickListener}. This anonymous 66 instance defines the {@link 67 android.widget.AdapterView.OnItemClickListener#onItemClick(AdapterView,View,int,long) 68 onItemClick()} callback method to show a {@link android.widget.Toast} that displays the index 69 position (zero-based) of the selected item (in a real world scenario, the position could be used to 70 get the full sized 71 image for some other task).</p> 72 73 </li> 74 <li>Create a new class called <code>ImageAdapter</code> that extends {@link 75 android.widget.BaseAdapter}: 76 <pre> 77 public class ImageAdapter extends BaseAdapter { 78 private Context mContext; 79 80 public ImageAdapter(Context c) { 81 mContext = c; 82 } 83 84 public int getCount() { 85 return mThumbIds.length; 86 } 87 88 public Object getItem(int position) { 89 return null; 90 } 91 92 public long getItemId(int position) { 93 return 0; 94 } 95 96 // create a new ImageView for each item referenced by the Adapter 97 public View getView(int position, View convertView, ViewGroup parent) { 98 ImageView imageView; 99 if (convertView == null) { // if it's not recycled, initialize some attributes 100 imageView = new ImageView(mContext); 101 imageView.setLayoutParams(new GridView.LayoutParams(85, 85)); 102 imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); 103 imageView.setPadding(8, 8, 8, 8); 104 } else { 105 imageView = (ImageView) convertView; 106 } 107 108 imageView.setImageResource(mThumbIds[position]); 109 return imageView; 110 } 111 112 // references to our images 113 private Integer[] mThumbIds = { 114 R.drawable.sample_2, R.drawable.sample_3, 115 R.drawable.sample_4, R.drawable.sample_5, 116 R.drawable.sample_6, R.drawable.sample_7, 117 R.drawable.sample_0, R.drawable.sample_1, 118 R.drawable.sample_2, R.drawable.sample_3, 119 R.drawable.sample_4, R.drawable.sample_5, 120 R.drawable.sample_6, R.drawable.sample_7, 121 R.drawable.sample_0, R.drawable.sample_1, 122 R.drawable.sample_2, R.drawable.sample_3, 123 R.drawable.sample_4, R.drawable.sample_5, 124 R.drawable.sample_6, R.drawable.sample_7 125 }; 126 } 127 </pre> 128 <p>First, this implements some required methods inherited from {@link 129 android.widget.BaseAdapter}. The constructor and {@link 130 android.widget.Adapter#getCount()} are self-explanatory. Normally, {@link 131 android.widget.Adapter#getItem(int)} should return the actual object at the specified position in 132 the adapter, but it's ignored for this example. Likewise, {@link 133 android.widget.Adapter#getItemId(int)} should return the row id of the item, but it's not 134 needed here.</p> 135 136 <p>The first method necessary is {@link android.widget.Adapter#getView(int,View,ViewGroup) 137 getView()}. This method creates a new {@link android.view.View} for each image added to the {@code 138 ImageAdapter}. When this is called, a {@link android.view.View} is passed in, which is normally a 139 recycled object (at least after this has been called once), so there's a check to see if the 140 object is null. If it <em>is</em> null, an {@link android.widget.ImageView} is instantiated and 141 configured with desired properties for the image presentation:</p> 142 <ul> 143 <li>{@link android.view.View#setLayoutParams(ViewGroup.LayoutParams)} sets 144 the height and width for the View—this ensures that, no matter the size of the drawable, each 145 image is resized and cropped to fit in these dimensions, as appropriate.</li> 146 <li>{@link android.widget.ImageView#setScaleType(ImageView.ScaleType)} declares that images should 147 be cropped toward the center (if necessary).</li> 148 <li>{@link android.widget.ImageView#setPadding(int,int,int,int)} defines the padding for all 149 sides. (Note that, if the images have different aspect-ratios, then less 150 padding will cause for more cropping of the image if it does not match 151 the dimensions given to the ImageView.)</li> 152 </ul> 153 154 <p>If the {@link android.view.View} passed to {@link 155 android.widget.Adapter#getView(int,View,ViewGroup) getView()} is <em>not</em> null, then the local 156 {@link android.widget.ImageView} is initialized with the recycled {@link android.view.View} 157 object.</p> 158 159 <p>At the end of the {@link android.widget.Adapter#getView(int,View,ViewGroup) getView()} method, 160 the {@code 161 position} integer passed into the method is used to select an image from the {@code mThumbIds} 162 array, which is set as the image resource for the {@link android.widget.ImageView}.</p> 163 <p>All that's left is to define the {@code mThumbIds} array of drawable resources.</p> 164 </li> 165 <li>Run the application.</li> 166 </ol> 167 <p>Your grid layout should look something like this:</p> 168 <img src="images/hello-gridview.png" width="150px" /> 169 170 <p>Try experimenting with the behaviors of the {@link android.widget.GridView} and {@link 171 android.widget.ImageView} elements by adjusting their properties. For example, instead of using 172 {@link android.view.View#setLayoutParams(ViewGroup.LayoutParams)}, try using 173 {@link android.widget.ImageView#setAdjustViewBounds(boolean)}. </p> 174 175 <h3>References</h3> 176 <ul> 177 <li>{@link android.widget.GridView}</li> 178 <li>{@link android.widget.ImageView}</li> 179 <li>{@link android.widget.BaseAdapter}</li> 180 <li>{@link android.widget.AdapterView.OnItemClickListener}</li> 181 </ul> 182 183