1 page.title=Gallery 2 parent.title=Hello, Views 3 parent.link=index.html 4 @jd:body 5 6 <p>{@link android.widget.Gallery} is a layout widget used to display items in a 7 horizontally scrolling list and positions the current selection at the center of the view.</p> 8 9 <p>In this tutorial, you'll create a gallery of photos and then display a toast message each time a 10 gallery item is selected.</p> 11 12 13 <ol> 14 <li>Start a new project named <em>HelloGallery</em>.</li> 15 <li>Find some photos you'd like to use, or use these <a 16 href="{@docRoot}shareables/sample_images.zip">sample images</a>. Save the images into the project's 17 <code>res/drawable/</code> directory.</li> 18 <li>Open the <code>res/layout/main.xml</code> file and insert the following: 19 <pre> 20 <?xml version="1.0" encoding="utf-8"?> 21 <Gallery xmlns:android="http://schemas.android.com/apk/res/android" 22 android:id="@+id/gallery" 23 android:layout_width="fill_parent" 24 android:layout_height="wrap_content" 25 /> 26 </pre> 27 </li> 28 29 <li>Open the <code>HelloGallery.java</code> file and insert the following code for the 30 {@link android.app.Activity#onCreate(Bundle) onCreate()} method: 31 <pre> 32 @Override 33 public void onCreate(Bundle savedInstanceState) { 34 super.onCreate(savedInstanceState); 35 setContentView(R.layout.main); 36 37 Gallery g = (Gallery) findViewById(R.id.gallery); 38 g.setAdapter(new ImageAdapter(this)); 39 40 g.setOnItemClickListener(new OnItemClickListener() { 41 public void onItemClick(AdapterView parent, View v, int position, long id) { 42 Toast.makeText(HelloGallery.this, "" + position, Toast.LENGTH_SHORT).show(); 43 } 44 }); 45 } 46 </pre> 47 <p>This starts by setting the {@code main.xml} layout as the content view and then capturing the 48 {@link android.widget.Gallery} from 49 the layout with {@link 50 android.app.Activity#findViewById(int)}. A custom {@link android.widget.BaseAdapter} called 51 <code>ImageAdapter</code> is 52 instantiated and applied to the {@link android.widget.Gallery} with {@link 53 android.widget.AdapterView#setAdapter(T) setAdapter()}. (The <code>ImageAdapter</code> class is 54 defined next.) 55 Then an anonymous {@link android.widget.AdapterView.OnItemClickListener} is instantiated. The 56 {@link android.widget.AdapterView.OnItemClickListener#onItemClick(AdapterView,View,int,long)} 57 callback method receives the {@link android.widget.AdapterView} where the click occurred, the 58 specific {@link android.view.View} that received the click, the 59 position of the {@link android.view.View} clicked (zero-based), and the row ID of the item clicked 60 (if applicable). In this example, all that's needed is the position of the click to show a {@link 61 android.widget.Toast} message that says the position of the item, using 62 {@link android.widget.Toast#makeText(Context,CharSequence,int)} and {@link 63 android.widget.Toast#show()} (in a real world scenario, this ID could be used to get the full sized 64 image for some other task). 65 </p> 66 </li> 67 <li>Create a new XML file in the <code>res/values/</code> directory named <code>attrs.xml</code>. 68 Insert the following: 69 <pre> 70 <?xml version="1.0" encoding="utf-8"?> 71 <resources> 72 <declare-styleable name="HelloGallery"> 73 <attr name="android:galleryItemBackground" /> 74 </declare-styleable> 75 </resources> 76 </pre> 77 <p>This is a custom styleable resource that can be applied to a layout. In this case, it will be 78 applied to the individual items placed into the {@link android.widget.Gallery} widget. The 79 <code><attr></code> element defines a specific attribute for the styleable, and in this case, it 80 refers to an existing platform attribute, {@link android.R.attr#galleryItemBackground}, which 81 defines a border styling for gallery items. In the next step, you'll 82 see how this attribute is referenced and then later applied to each item in the gallery.</p> 83 </li> 84 85 <li>Go back to the <code>HelloGallery.java</code> file. After the {@link 86 android.app.Activity#onCreate(Bundle)} method, define the custom <code>ImageAdapter</code> class: 87 <pre> 88 public class ImageAdapter extends BaseAdapter { 89 int mGalleryItemBackground; 90 private Context mContext; 91 92 private Integer[] mImageIds = { 93 R.drawable.sample_1, 94 R.drawable.sample_2, 95 R.drawable.sample_3, 96 R.drawable.sample_4, 97 R.drawable.sample_5, 98 R.drawable.sample_6, 99 R.drawable.sample_7 100 }; 101 102 public ImageAdapter(Context c) { 103 mContext = c; 104 TypedArray a = obtainStyledAttributes(R.styleable.HelloGallery); 105 mGalleryItemBackground = a.getResourceId( 106 R.styleable.HelloGallery_android_galleryItemBackground, 0); 107 a.recycle(); 108 } 109 110 public int getCount() { 111 return mImageIds.length; 112 } 113 114 public Object getItem(int position) { 115 return position; 116 } 117 118 public long getItemId(int position) { 119 return position; 120 } 121 122 public View getView(int position, View convertView, ViewGroup parent) { 123 ImageView i = new ImageView(mContext); 124 125 i.setImageResource(mImageIds[position]); 126 i.setLayoutParams(new Gallery.LayoutParams(150, 100)); 127 i.setScaleType(ImageView.ScaleType.FIT_XY); 128 i.setBackgroundResource(mGalleryItemBackground); 129 130 return i; 131 } 132 } 133 </pre> 134 <p>First, there are a few member variables, including an array of IDs that reference 135 the images saved in the drawable resources directory ({@code res/drawable/}).</p> 136 <p>Next is the class constructor, where the {@link android.content.Context} for an {@code 137 ImageAdapter} instance is defined and the styleable 138 resource defined in the last step is acquired and saved to a local field. At the end of the 139 constructor, {@link android.content.res.TypedArray#recycle()} is called on the {@link 140 android.content.res.TypedArray} so it can be re-used by the system.</p> 141 <p>The methods {@link android.widget.Adapter#getCount()}, {@link 142 android.widget.Adapter#getItem(int)}, and {@link android.widget.Adapter#getItemId(int)} are methods 143 that must be implemented for simple queries on the {@link android.widget.Adapter}. 144 The {@link android.widget.Adapter#getView(int,View,ViewGroup) method does the 145 work to apply an image to an {@link android.widget.ImageView} that will be embedded in the 146 {@link android.widget.Gallery}. In this method, the member {@link android.content.Context} is used 147 to create a new {@link android.widget.ImageView}. The {@link android.widget.ImageView} is prepared 148 by applying an image from the local array of drawable resources, setting the {@link 149 android.widget.Gallery.LayoutParams} height and width for the image, setting the scale to fit the 150 {@link android.widget.ImageView} dimensions, and then finally setting the background to use the 151 styleable attribute acquired in the constructor.</p> 152 153 <p>See {@link android.widget.ImageView.ScaleType} for other image scaling options.</p> 154 </li> 155 156 <li>Run the application.</li> 157 </ol> 158 159 <p>You should see something like this:</p> 160 <img src="images/hello-gallery.png" width="150px" /> 161 162 163 <h3>References</h3> 164 <ul> 165 <li>{@link android.widget.BaseAdapter}</li> 166 <li>{@link android.widget.Gallery}</li> 167 <li>{@link android.widget.ImageView}</li> 168 <li>{@link android.widget.AdapterView.OnItemClickListener}</li> 169 </ul> 170 171 172