Recipe: Creating a Stack of Images Using StackView
StackView helps in arranging items in the form of stacked cards, where the front item can be flipped to bring the item behind it to the front. In addition to images, you can stack objects composed of text and other data, too.
In this recipe, you will learn to stack images in the StackView. So create a new Android project called StackViewApp. The only control that you need to define in the activity layout file is StackView widget. After defining the StackView widget, the activity layout file activity_stack_view_app.xml will appear, as shown in Listing 4.5.
Listing 4.5. Code Written in the Activity Layout File activity_stack_view_app.xml
<FrameLayout xmlns: <StackView android: </StackView> </FrameLayout>
To access and identify the StackView in Java code, assign the control the ID stackview. The value of the android:animateLayoutChanges attribute is set to true so that changes occurring in the layout will not mandate running LayoutTransition.
To represent the stack item that you want to stack in StackView, you need to define an XML file in the res/layout folder. Right-click the res/layout folder in the Package Explorer window, and add an XML file called item.xml. Because you want to stack only the images, only an ImageView control is defined in the item.xml file. After you define the ImageView, the item.xml file will appear, as shown in Listing 4.6.
Listing 4.6. Code Written in the item.xml File
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns: <ImageView android: </FrameLayout>
You can see that the ImageView control is assigned the ID imageview and is initialized to display the ic_launcher.png file. In all, you want to display five images through the StackView control. Assuming the five image filenames are prod1.png, prod2.png, prod3.png, prod4.png, and prod5.png, copy them to the res/drawable folders. It’s time to write code in the Java activity file to perform the following tasks:
- Access the StackView from the layout file and map it to the StackView object.
- Define an array to contain the resource IDs of the images that you copied into res/drawable folders. This array will act as a data source, providing the images that you want to display.
- Define a custom adapter called ImageAdapter that will extend the BaseAdapter abstract class to define the content to be displayed through the StackView control.
- Display the adapter’s content (images) via StackView, and set ImageAdapter to the StackView object via the setAdapter() method.
To accomplish all the preceding tasks, write the code as shown in Listing 4.7 in the Java activity file StackViewAppActivity.java.
Listing 4.7. Code Written in the Java Activity File StackViewAppActivity.java
package com.androidtablet.stackviewapp; import android.os.Bundle; import android.app.Activity; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.StackView; import android.widget.BaseAdapter; public class StackViewAppActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_stack_view_app); StackView stackView = (StackView)this.findViewById( R.id.stackview); stackView.setAdapter(new ImageAdapter(this)); } public class ImageAdapter extends BaseAdapter { private Context contxt; Integer[] images = { R.drawable.prod1, R.drawable.prod2, R.drawable.prod3, R.drawable.prod4, R.drawable.prod5 }; public ImageAdapter(Context c) { contxt = c; } public int getCount() { return images.length; } public Object getItem(int position) { return position; } public long getItemId(int position) { return position; } public View getView(int position, View view, ViewGroup parent) { if (view == null) { LayoutInflater vi = (LayoutInflater) getBaseContext().getSystemService( Context.LAYOUT_INFLATER_SERVICE); view = vi.inflate(R.layout.item, null, false); } ImageView imageView = (ImageView) view.findViewById( R.id.imageview); imageView.setImageResource(images[position]); return view; } } }
The ImageAdapter is set to the StackView control, so it can access the adapter methods to display content (images). The adapter’s methods—getCount(), getItem(), and getItemId()—are used to determine the number of images to be displayed and the unique identifier of the specified image. The getView() method is used to retrieve the appropriate view or image at the specified position. The ImageView defined in the item.xml file is accessed and is used to display images through the StackView.
After running the application, you find the stack of items (images) (see Figure 4.4 [left]). When you flip the front image, the images in back are moved to the front, as shown in Figure 4.4 [right]).
Figure 4.4. StackView displaying images (left), and the hidden images displayed in the front after flipping the front images (right)
The size of the images when an application is run on a phone may appear fine. But on a tablet, the images appear very small. To scale the images according to the screen size of the device, you need to modify the item.xml file. Open the item.xml file in the res/layout folder, and modify it to appear as shown in Listing 4.8. Only the code in bold is the modified code; the rest is the same that you saw in Listing 4.6.
Listing 4.8. Code Written in the item.xml File
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns: <ImageView android: </FrameLayout>
The image(s) that will be displayed through StackView are assigned the width and height through the dimension resources image_width and image_height, respectively.
To define the dimension resources image_width and image_height, open the dimens.xml file from the res/values folder. You assume that the dimension file dimens.xml already exists in the res/values folder of the application. You also assume that two folders named values-sw600dp and values-sw720dp exist in the res folder, and both the folders contain a dimension file named dimens.xml.
To define the width and height for the images when an application runs on a phone, open the dimens.xml file in the res/values folder, and write the following code in it:
<?xml version="1.0" encoding="utf-8"?> <resources> <dimen name="image_width">100dp</dimen> <dimen name="image_height">200dp</dimen> </resources>
You can see that on the phone, the StackView will display the images of width and height 100dp and 200dp, respectively.
Again, to define the width and height for the images when an application is viewed on a 7-inch tablet, open the dimension file dimens.xml in the res/values-sw600dp folder, and write the following code in it:
<?xml version="1.0" encoding="utf-8"?> <resources> <dimen name="image_width">200dp</dimen> <dimen name="image_height">300dp</dimen> </resources>
The preceding code will assign 200dp width and 300dp height to the images displayed through StackView on a 7-inch tablet. For defining the image dimensions for a 10-inch tablet, open the dimension file dimens.xml found in the res/values-sw720dp folder, and write the following code in it:
<?xml version="1.0" encoding="utf-8"?> <resources> <dimen name="image_width">300dp</dimen> <dimen name="image_height">400dp</dimen> </resources>
The preceding code will make the images appear 300dp wide and 400dp high in StackView when an application runs on a 10-inch tablet.
After you run the application on a 10-inch tablet, the StackView will appear as shown on the phone in Figure 4.5 (left). Compared to Figure 4.4 (left), you can see that the images appear quite big and clear on a tablet. When you flip a front image, the images at the back move to the front, as shown in Figure 4.5 (right).
Figure 4.5. StackView displaying enlarged images (left); the images at the back appear in the front when you flip the front images (right).