androidandroid-studioandroid-drawableandroid-shapeandroid-shapedrawable

Can we create multiple shapes in one xml file and point them within this single file?


For example to create a button whose button_normal state shows some different style and button_pressed state shows some different style, we create three files:

button_normal.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="#0084FF" />
</shape>

button_pressed.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="#FF19F4" />
</shape>

And finally, button.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true"
        android:drawable="@drawable/button_pressed" />
    <item android:drawable="@drawable/button_normal" />
</selector>

As you can see, inside the button.xml file we are pointing the button_normal.xml and button_pressed.xml. Ok fine that is normal.

Actual consideration:

Now the question is that is this possible to add the source of button_normal.xml and button_pressed.xml inside the button.xml and point the these two shapes (button_normal and button_pressed) within the same file button.xml as:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true"
        android:drawable="@drawable/button_pressed" />
    <item android:drawable="@drawable/button_normal" />
</selector>

<shape android:shape="rectangle">
    <solid android:color="#0084FF" />
    <corners android:radius="3dp" />
</shape>

<shape android:shape="rectangle">
    <solid android:color="#FF19F4" />
</shape>

The summary of the question is that is this possible to create multiple shapes within one xml file and point them in the same file to something else (if needed) - for example see the above source? So in that case we will not create extra files for each shape.

Thanks in advance!!!


Solution

  • Nesting works:

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_pressed="true">
            <shape android:shape="rectangle">
                <solid android:color="#0084FF" />
                <corners android:radius="3dp" />
            </shape>
        </item>
        <item>
            <shape android:shape="rectangle">
                <solid android:color="#FF19F4" />
            </shape>
        </item>
    </selector>
    

    You can nest a lot of the XML drawable resources. Here is a complex example from the Android SDK (seekbar_track_material.xml), blending a LayerListDrawable, a ScaleDrawable, a StateListDrawable, and a couple of ShapeDrawables:

    <?xml version="1.0" encoding="utf-8"?>
    <!-- Copyright (C) 2014 The Android Open Source Project
    
         Licensed under the Apache License, Version 2.0 (the "License");
         you may not use this file except in compliance with the License.
         You may obtain a copy of the License at
    
              http://www.apache.org/licenses/LICENSE-2.0
    
         Unless required by applicable law or agreed to in writing, software
         distributed under the License is distributed on an "AS IS" BASIS,
         WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
         See the License for the specific language governing permissions and
         limitations under the License.
    -->
    
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:id="@id/background"
              android:gravity="center_vertical|fill_horizontal">
            <shape android:shape="rectangle"
                   android:tint="?attr/colorProgressBackgroundNormal">
                <corners android:radius="?attr/progressBarCornerRadius" />
                <size android:height="@dimen/seekbar_track_background_height_material" />
                <solid android:color="@color/white_disabled_material" />
            </shape>
        </item>
        <item android:id="@id/secondaryProgress"
              android:gravity="center_vertical|fill_horizontal">
            <scale android:scaleWidth="100%">
                <selector>
                    <item android:state_enabled="false"
                          android:drawable="@color/transparent" />
                    <item>
                        <shape android:shape="rectangle"
                               android:tint="?attr/colorControlActivated">
                            <corners android:radius="?attr/progressBarCornerRadius" />
                            <size android:height="@dimen/seekbar_track_progress_height_material" />
                            <solid android:color="@color/white_disabled_material" />
                        </shape>
                    </item>
                </selector>
            </scale>
        </item>
        <item android:id="@id/progress"
              android:gravity="center_vertical|fill_horizontal">
            <scale android:scaleWidth="100%">
                <selector>
                    <item android:state_enabled="false"
                          android:drawable="@color/transparent" />
                    <item>
                        <shape android:shape="rectangle"
                               android:tint="?attr/colorControlActivated">
                            <corners android:radius="?attr/progressBarCornerRadius" />
                            <size android:height="@dimen/seekbar_track_progress_height_material" />
                            <solid android:color="@color/white" />
                        </shape>
                    </item>
                </selector>
            </scale>
        </item>
    </layer-list>