在Android上重用drawable的部分内容

Spo*_*ook 9 android android-drawable

我正在为我的应用准备drawables.我有很多单选按钮,它们显示为带有可选框架的图像(选中时).一个drawable看起来如下:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true">
        <layer-list>
            <item>
                <shape android:shape="rectangle">
                    <solid android:color="@color/colorPrimary" />
                </shape>
            </item>

            <item>
                <inset android:insetTop="@dimen/selectionBorderSize"
                    android:insetLeft="@dimen/selectionBorderSize"
                    android:insetRight="@dimen/selectionBorderSize"
                    android:insetBottom="@dimen/selectionBorderSize">
                    <layer-list>
                        <item>
                            <shape android:shape="rectangle">
                                <solid android:color="#ffffff"></solid>
                            </shape>
                        </item>
                        <item>
                            <bitmap android:src="@drawable/sharp7" >
                                <padding android:bottom="@dimen/selectionBorderSize"
                                    android:top="@dimen/selectionBorderSize"
                                    android:left="@dimen/selectionBorderSize"
                                    android:right="@dimen/selectionBorderSize" />
                            </bitmap>
                        </item>
                    </layer-list>
                </inset>
            </item>
        </layer-list>
    </item>

    <item android:state_checked="false">
        <layer-list>
            <item>
                <shape android:shape="rectangle">
                    <solid android:color="#ffffff" />
                </shape>
            </item>

            <item>
                <inset android:insetTop="@dimen/selectionBorderSize"
                    android:insetLeft="@dimen/selectionBorderSize"
                    android:insetRight="@dimen/selectionBorderSize"
                    android:insetBottom="@dimen/selectionBorderSize">
                    <layer-list>
                        <item>
                            <shape android:shape="rectangle">
                                <solid android:color="#ffffff"></solid>
                            </shape>
                        </item>
                        <item>
                            <bitmap android:src="@drawable/sharp7" >
                                <padding android:bottom="@dimen/selectionBorderSize"
                                    android:top="@dimen/selectionBorderSize"
                                    android:left="@dimen/selectionBorderSize"
                                    android:right="@dimen/selectionBorderSize" />
                            </bitmap>
                        </item>
                    </layer-list>
                </inset>
            </item>
        </layer-list>
    </item>

    <item>
        <shape android:shape="rectangle">
            <solid android:color="#ffffff" />
        </shape>
    </item>
</selector>
Run Code Online (Sandbox Code Playgroud)

另一个:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true">
        <layer-list>
            <item>
                <shape android:shape="rectangle">
                    <solid android:color="@color/colorPrimary" />
                </shape>
            </item>

            <item>
                <inset android:insetTop="@dimen/selectionBorderSize"
                    android:insetLeft="@dimen/selectionBorderSize"
                    android:insetRight="@dimen/selectionBorderSize"
                    android:insetBottom="@dimen/selectionBorderSize">
                    <layer-list>
                        <item>
                            <shape android:shape="rectangle">
                                <solid android:color="#ffffff"></solid>
                            </shape>
                        </item>
                        <item>
                            <bitmap android:src="@drawable/sharp6" >
                                <padding android:bottom="@dimen/selectionBorderSize"
                                    android:top="@dimen/selectionBorderSize"
                                    android:left="@dimen/selectionBorderSize"
                                    android:right="@dimen/selectionBorderSize" />
                            </bitmap>
                        </item>
                    </layer-list>
                </inset>
            </item>
        </layer-list>
    </item>

    <item android:state_checked="false">
        <layer-list>
            <item>
                <shape android:shape="rectangle">
                    <solid android:color="#ffffff" />
                </shape>
            </item>

            <item>
                <inset android:insetTop="@dimen/selectionBorderSize"
                    android:insetLeft="@dimen/selectionBorderSize"
                    android:insetRight="@dimen/selectionBorderSize"
                    android:insetBottom="@dimen/selectionBorderSize">
                    <layer-list>
                        <item>
                            <shape android:shape="rectangle">
                                <solid android:color="#ffffff"></solid>
                            </shape>
                        </item>
                        <item>
                            <bitmap android:src="@drawable/sharp6" >
                                <padding android:bottom="@dimen/selectionBorderSize"
                                    android:top="@dimen/selectionBorderSize"
                                    android:left="@dimen/selectionBorderSize"
                                    android:right="@dimen/selectionBorderSize" />
                            </bitmap>
                        </item>
                    </layer-list>
                </inset>
            </item>
        </layer-list>
    </item>

    <item>
        <shape android:shape="rectangle">
            <solid android:color="#ffffff" />
        </shape>
    </item>
</selector>
Run Code Online (Sandbox Code Playgroud)

如果你不想玩"找到2个差异",唯一改变的是<bitmap>标签中的图像.

我在这里感觉整个WET 1.有没有办法重用这个drawable的一部分?

1 WET,例如.未

Flo*_*ern 11

简而言之:XML drawable没有参数,因此可能会有点复杂.

通常1我会尝试将所有单个<item>内容分成单独的可绘制文件,然后将它们包含在内<item android:drawable="..." />.那些可以在其他drawables中重复使用.

例如,您可以将以下项目移动到单独的文件中:

<item>
    <shape android:shape="rectangle">
        <solid android:color="#ffffff" />
    </shape>
</item>
Run Code Online (Sandbox Code Playgroud)

然后,您可以在需要的任何地方包含(重用)它:

<item android:drawable="@drawable/shared_drawable" />
Run Code Online (Sandbox Code Playgroud)

1但是,在您的情况下,您可能只使用此方法可以节省约10%,因为<bitmap>元素深埋在层次结构中.


另一种略带异国情调的方法是使用Gradle任务从单个可绘制模板生成多个XML drawable.这显然要求您分别使用Gradle或Android Studio.

您可以将可绘制文件放入/res/raw文件夹(或任何其他不会导致问题的文件夹).我将这个XML模板文件命名drawable_template.xml为如下所述.在这个文件中,我们使用Groovy模板变量${bitmapdrawable}作为实际位图drawable名称的占位符:

...
    <item>
        <bitmap android:src="@drawable/${bitmapdrawable}"><!-- placeholder for gradle -->
            ...
        </bitmap>
    </item>
...
Run Code Online (Sandbox Code Playgroud)

现在我们需要定义一个Gradle任务,将drawable模板复制到/res/drawable包含所需位图drawable 的实际文件夹中:

def drawablesToGenerate = ['sharp5', 'sharp6', 'sharp7', 'sharp8']  // bitmap names
task drawableTemplate << {
    drawablesToGenerate.each { drawableName ->  // for each drawable
        copy {
            println("copy template for ${drawableName}")
            from 'src/main/res/raw'  // source folder
            into 'src/main/res/drawable'  // target folder
            include 'drawable_template.xml'  // template file
            // rename file to final drawable
            rename('drawable_template.xml', "drawable_gen_${drawableName}.xml")
            expand(bitmapdrawable: "${drawableName}")
        }
    }
}
preBuild.dependsOn drawableTemplate
Run Code Online (Sandbox Code Playgroud)

该脚本可以放入应用程序(模块)的build.gradle文件中.

现在,在编译时从单个模板文件生成具有不同包含的位图的最终drawable.它们有名称drawable_gen_sharpX.xml,可以用作普通的drawables.