Android Hello, Gallery tutorial -- "R.styleable cannot be resolved"

When working on the Hello, Gallery tutorial/sample app, after following the instructions on the site, Eclipse reported that R.styleable cannot be resolved.

What is the reason for this error, and how can it be fixed or worked around?


Per this thread, R.styleable has been removed from android 1.5 and higher.

There are a number of ways to get the sample to work, the simplest that I found was recommended by Justin Anderson in the thread linked to above:

  1. Create a new XML file called "resources.xml" with the following content:

    <?xml version="1.0" encoding="utf-8"?> 
    <resources> 
        <declare-styleable name="Gallery1"> 
            <attr name="android:galleryItemBackground" /> 
        </declare-styleable> 
    </resources>
    
  2. Place the XML file in the res\values directory (alongside strings.xml)

  3. Update the constructor for your ImageAdapter with the following (assuming the ImageAdapter class is defined in its own file):

    public ImageAdapter(Context c) {
        mContext = c;
        TypedArray a = c.obtainStyledAttributes(R.styleable.Gallery1);
        mGalleryItemBackground = a.getResourceId(R.styleable.Gallery1_android_galleryItemBackground, 0);
        a.recycle();
    }
    

This solution basically defines the styleable attribute as a resource of the app itself and gives it the necessary structure to work in the app. Note that the app can run fine if you just omit the two lines of code (prior to a.recycle();), all this code does is set a grey background around the images in the Gallery.


The reason for this problem is the resources they tell you to put into res/values/attrs.xml are:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="HelloGallery">
        <attr name="android:galleryItemBackground" />
    </declare-styleable>
</resources>

But then you get this adapter, which Eclipse can't figure out and frankly makes no sense:

public ImageAdapter(Context c) {
    mContext = c;
    TypedArray a = obtainStyledAttributes(android.R.styleable.Theme);
    mGalleryItemBackground = a.getResourceId(
            android.R.styleable.Theme_galleryItemBackground, 0);
    a.recycle();
}

That's because you shouldn't have "android." preceeding the resources, the styleable name is Theme here but HelloGallery in the actual resource, and the galleryItemBackground puts android between the styleable name and the attribute like this: Theme_android_galleryItemBackground

So if want the ImageAdapter method to work with the resources you're given, you should rewrite it like this:

public ImageAdapter(Context c) {
    mContext = c;
    TypedArray a = obtainStyledAttributes(R.styleable.HelloGallery);
    mGalleryItemBackground = a.getResourceId(
            R.styleable.HelloGallery_android_galleryItemBackground, 0);
    a.recycle();
}

For future problems regarding resources (R.* cannot be resolved type errors), examine /gen/R.java for what the resources are actually being named.