Define default values ​​for layout_width and layout_height properties for style subclass

Minimum and target SDK is 21 (Lollipop), no support library supported.

I am trying to create a floating action button . So far so good, it does work (based on several other SO threads), here is the code:

  • attrs.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
        <attr name="fabStyle" format="reference"/>
    
    </resources>
    
          

  • styles.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
        <style name="MyTheme" parent="android:Theme.Material.Light.NoActionBar">
            <item name="floatingActionButtonStyle">@style/FabStyle</item>
        </style>
    
        <style name="FabStyle" parent="android:Widget.ImageButton">
            <item name="android:background">@drawable/ripple</item>
            <item name="android:elevation">4dp</item>
        </style>
    
          

(I want the button to inherit the default characteristics of the DefaultButton and it seems to work fine, is this the correct way?)

  • View code (note the use of the custom style attribute in the second constructor):

    public class FloatingActionImageButton extends ImageButton {
    
        public FloatingActionImageButton(Context context) {
            this(context, null);
        }
    
        public FloatingActionImageButton(Context context, AttributeSet attrs) {
            this(context, attrs, R.attr.floatingActionButtonStyle);
        }
    
        public FloatingActionImageButton(Context context, AttributeSet attrs, int defStyleAttr) {
            this(context, attrs, defStyleAttr, 0);
        }
    
        public FloatingActionImageButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
            super(context, attrs, defStyleAttr, defStyleRes);
    
            setOutlineProvider(new ViewOutlineProvider() {
    
                @Override
                public void getOutline(View view, Outline outline) {
                    int width = view.getMeasuredWidth();
                    int height = view.getMeasuredHeight();
                    outline.setOval(0, 0, width, height);
                }
            });
            setClipToOutline(true);
        }
    }
    
          

  • ripple.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <ripple xmlns:android="http://schemas.android.com/apk/res/android"
            android:color="?android:attr/colorPrimary">
    
        <item android:drawable="?android:attr/colorAccent"/>
    
    </ripple>
    
          

  • usage in XML:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                    xmlns:tools="http://schemas.android.com/tools"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    tools:context="com.test.TestActivity">
    
        <com.test.FloatingActionImageButton
            android:id="@+id/refresh_button"
            android:layout_width="@dimen/fab_size"
            android:layout_height="@dimen/fab_size"
            android:layout_alignParentBottom="true"
            android:layout_alignParentEnd="true"
            android:layout_marginBottom="@dimen/padding_big"
            android:layout_marginEnd="@dimen/padding_big"
            android:src="@drawable/ic_action_restart"/>
    
    </RelativeLayout>
    
          

(@ dimen / fab_size - 56dp)

The result is a nice looking boosted FAB, the ripple effect works as intended:

fab

  • Since this is my first such attempt at styling etc. in Android, I would like to ask if what I am doing is "canon". How can I do this if I want to publish my own Fab-noul library? Is the styling code now ready for potential clients of my library to simply define fabStyle in some way (how?) In their styles.xml and my View will use the settings?

  • What I don't like about my solution is that while I would like all FABs to be 56dp as suggested by Google in the document above, I have to figure out the size whenever the fab is used in XML. Since I want the default button to be 56dp, I tried to put layout_width and _height in FabStyle and remove from XML, but AndroidStudio says that I have to set them, and the app actually crashes at runtime, saying the values ​​should be installed.

I tried setting @null to XML, which crashed, and 0dp / px, which just made the button, well, invisible ...

Is it possible to define default values ​​for these attributes, or am I out of luck here?

+3


source to share





All Articles