Images

Intro

So you want to use images in your app.  Why didn't you say so!  Incorporating images is simple.  By using the provided ImageView, you can add images anywhere in your layout.  Additionally, there are other, like a Gallery, that let us get even more creative with our images.  For this lesson, download the following archive of images (or feel free to use your own...just make sure you get the names correct):

Image Files

ImageView

To display an image in your app, simply add an ImageView to you layout file.  You can specify the height, width, gravity, etc, just like any other View.  The  "android:src" attribute of the ImageView should point to a file in your res > drawable folders.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#444444"
    tools:context=".MainActivity" >

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/pic1" />

</RelativeLayout>

That's it!  Aren't images easy?  

To programmatically set the image source to an image stored in your drawable folder, you use setImageResource(), which takes a resource id argument:

ImageView imageView = (ImageView) findViewById(R.id.imageView);
imageView.setImageResource(R.drawable.pic2);

Loading Images From the assets Folder

Although using the res > drawable folder is preferred because it takes advantage of the operating system's resource management system, when it comes to using files in your app's resources folders, you have several options.  You can also use images that are stored in places other than the resources > drawable folders.  Another common place to put files is the assets folder (a subfolder of main).  By default, this folder isn't created by Android Studio when your project is created so you will need to create it yourself.

 

Loading an image from the assets folder is handled differently than loading one from the drawable folder.  As a matter fact, there are multiple ways to accomplish this:

1.  As opposed to using a resource id, you will use a InputStream, like so:

InputStream inStream = getAssets().open("severn.jpg");

Once you have the input stream, you use it to create a Drawable object which can then be loaded into the ImageView:

Drawable d = Drawable.createFromStream(inStream, null);
imageView.setImageDrawable(d);

2.  Alternatively, you can use the stream to create a Bitmap instead of a Drawable, and load the Bitmap into the ImageView:

Bitmap b = BitmapFactory.decodeStream(inStream);
imageView.setImageBitmap(b);

TASK:

Using the sample code above, create a new Android Studio project named ImagesExample.  Place pic1.png - pic5.png in the app's res > drawable folder.  Next, place the file severn.jpg in the assets folder.  First, have the ImageView element display an image from the res > drawable folder.  Then, modify you app so that it displays an image from the assets folder. 

Retrieving Drawable from an ImageView

Sometimes you need to get the image from an ImageView.  This can be accomplished using the getDrawable method of ImageView:

Drawable myDrawable = myImageView.getDrawable();

 

Building a Simple Gallery App

There's a View called a Gallery that allows you to display multiple images in a horizontal list in your layout.  The Gallery View is now deprecated, but we can build our own using a HorizontalScrollView.  Like a normal ScrollView, the horizontal version can only take one child element.  In this case, we'll use a Linear Layout to hold our images.  The following is layout incorporates the horizontal scrollview:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#444444"
    tools:context=".MainActivity" >

    <HorizontalScrollView
        android:id="@+id/scrollView"
        android:layout_width="wrap_content"
        android:layout_height="100dp" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:orientation="horizontal" >

            <ImageView
                android:id="@+id/imageView2"
                android:layout_width="150dp"
                android:layout_height="100dp"
                android:src="@drawable/pic1" />

            <ImageView
                android:id="@+id/imageView3"
                android:layout_width="150dp"
                android:layout_height="100dp"
                android:src="@drawable/pic2" />

            <ImageView
                android:id="@+id/imageView4"
                android:layout_width="150dp"
                android:layout_height="100dp"
                android:src="@drawable/pic3" />

            <ImageView
                android:id="@+id/imageView5"
                android:layout_width="150dp"
                android:layout_height="100dp"
                android:src="@drawable/pic4" />

            <ImageView
                android:id="@+id/imageView6"
                android:layout_width="150dp"
                android:layout_height="100dp"
                android:src="@drawable/pic5" />
        </LinearLayout>
    </HorizontalScrollView>

    <ImageView
        android:id="@+id/imageView"
        android:layout_below="@id/scrollView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/pic1" />

</RelativeLayout>

Task:

Modify MainActivity.java such that when an image is clicked in the HorizontalScrollView, the image in the ImageView is changed to reflect the selected item.

In order to update the larger ImageView with the Drawable in the clicked ImageView, you need to:

  1. Have you Activity implement View.OnClickListener, and then set each ImageView in the HorizontalScrollView to use it.
  2. When an ImageView is clicked:
    1. Check the clicked View to ensure it's an ImageView
    2. Retrieve the Drawable from the clicke ImageView
    3. Load the retrieved Drawable into the larger ImageView
@Override
public void onClick(View v) {
    if (v instanceof ImageView) {
        ImageView myImageView = (ImageView) v;
        Drawable clickedDrawable = myImageView.getDrawable();
        imageView.setImageDrawable(clickedDrawable);
    }
}

 

ImageButton

An ImageButton is a subclass of ImageView that displays an image on a Button (as the name implies).  ImageButtons are created the same way as ImageViews:

<ImageButton
        android:scaleType="centerInside"
        android:id="@+id/imageButton"
        android:layout_width="150dp"
        android:layout_height="100dp"
        android:src="@drawable/pic1" 
/>

In order to ensure that the image is scaled properly inside the Button, you use the scaleType attribute. 

Task:

Modify you Gallery app so that the HorizontalScrollView contains ImageButtons instead of ImageViews.  Make sure the images are scaled properly!