Android Fragment for an Item in a Store

I am working on  a game that has items that players can buy from a store. I needed a way to display the list of items on the screen. I am using a StoreItemFragment to display them on the screen.  In this blog post, I describe a demo app that I built that uses the fragment in a list of items for sale. Screenshots from the demo are shown below. Screenshot_2013-11-08-15-56-47 Screenshot_2013-11-08-15-57-07

Figures 1-2

Each item has a picture, a description, and a button to push to make the purchase. Buttons can be disabled. In a game, you could do that when the player does not have enough money for the purchase. The image next to the purchase button indicates the currency used for the payment. In this demo, players pay in gold coins or crystals. I plan to use this Fragment for purchases made in a game with virtual currency, and I will use it with a second activity where the player can start an in-app purchase using real money to purchase game coins.

How It Works

Here is what the demo program looks like in Eclipse. store-item-project

There are two class files: one for the main activity and one for the fragment. There are two layout files. One layout is for for the main activity;  the other, for StoreItemFragment.
The main_activity.xml file defines the layout that you see in Figure 1 and Figure 2 above. Only one fragment  is shown in excerpt below (Listing 1), but there are actually three fragments in the layout. As you can see, store items are implemented with Fragments rather than views. The fragment StoreItemFragment, which will be described in a section below, uses store_item_display.xml as its layout.
In the Eclipse project structure, there are two of the store_item_display.xml  files, one for portrait mode and one for landscape mode (folder layout-land). I did that so that the text description part would have enough room in portrait mode. See Figure 3 below.

Notice that file android-support-v4.jar is in the libs folder. This app was built using the Android Support Library so it supports old versions of Android that did not originally support Fragments. (This demo app is based on my Fragments starter app, which includes the v4 library.)

Listing 1: main_activity.xml

 android:orientation="vertical" >

layout-sketchFigure 3 – Depiction of the views in MainActivity and in StoreItemFragment

You may have noticed that there are custom attributes in the main_activity.xml file above. With those, users of StoreItemFragment can indicate exactly how they want the item to appear. There are attributes for title, subtitle, the item picture, the text for the purchase button, and the currency image. There are also a few to control the color of the button and the color of the line that separates one item from another. To understand how custom attributes are done, you should look in the attr_views.xml file and in the onInflate method of StoreItemFragment. The xml file defines the names and types of the attributes.

Listing 2: attr_views.xml

<declare-styleable name="StoreItem">
 <attr name="item_image" format="integer"/>
 <attr name="currency_image" format="integer"/>
 <attr name="title_text" format="string"/>
 <attr name="subtitle_text" format="string"/>
 <attr name="currency_label" format="string"/>
 <attr name="purchase_enabled" format="boolean"/>
 <attr name="line_color" format="color|reference"/>
 <attr name="line_height" format="dimension"/>
 <attr name="button_width" format="dimension"/>
 <attr name="button_height" format="dimension"/>
 <attr name="button_enabled_color" format="color|reference"/>
 <attr name="button_disabled_color" format="color|reference"/>
 <attr name="text_disabled_color" format="color|reference"/>

Store Item Fragment The store item fragment is composed of several views, as shown in the landscape layout in Listing 3 below. There is an image on the left to show what the item being sold looks like. There is a section in the middle for a title and a subtitle. On the right, there is a button and an image that indicates what currency payment is in.

Listing 3: store_item_display.xml

 android:src="@drawable/sample_item_image" />
 android:padding="12dp" >
 android:text="@string/si_sample_title" />
 android:text="@string/si_sample_subtitle" />
 android:padding="4dp" >
 android:src="@drawable/coin_01" />

The connection between class StoreItemFragment and the layout file store_item_display.xml (above) is made in the onCreateView method of StoreItemFragment. Here is the relevant portion of that method.

