I had to dig for a while (some 10 minutes) to get my android fragments to receive the attributes form the xml layout.
This is how I got it working.
Starting by with a fragment (I'm using Jake Burton's ActionBarSherlok but the same should work when extending the support or original fragment classes):
1: class MyOwnFragment extends extends SherlockFragment {
2: /* fragments attributes */
3: private int padding = 8; // default value that will be overridden if there's a layout attributes
4: private String lavel = ""; // default value that will be overridden if there's a layout attributes
5:
6: @Override
7: public void onCreate (Bundle savedInstanceState) {
8: super.onCreate (savedInstanceState);
9: if (savedInstanceState != null) {
10: // use the saved state that was set in the #onSaveInstanceState
11: }
12: }
13:
14: @Override
15: public void onSaveInstanceState (Bundle outState) {
16: // save the state of our fragment into the outState bundle.
17: }
18:
19:
20: @Override
21: public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
22: View fragmentRootView = // what ever you need, inflate a layout, progamatically create a view, etc.
23:
24: // if there were attibutes in the layout XML
25: // then we would have captured them in the #onInflate method
26: // so we would already have them available
27:
28: // we can also use the savedInstanceState here
29: // to set child views of GroupView for example.
30:
31: return fragmentRootView;
32: }
33:
34: @Override
35: public void onInflate (Activity activity, AttributeSet attrs, Bundle savedInstanceState) {
36: super.onInflate (activity, attrs, savedInstanceState);
37: TypedArray typedArray = activity.obtainStyledAttributes(attrs, R.styleable.MyOwnFragment);
38: if (typedArray != null) {
39: // this is where we can get out attributes.
40: // we can "parse" them into class fields
41: this.padding = typedArray.getDimensionPixelSize (R.styleable.MyOwnFragment_padding, this.padding);
42: String labelAttr = typedArray.getString (R.styleable.MyOwnFragment_label);
43: if (labelAttr != null) {
44: this.label = labelAttr;
45: }
46: } else {
47: // no attributes are defined
48: }
49: }
50: }
The R.stylable.MyOwnFragment is a reference to the styleable defined at res/attrs.xml:
1: <?xml version="1.0" encoding="utf-8"?>
2: <resources>
3: <declare-styleable name="MyOwnFragment">
4: <attr name="padding" format="dimension" />
5: <attr name="label" format="string" />
6: </declare-styleable>
7: </resources>
And finally in the layout file:
1: <?xml version="1.0" encoding="utf-8"?>
2: <RelativeLayout
3: xmlns:android="http://schemas.android.com/apk/res/android"
4: xmlns:app="http://schemas.android.com/apk/res/our.package.name"
5: android:layout_width="fill_parent"
6: android:layout_height="fill_parent">
7:
8: <fragment android:name="our.package.name.MyOwnFragment"
9: android:id="@+id/myOwnFragment"
10: android:layout_width="wrap_content"
11: android:layout_height="wrap_content"
12: app:padding="2dp"
13: app:label="Fragment label" />
14: </RelativeLayout>
Now the trick I had to find was that the we need to use the namespace of our application in the layout XML or it doesn't work (the attributes do not arrive at our fragment onInflate method). The strange thing is that the android lint will then complain that the defined namespace is not used but if we ignore the warning everything works fine.
The Fragment documentation and the sdk example are not very helpful. They reuse the android namespace but that seems not to work (for me at least) as then it complains that the attribute is not recognized.