Home | History | Annotate | Download | only in views
      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 &lt;?xml version="1.0" encoding="utf-8"?>
     24 &lt;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&lt;?> 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&mdash;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