20

So I have looked around and found out that android.R.styleable is no longer part of the SDK even though it is still documented here.

That wouldn't really be an issue if it was clearly documented what the alternative is. For example the AOSP Calendar App is still using the android.R.styleable

// Get the dim amount from the theme   
TypedArray a = obtainStyledAttributes(com.android.internal.R.styleable.Theme);
lp.dimAmount = a.getFloat(android.R.styleable.Theme_backgroundDimAmount, 0.5f);
a.recycle();

So how would one get the backgroundDimAmount without getting the int[] from android.R.styleable.Theme?

What do I have to stick into obtainStyledAttributes(int []) in order to make it work with the SDK?

Rahul Sharma
  • 2,623
  • 2
  • 25
  • 38
AGrunewald
  • 1,675
  • 3
  • 16
  • 25
  • The same problem exists with the Gallery View tutorial, I have seen workarounds that make the tutorial work but no explanation as to how the tutorial would have to be fixed using only SDK classes and not adding your own xml with the styleable in it. The tutorial is at http://developer.android.com/resources/tutorials/views/hello-gallery.html the code is in the "ImageAdapter(Context c)" Constructor – AGrunewald Jan 24 '10 at 13:34
  • Here is similar discussion http://stackoverflow.com/q/8793183/1307690 – Roman Nazarevych Apr 03 '17 at 21:01

4 Answers4

15

The CustomView API demo shows how to retrieve styled attributes. The code for the view is here:

https://github.com/android/platform_development/blob/master/samples/ApiDemos/src/com/example/android/apis/view/LabelView.java

The styleable array used to retrieve the text, color, and size is defined in the <declare-styleable> section here:

https://github.com/android/platform_development/blob/master/samples/ApiDemos/res/values/attrs.xml#L24

You can use <declare-styleable> to define any list of attributes that you want to retrieve as a group, containing both your own and ones defined by the platform.

As far as these things being in the documentation, there is a lot of java doc around the styleable arrays that makes them useful to have in the documentation, so they have been left there. However as the arrays change, such as new attributes being added, the values of the constants can change, so the platform ones can not be in the SDK (and please do not use any tricks to try to access them). There should be no need to use the platform ones anyway, because they are each there just for the implementation of parts of the framework, and it is trivial to create your own as shown here.

Melebius
  • 4,692
  • 3
  • 32
  • 43
hackbod
  • 88,517
  • 16
  • 135
  • 152
  • 2
    Thanks for the info,helps quite a bit.As far as I understand one creates, the Xml Styleable with eg. one attribute being "android:backgroundDimAmount" that allows the App to retrieve the correct Data. With regards to the stuff being in the SDK. I understand that there is a lot of valuable Documentation but an explanation why the Class is in the SDK doc and not in the actual SDK right in the API Reference could clear things up for Developers in the future, since there are still tutorials that do it wrong: http://developer.android.com/intl/zh-CN/resources/tutorials/views/hello-gallery.html – AGrunewald Jan 25 '10 at 14:17
  • @hackbod First link in answer is outdated. – Pang Nov 12 '14 at 09:25
15

In the example, they left out the reference to the Context 'c':

public ImageAdapter(Context c) {
    TypedArray a = c.obtainStyledAttributes(R.styleable.GalleryPrototype);
    mGalleryItemBackground = a.getResourceId(
            R.styleable.GalleryPrototype_android_galleryItemBackground, 0);
    a.recycle();
    return mGalleryItemBackground;
}

Changing obtainStyledAttributes to c.obtainStyledAttributes should work

Daniel
  • 86
  • 13
kpasgma
  • 366
  • 2
  • 9
7

Example of pulling out standard attribute (background) in a custom view which has its own default style. In this example the custom view PasswordGrid extends GridLayout. I specified a style for PasswordGrid which sets a background image using the standard android attribute android:background.

public class PasswordGrid extends GridLayout {

    public PasswordGrid(Context context) {
        super(context);
        init(context, null, 0);
    }

    public PasswordGrid(Context context, AttributeSet attrs) {
        super(context, attrs, R.attr.passwordGridStyle);
        init(context, attrs, 0);
    }

    public PasswordGrid(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context, attrs, defStyle);
    }

    private void init(Context context, AttributeSet attrs, int defStyle) {
        if (!isInEditMode()) {

            TypedArray stdAttrs = context.obtainStyledAttributes(attrs,
                    new int[] { android.R.attr.background },  // attribute[s] to access
                    defStyle, 
                    R.style.PasswordGridStyle);  // Style to access

           // or use any style available in the android.R.style file, such as
           //       android.R.style.Theme_Holo_Light

            if (stdAttrs != null) {
                Drawable bgDrawable = stdAttrs.getDrawable(0);
                if (bgDrawable != null)
                    this.setBackground(bgDrawable);
                stdAttrs.recycle();
            }
        }
    }

Here is part of my styles.xml file:

 <declare-styleable name="passwordGrid">
    <attr name="drawOn" format="color|reference" />
    <attr name="drawOff" format="color|reference" />
    <attr name="pathWidth" format="integer" />
    <attr name="pathAlpha" format="integer" />
    <attr name="pathColor" format="color" />
 </declare-styleable>



  <style name="PasswordGridStyle" parent="@android:style/Widget.GridView" >  
      <!--  Style custom attributes.  -->
      <item name="drawOff">@drawable/ic_more</item>
      <item name="drawOn">@drawable/ic_menu_cut</item>
      <item name="pathWidth">31</item>
      <item name="pathAlpha">129</item>
      <item name="pathColor">@color/green</item>

      <!-- Style standard attributes -->
      <item name="android:background">@drawable/pattern_bg</item>
</style>
LanDenLabs
  • 995
  • 10
  • 8
5

This appears to be a bug in the SDK. I have filed an issue on it, which you may wish to star so as to receive updates on it.

As a worksaround, you can use reflection to access the field:

Class clazz=Class.forName("android.R$styleable");
int i=clazz.getField("Theme_backgroundDimAmount").getInt(clazz);
CommonsWare
  • 910,778
  • 176
  • 2,215
  • 2,253
  • Well according to Dianne Hackborn it was intentionally removed from the SDK by hiding it. Here the Discussion about it http://groups.google.com/group/android-developers/tree/browse_frm/thread/6554c6688f3ca6d9/8d018aa3f5c2beb9?rnum=1&_done=%2Fgroup%2Fandroid-developers%2Fbrowse_frm%2Fthread%2F6554c6688f3ca6d9%3Ftvc%3D1%26#doc_72f29c1df624bbed So is there a way to do it properly without using reflection? – AGrunewald Jan 24 '10 at 15:37
  • If it is intentionally gone, you shouldn't be using it. Internal applications (e.g., Calendar) can use it, because they are not restricted to using the SDK. Beyond that, I have no advice, sorry. I have updated the issue to try to get some answers. – CommonsWare Jan 24 '10 at 16:01
  • 2
    Thanks, ya I agree I shouldn't be using it but then there should be an alternative. And the Gallery View Tutorial should have been updated a long time ago, since it still shows that code. – AGrunewald Jan 24 '10 at 16:34