public View onCreateView (LayoutInflater inflater, ViewGroup container, 
    Bundle savedInstanceState) {
final View v = inflater.inflate (R.layout.store_item_display, container, false);
// Set up views using inflated information

The call to inflater.inflate results in a call to the onInflate method of StoreItemFragment. That method takes information from an xml (like main_activity.xml)  and saves it so code later in onCreateView can show the custom requests. In the code excerpt below, you see how the item_image attribute is read in and handled. It checks to see if “custom:item_image” has been used as an attribute. If it has it reads in the Drawable for the image. If there is no custom image, it substitutes a default drawable named “sample_item_image”.

public void onInflate(Activity activity, AttributeSet attrs, Bundle savedInstanceState) {
 super.onInflate(activity, attrs, savedInstanceState);
Resources res = activity.getResources ();
TypedArray a = activity.obtainStyledAttributes(attrs, R.styleable.StoreItem);
mItemImage = a.getDrawable (R.styleable.StoreItem_item_image);
 if (mItemImage == null) mItemImage = res.getDrawable (R.drawable.sample_item_image);
mTitleText = a.getString (R.styleable.StoreItem_title_text);

Here is a section of code that does some of the work in onCreateView.  It locates the item_image and sets its drawable with what was set in onInflate. The other lines show how the title text gets set.

ImageView iv = (ImageView) v.findViewById (;
if (iv != null) iv.setImageDrawable (mItemImage);
TextView tv1 = (TextView) v.findViewById (;
if (tv1 != null) tv1.setText (mTitleText);

Also in onCreateView is the call to set up an OnClickListener for the purchase button: “mPurchaseButton.setOnClickListener (this);”. This makes the button clicks on the purchase button go to code in StoreItemFragment. If we look at the code there, we see how those clicks are relayed to the activity where the fragment is being used.

public void onClick (View v) {
 int vid = v.getId ();
 if (mPurchaseEnabled && (vid == {
 mContainer.onClickPurchase (this);

Notice that the call goes to mContainer. That variable gets set in onAttach, which was actually the first method called when the fragment was attached to an Activity. It does a simple assignment that ensures that the activity is compatible with this particular fragment.  That’s the line “mContainer = (StoreItemFragment) activity;”.

public void onAttach (Activity activity) {
 super.onAttach (activity);
 try {
 mContainer = (StoreItemFragment.Container) activity;
 } catch (ClassCastException ex) {
 throw new ClassCastException (activity.toString () 
 + " must implement StoreItemFragment.Container interface");

The interface for Container is simple in this demo app.  In some of my apps with fragments, it has had several methods because there are more clickable views in the fragment. This one is simple, with just the one clickable button.

public interface Container {
 public void onClickPurchase (StoreItemFragment frag);

To finish out the discussion of StoreItemFragment, look at the onResume method. The onResume implementation for StoreItemFragment does not do much. It calls the super.onResume method and then calls updateContent. The updateContent method is taking care of the dynamic elements of the views that make up a StoreItemFragment. In this demo, the only really dynamic aspect is whether the purchase button is enabled or disabled. That is done that way so the player gets an indication of whether there are enough coins on hand to pay for the item.

public void onResume() {
 updateContent ();
public void updateContent () {
 if (mPurchaseButton != null) {
 int colorNow = mPurchaseEnabled ? mEnabledColor : mDisabledColor;
 int textColorNow = mPurchaseEnabled ? mEnabledTextColor : mDisabledTextColor;
 mPurchaseButton.getBackground().setColorFilter (colorNow, PorterDuff.Mode.MULTIPLY);
 mPurchaseButton.setTextColor (textColorNow);
 mPurchaseButton.invalidate ();

It might seem like a lot is going on in StoreItemFragment and I guess that’s true. However, keep in mind that without fragments all of these actions would have to be done in Activity code. In a situation where there are multiple copies of a fairly complex view being used by an activity, you’d certainly find yourself writing a lot more code in your activity. To help you appreciate that point, let’s look at MainActivity for this demo.

MainActivity The layout file for the MainActivity has already been shown above (see Listing 1). You have seen that the fragments used are not added dynamically. Instead they are added by being defined in the layout file. So, as far as making a connection between a StoreItemFragment object and a MainActivity, only two things are needed:

  1. MainActivity must implement the StoreItemFragment.Container interface. That interface requires an onClickPurchase method.
  2. MainActivity must use the layout file. That’s done in onCreate.

Here’s the relevant portion of the MainActivity java file:

public class MainActivity extends FragmentActivity 
 implements StoreItemFragment.Container 
protected void onCreate(Bundle savedInstanceState) {

The demo onClickPurchase method does not do a lot. It checks to see which fragment had its purchase button clicked. It then changes the state of the all the buttons being displayed and asks that the MainActivity update itself.

public void onClickPurchase (StoreItemFragment frag) {
 int id = frag.getId ();
 int itemNum = 0;
 boolean paidCoins = true;
 switch (id) {
 case :
 itemNum = 1;
 mItem1Available = false;
 mItem2Available = true;
 mItem3Available = true;
 case : 
if (itemNum > 0) {
 toast ("You purchased item " + itemNum);
 updateContent ();

In a real app, there would likely be a bit more going on than that. For instance, there might be different rules for deciding which buttons are enabled and which are disabled.

Source Code

You can download the source code for this demo from the website. Click here: download zip file from The zip is attached at the bottom of that page. After you import the project into Eclipse, it’s a good idea to use the Project – Clean menu item to rebuild the project. This demo app was compiled with Android 4.2 (API 17). It works in all API levels from API 10 on up.


Android Developer Fragments – information on fragments, the lifecycle, etc.

My Android Fragments Example – explains basic fragments, v4 compatibility, etc. I often use it as my starter kit for a project with Fragments.

Two good discussions about use of custom attributes for views and fragments: (1) Defining Custom Attributes; (2) Understanding Custom Attributes.

About Bill Lahti

Bill Lahti is a software engineer building mobile applications and knowledge management solutions. Two of his interests are writing for this blog and building Android apps, with strategy games being an area of particular interest.
This entry was posted in Android, Game Design and tagged , , , , , . Bookmark the permalink.

7 Responses to Android Fragment for an Item in a Store

  1. Pingback: Examples of Store Item Activities in Android | More Is Not Always Better

  2. Pingback: More Mobile Enemy in Starship App | More Is Not Always Better

  3. Pingback: In-app Billing in an Android Space War Game | More Is Not Always Better

  4. Jake says:

    Hi Bill,

    Thanks for posting this! I’m getting 415 errors on the sample code when I try to download tho.

    • Bill Lahti says:

      Use the download icon on the page for the demo app. The icon is to the right of the date and the version number. That one works fine. When you click on the the zip file link, it goes to a Google Docs/Drive viewer for zip files. That one reports a 415 error.

  5. Pingback: Tutorial: How to Implement In-app Billing in Android – Part 2 | More Is Not Always Better

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s