[android-developers] Re: How to style my own styleable with a style? (Custom view class with custom attribute)

2009-07-08 Thread brian.schimmel

Thank you very much, Dianne! It's alway amazing how quick and correct
your answers are ;)

This solves the problems I mentioned above, and some others I was not
even aware of.

I've seen that TypedArray-stuff in the plattform source before, e.g.
in the constructor of TextView.java, but did not quite get its meaning
and forgot about it. Your example above makes it much clearer.

I was working along the instructions on
http://developer.android.com/guide/topics/ui/custom-components.html to
create my component. Maybe the part that sais "Note that you also
might introduce your own attributes and parameters into the XML that
can be pulled out and used by your constructor." should elaborate some
more, or should be linked to the API demo you provided above.

On 8 Jul., 17:50, Dianne Hackborn  wrote:
> If you are using attrs.getAttributeResourceValue(), then you are not using
> the style/theming system at all.  That is, there was no purpose to defining
> a  an  at all, that function is just retrieving a
> raw value from a resource for a given name.  (This is also why the 
> "http://some.weird.url.com/seems/not/to/matter"; URI doesn't matter -- you
> have declared it as a namespace in your XML, and you have retrieved the
> attribute in that namespace in your Java code, and that is all that is
> happening.  You just made up a namespace and used it.)
>
> You can find a complete example if declaring styleables and themes in API
> demos.  Basically you declare a styleable like this (there is no "id" field
> that is used):
>
> 
>   
>   
>   
>   
> 
>
> Then use it in a layout like this:
>
> http://schemas.android.com/apk/res/android";
>
>         
> xmlns:app="http://schemas.android.com/apk/res/com.example.android.apis";
>
>         android:orientation="vertical"
>         android:layout_width="fill_parent"
>
>         android:layout_height="wrap_content">
>
>     
>             android:background="@drawable/green"
>             android:layout_width="fill_parent"
>
>             android:layout_height="wrap_content"
>             app:text="Green" app:textColor="#" />
>
> 
>
> Note that the URI of xmlns:app is very important, this is the namespace for
> android resources (the first part) in your package (the second part).
>
> Finally to retrieve the resources, you do this:
>
>     public LabelView(Context context, AttributeSet attrs) {
>         super(context, attrs);
>         initLabelView();
>
>         TypedArray a = context.obtainStyledAttributes(attrs,
>
>                 R.styleable.LabelView);
>
>         CharSequence s = a.getString(R.styleable.LabelView_text);
>         if (s != null) {
>             setText(s.toString());
>         }
>
>         // Retrieve the color(s) to be used for this view and apply them.
>
>         // Note, if you only care about supporting a single color, that you
>         // can instead call a.getColor() and pass that to setTextColor().
>         setTextColor(a.getColor(R.styleable.LabelView_textColor, 0xFF00));
>
>         int textSize =
> a.getDimensionPixelOffset(R.styleable.LabelView_textSize, 0);
>         if (textSize > 0) {
>             setTextSize(textSize);
>         }
>
>         a.recycle();
>     }
>
> The use of obtainedStyledAttributes() is very important, as that is the key
> function that extracts the attributes you have declared in your styleable,
> filling them in from the current AttributeSet or style or theme as
> appropriate.
>
> With all of that together, you can now define your theme, assigning values
> to your own custom attributes that will be seen in your custom view.
>
> On Wed, Jul 8, 2009 at 8:02 AM, brian.schim...@googlemail.com <
>
>
>
> brian.schim...@googlemail.com> wrote:
>
> > Hi,
>
> > I'm creating my own View class, and defining custom xml attributes
> > with a attrs.xml. As long as I provide each attribute manually, there
> > is no problem, but
>
> > 
> > 
> >         > name="CustomizedButtonView">
> >                
> >        
> > 
>
> > To be honest, I don't understand the proper use of the attributes "id"
> > and "name" in the above code, but somehow it works. I can now
> > reference the borderDrawable-Attribute from a layout xml file:
>
> > 
> >  >        xmlns:android="http://schemas.android.com/apk/res/android";
> >        xmlns:mypack="http://some.weird.url.com/seems/not/to/matter";
>
> >         >                                android:text="This is my text"
>
> >  mypack:borderDrawable="@drawable/border243"/>
> > 
>
> > My class CustomizedButtonView now reads the attribute like this:
> >        public CustomizedButtonView(Context context, AttributeSet attrs) {
> >                super(context, attrs);
> >                int borderDrawableId = attrs.getAttributeResourceValue(
> >                                "
> >http://some.weird.url.com/seems/not/to/matter";,
> >                                "borderDrawable", -1);
>
> > Until now, everything works fine. Many of my CustomizedButtonView will
> > have the same borderDra

[android-developers] Re: How to style my own styleable with a style? (Custom view class with custom attribute)

2009-07-08 Thread Dianne Hackborn
If you are using attrs.getAttributeResourceValue(), then you are not using
the style/theming system at all.  That is, there was no purpose to defining
a  an  at all, that function is just retrieving a
raw value from a resource for a given name.  (This is also why the "
http://some.weird.url.com/seems/not/to/matter"; URI doesn't matter -- you
have declared it as a namespace in your XML, and you have retrieved the
attribute in that namespace in your Java code, and that is all that is
happening.  You just made up a namespace and used it.)

You can find a complete example if declaring styleables and themes in API
demos.  Basically you declare a styleable like this (there is no "id" field
that is used):


  
  
  
  


Then use it in a layout like this:

http://schemas.android.com/apk/res/android";

xmlns:app="http://schemas.android.com/apk/res/com.example.android.apis";

android:orientation="vertical"
android:layout_width="fill_parent"

android:layout_height="wrap_content">






Note that the URI of xmlns:app is very important, this is the namespace for
android resources (the first part) in your package (the second part).

Finally to retrieve the resources, you do this:

public LabelView(Context context, AttributeSet attrs) {
super(context, attrs);
initLabelView();

TypedArray a = context.obtainStyledAttributes(attrs,

R.styleable.LabelView);

CharSequence s = a.getString(R.styleable.LabelView_text);
if (s != null) {
setText(s.toString());
}

// Retrieve the color(s) to be used for this view and apply them.

// Note, if you only care about supporting a single color, that you
// can instead call a.getColor() and pass that to setTextColor().
setTextColor(a.getColor(R.styleable.LabelView_textColor, 0xFF00));

int textSize =
a.getDimensionPixelOffset(R.styleable.LabelView_textSize, 0);
if (textSize > 0) {
setTextSize(textSize);
}

a.recycle();
}

The use of obtainedStyledAttributes() is very important, as that is the key
function that extracts the attributes you have declared in your styleable,
filling them in from the current AttributeSet or style or theme as
appropriate.

With all of that together, you can now define your theme, assigning values
to your own custom attributes that will be seen in your custom view.

On Wed, Jul 8, 2009 at 8:02 AM, brian.schim...@googlemail.com <
brian.schim...@googlemail.com> wrote:

>
> Hi,
>
> I'm creating my own View class, and defining custom xml attributes
> with a attrs.xml. As long as I provide each attribute manually, there
> is no problem, but
>
> 
> 
> name="CustomizedButtonView">
>
>
> 
>
> To be honest, I don't understand the proper use of the attributes "id"
> and "name" in the above code, but somehow it works. I can now
> reference the borderDrawable-Attribute from a layout xml file:
>
> 
> xmlns:android="http://schemas.android.com/apk/res/android";
>xmlns:mypack="http://some.weird.url.com/seems/not/to/matter";
>
>android:text="This is my text"
>
>  mypack:borderDrawable="@drawable/border243"/>
> 
>
> My class CustomizedButtonView now reads the attribute like this:
>public CustomizedButtonView(Context context, AttributeSet attrs) {
>super(context, attrs);
>int borderDrawableId = attrs.getAttributeResourceValue(
>"
> http://some.weird.url.com/seems/not/to/matter";,
>"borderDrawable", -1);
>
> Until now, everything works fine. Many of my CustomizedButtonView will
> have the same borderDrawable, but not all of them, so I want to define
> a style. My styles.xml reads like this:
>
> 
>name="android:text">Default text
>
>  name="mypack:borderDrawable">@drawable/border243
>
>
> And the layout like that:
>
> 
> xmlns:android="http://schemas.android.com/apk/res/android";
>xmlns:mypack="http://some.weird.url.com/seems/not/to/matter";
>
>style="@style/customStyle1"/>
> 
>
> The android:text is properly set in my instance, but the
> borderDrawable is not. I guess this has something to do with
> namespaces, because inside the styles.xml, the
> name="mypack:borderDrawable" is not handled by the XML parser's
> namespace facility, because its inside an attribute value. So "mypack"
> is in no way connected to "http://some.weird.url.com/seems/not/to/
> matter" and adding it via xmlns:mypack... to the stylefile would not
> help, I guess. In the same file, "android:text" is somehow recognized,
> even though "android" is AFAIK only a ns-defintion for "http://
> schemas.android.com/apk/res/android", which is also not declared in
> that file.
>
> So what is t