page.title=Gallery parent.title=Hello, Views parent.link=index.html @jd:body <p>{@link android.widget.Gallery} is a layout widget used to display items in a horizontally scrolling list and positions the current selection at the center of the view.</p> <p>In this tutorial, you'll create a gallery of photos and then display a toast message each time a gallery item is selected.</p> <ol> <li>Start a new project named <em>HelloGallery</em>.</li> <li>Find some photos you'd like to use, or use these <a href="{@docRoot}shareables/sample_images.zip">sample images</a>. Save the images into the project's <code>res/drawable/</code> directory.</li> <li>Open the <code>res/layout/main.xml</code> file and insert the following: <pre> <?xml version="1.0" encoding="utf-8"?> <Gallery xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/gallery" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </pre> </li> <li>Open the <code>HelloGallery.java</code> file and insert the following code for the {@link android.app.Activity#onCreate(Bundle) onCreate()} method: <pre> @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Gallery g = (Gallery) findViewById(R.id.gallery); g.setAdapter(new ImageAdapter(this)); g.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView parent, View v, int position, long id) { Toast.makeText(HelloGallery.this, "" + position, Toast.LENGTH_SHORT).show(); } }); } </pre> <p>This starts by setting the {@code main.xml} layout as the content view and then capturing the {@link android.widget.Gallery} from the layout with {@link android.app.Activity#findViewById(int)}. A custom {@link android.widget.BaseAdapter} called <code>ImageAdapter</code> is instantiated and applied to the {@link android.widget.Gallery} with {@link android.widget.AdapterView#setAdapter(T) setAdapter()}. (The <code>ImageAdapter</code> class is defined next.) Then an anonymous {@link android.widget.AdapterView.OnItemClickListener} is instantiated. The {@link android.widget.AdapterView.OnItemClickListener#onItemClick(AdapterView,View,int,long)} callback method receives the {@link android.widget.AdapterView} where the click occurred, the specific {@link android.view.View} that received the click, the position of the {@link android.view.View} clicked (zero-based), and the row ID of the item clicked (if applicable). In this example, all that's needed is the position of the click to show a {@link android.widget.Toast} message that says the position of the item, using {@link android.widget.Toast#makeText(Context,CharSequence,int)} and {@link android.widget.Toast#show()} (in a real world scenario, this ID could be used to get the full sized image for some other task). </p> </li> <li>Create a new XML file in the <code>res/values/</code> directory named <code>attrs.xml</code>. Insert the following: <pre> <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="HelloGallery"> <attr name="android:galleryItemBackground" /> </declare-styleable> </resources> </pre> <p>This is a custom styleable resource that can be applied to a layout. In this case, it will be applied to the individual items placed into the {@link android.widget.Gallery} widget. The <code><attr></code> element defines a specific attribute for the styleable, and in this case, it refers to an existing platform attribute, {@link android.R.attr#galleryItemBackground}, which defines a border styling for gallery items. In the next step, you'll see how this attribute is referenced and then later applied to each item in the gallery.</p> </li> <li>Go back to the <code>HelloGallery.java</code> file. After the {@link android.app.Activity#onCreate(Bundle)} method, define the custom <code>ImageAdapter</code> class: <pre> public class ImageAdapter extends BaseAdapter { int mGalleryItemBackground; private Context mContext; private Integer[] mImageIds = { R.drawable.sample_1, R.drawable.sample_2, R.drawable.sample_3, R.drawable.sample_4, R.drawable.sample_5, R.drawable.sample_6, R.drawable.sample_7 }; public ImageAdapter(Context c) { mContext = c; TypedArray a = obtainStyledAttributes(R.styleable.HelloGallery); mGalleryItemBackground = a.getResourceId( R.styleable.HelloGallery_android_galleryItemBackground, 0); a.recycle(); } public int getCount() { return mImageIds.length; } public Object getItem(int position) { return position; } public long getItemId(int position) { return position; } public View getView(int position, View convertView, ViewGroup parent) { ImageView i = new ImageView(mContext); i.setImageResource(mImageIds[position]); i.setLayoutParams(new Gallery.LayoutParams(150, 100)); i.setScaleType(ImageView.ScaleType.FIT_XY); i.setBackgroundResource(mGalleryItemBackground); return i; } } </pre> <p>First, there are a few member variables, including an array of IDs that reference the images saved in the drawable resources directory ({@code res/drawable/}).</p> <p>Next is the class constructor, where the {@link android.content.Context} for an {@code ImageAdapter} instance is defined and the styleable resource defined in the last step is acquired and saved to a local field. At the end of the constructor, {@link android.content.res.TypedArray#recycle()} is called on the {@link android.content.res.TypedArray} so it can be re-used by the system.</p> <p>The methods {@link android.widget.Adapter#getCount()}, {@link android.widget.Adapter#getItem(int)}, and {@link android.widget.Adapter#getItemId(int)} are methods that must be implemented for simple queries on the {@link android.widget.Adapter}. The {@link android.widget.Adapter#getView(int,View,ViewGroup) method does the work to apply an image to an {@link android.widget.ImageView} that will be embedded in the {@link android.widget.Gallery}. In this method, the member {@link android.content.Context} is used to create a new {@link android.widget.ImageView}. The {@link android.widget.ImageView} is prepared by applying an image from the local array of drawable resources, setting the {@link android.widget.Gallery.LayoutParams} height and width for the image, setting the scale to fit the {@link android.widget.ImageView} dimensions, and then finally setting the background to use the styleable attribute acquired in the constructor.</p> <p>See {@link android.widget.ImageView.ScaleType} for other image scaling options.</p> </li> <li>Run the application.</li> </ol> <p>You should see something like this:</p> <img src="images/hello-gallery.png" width="150px" /> <h3>References</h3> <ul> <li>{@link android.widget.BaseAdapter}</li> <li>{@link android.widget.Gallery}</li> <li>{@link android.widget.ImageView}</li> <li>{@link android.widget.AdapterView.OnItemClickListener}</li> </ul>