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