Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - AttributeSet

Tags:

android

I have a code something like this:

public class CannonView extends SurfaceViewimplements SurfaceHolder.Callback{
Activity activity;

And its constructor:

public CannonView(Context context, AttributeSet attrs){
Super(context,attrs)
activity = (Activity) context; 

but apparently the AttributeSet is doing nothing, I dont know why is there, so my questions are: 1.-what is AttributeSet? 2.-why do we need to provide AttributeSet attrs as a second argument? by the way the rest of code is for painting using canvas. Thanks.

like image 377
user2580401 Avatar asked Aug 09 '13 21:08

user2580401


People also ask

What is AttributeSet in Android?

AttributeSet (Android Docs)A collection of attributes, as found associated with a tag in an XML document. Basically if you are trying to create a custom view, and you want to pass in values like dimensions, colors etc, you can do so with AttributeSet .

What is typed array in Android?

Container for an array of values that were retrieved with Resources. Theme#obtainStyledAttributes(AttributeSet, int[], int, int) or Resources#obtainAttributes .

What is defStyleAttr?

defStyleAttr An attribute in the current theme that contains a reference to a style resource that supplies defaults values for the StyledAttributes. Can be 0 to not look for defaults.


2 Answers

http://developer.android.com/training/custom-views/create-view.html - this is an explanation.

Shortly, attributeSet is needed for GUI editor.
AttributeSet is a set of parameters like layout_width, layour_height and so on. It you need you new custom attributes, the you need to extend to expand AttributSet class

like image 168
Sergey Brazhnik Avatar answered Sep 18 '22 20:09

Sergey Brazhnik


Views have 3 constructors:

SurfaceView(Context context)
SurfaceView(Context context, AttributeSet attrs)
SurfaceView(Context context, AttributeSet attrs, int defStyle)

NOTE: The third style was added in API Level 11. But if you want to create a custom view for newer versions of the API you should implement it.

When implementing a custom view, if you want it to be widely usable, then you should implement the three Constructors - as another use of your View in a different part of the code or another app could instantiate it using any of the constructors.

If you are constructing the view programatically, then you can decide which constructor you use.

But, the Android Framework instantiates your view when they are referenced from XML.

<com.me.Common.MyView
   android:layout_width="wrap_contents"
...
/>

etc.

These XML declarations that instantiate your view can include many Attributes, some of them the standard android ones in the "android:" namespace. If you pass these to the SuperClass you are extending (if you are extending a View class - as you are) then it will parse them and use them and you don't need to do much.

But you can also define and use custom attributes in your own name name

<com.me.Common.MyView
   android:layout_width="wrap_contents"
...
   com.me:num_elements="10"
/>

and then you should parse the attribute set passed in the constructor and change the behaviour of your View object to respect the settings in the XML. The "android:" attributes will be parsed and used by the Superclass.

So, as you don´t know exactly how your custom view will be instantiated by the Android Framework (it will depend on the XML tag declaring it), you should implement the three constructors.

NOTE: It's tempting to do the standard Java override style and have each constructor use the more complex one via super:

MyView(Context context, AttributeSet attrs) {
    super(context, attrs, 0);
}

But I have seen this lead to problems, as 0 is not always a valid style. So, I recommend you implement a init() method that does your own customer code, and that you call the constructor of the Superclass that corresponds to the parameters of the constructor the Framework use for your customer view:

public AnimationController(Context context) {
    super(context);
    initUI(context, null, -1);
}

public AnimationController(Context context, AttributeSet attrs) {
    super(context, attrs);
    initUI(context, attrs, -1);
}

public AnimationController(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    initUI(context, attrs, defStyle);
}

Especially as the super() with the three parameters may not exist on a device with API < 11.

Implementing custom views this way makes them much more configurable and reusable, as you can lay them out in different XML files with different attributes set, or use a style that defines a set of attributes - just as the Android views are used.

like image 31
Andrew Mackenzie Avatar answered Sep 17 '22 20:09

Andrew Mackenzie