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="fill_parent" 49 android:layout_height="fill_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, int position, long id) { 74 Toast.makeText(HelloGridView.this, "" + position, Toast.LENGTH_SHORT).show(); 75 } 76 }); 77 } 78 </pre> 79 <p>After the {@code main.xml} layout is set for the content view, the 80 {@link android.widget.GridView} is captured from the layout with {@link 81 android.app.Activity#findViewById(int)}. The {@link 82 android.widget.GridView#setAdapter(T) setAdapter()} method then sets a custom adapter ({@code 83 ImageAdapter}) as the source for all items to be displayed in the grid. The {@code ImageAdapter} is 84 created in the next step.</p> 85 <p>To do something when an item in the grid is clicked, the {@link 86 android.widget.AdapterView#setOnItemClickListener(OnItemClickListener) setOnItemClickListener()} 87 method is passed a new {@link android.widget.AdapterView.OnItemClickListener}. This anonymous 88 instance defines the {@link 89 android.widget.AdapterView.OnItemClickListener#onItemClick(AdapterView,View,int,long) 90 onItemClick()} callback method to show a {@link android.widget.Toast} that displays the index 91 position (zero-based) of the selected item (in a real world scenario, the position could be used to 92 get the full sized 93 image for some other task).</p> 94 95 </li> 96 <li>Create a new class called <code>ImageAdapter</code> that extends {@link 97 android.widget.BaseAdapter}: 98 <pre> 99 public class ImageAdapter extends BaseAdapter { 100 private Context mContext; 101 102 public ImageAdapter(Context c) { 103 mContext = c; 104 } 105 106 public int getCount() { 107 return mThumbIds.length; 108 } 109 110 public Object getItem(int position) { 111 return null; 112 } 113 114 public long getItemId(int position) { 115 return 0; 116 } 117 118 // create a new ImageView for each item referenced by the Adapter 119 public View getView(int position, View convertView, ViewGroup parent) { 120 ImageView imageView; 121 if (convertView == null) { // if it's not recycled, initialize some attributes 122 imageView = new ImageView(mContext); 123 imageView.setLayoutParams(new GridView.LayoutParams(85, 85)); 124 imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); 125 imageView.setPadding(8, 8, 8, 8); 126 } else { 127 imageView = (ImageView) convertView; 128 } 129 130 imageView.setImageResource(mThumbIds[position]); 131 return imageView; 132 } 133 134 // references to our images 135 private Integer[] mThumbIds = { 136 R.drawable.sample_2, R.drawable.sample_3, 137 R.drawable.sample_4, R.drawable.sample_5, 138 R.drawable.sample_6, R.drawable.sample_7, 139 R.drawable.sample_0, R.drawable.sample_1, 140 R.drawable.sample_2, R.drawable.sample_3, 141 R.drawable.sample_4, R.drawable.sample_5, 142 R.drawable.sample_6, R.drawable.sample_7, 143 R.drawable.sample_0, R.drawable.sample_1, 144 R.drawable.sample_2, R.drawable.sample_3, 145 R.drawable.sample_4, R.drawable.sample_5, 146 R.drawable.sample_6, R.drawable.sample_7 147 }; 148 } 149 </pre> 150 <p>First, this implements some required methods inherited from {@link 151 android.widget.BaseAdapter}. The constructor and {@link 152 android.widget.Adapter#getCount()} are self-explanatory. Normally, {@link 153 android.widget.Adapter#getItem(int)} should return the actual object at the specified position in 154 the adapter, but it's ignored for this example. Likewise, {@link 155 android.widget.Adapter#getItemId(int)} should return the row id of the item, but it's not 156 needed here.</p> 157 158 <p>The first method necessary is {@link android.widget.Adapter#getView(int,View,ViewGroup) 159 getView()}. This method creates a new {@link android.view.View} for each image added to the {@code 160 ImageAdapter}. When this is called, a {@link android.view.View} is passed in, which is normally a 161 recycled object (at least after this has been called once), so there's a check to see if the 162 object is null. If it <em>is</em> null, an {@link android.widget.ImageView} is instantiated and 163 configured with desired properties for the image presentation:</p> 164 <ul> 165 <li>{@link android.view.View#setLayoutParams(ViewGroup.LayoutParams)} sets 166 the height and width for the View—this ensures that, no matter the size of the drawable, each 167 image is resized and cropped to fit in these dimensions, as appropriate.</li> 168 <li>{@link android.widget.ImageView#setScaleType(ImageView.ScaleType)} declares that images should 169 be cropped toward the center (if necessary).</li> 170 <li>{@link android.widget.ImageView#setPadding(int,int,int,int)} defines the padding for all 171 sides. (Note that, if the images have different aspect-ratios, then less 172 padding will cause more cropping of the image if it does not match 173 the dimensions given to the ImageView.)</li> 174 </ul> 175 176 <p>If the {@link android.view.View} passed to {@link 177 android.widget.Adapter#getView(int,View,ViewGroup) getView()} is <em>not</em> null, then the local 178 {@link android.widget.ImageView} is initialized with the recycled {@link android.view.View} 179 object.</p> 180 181 <p>At the end of the {@link android.widget.Adapter#getView(int,View,ViewGroup) getView()} method, 182 the {@code 183 position} integer passed into the method is used to select an image from the {@code mThumbIds} 184 array, which is set as the image resource for the {@link android.widget.ImageView}.</p> 185 <p>All that's left is to define the {@code mThumbIds} array of drawable resources.</p> 186 </li> 187 <li>Run the application.</li> 188 </ol> 189 190 <p>Try experimenting with the behaviors of the {@link android.widget.GridView} and {@link 191 android.widget.ImageView} elements by adjusting their properties. For example, instead of using 192 {@link android.view.View#setLayoutParams(ViewGroup.LayoutParams)}, try using 193 {@link android.widget.ImageView#setAdjustViewBounds(boolean)}. </p> 194 195 196