我正在为我的应用程序准备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>
另一个:
<?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>
如果你不想玩“找到2个差异”,唯一改变的是<bitmap>
标签中的图像。
我在这里感觉整个WET 1 。有没有办法重用这个drawable的一部分?
1 WET,例如。不是DRY
答案 0 :(得分:11)
简而言之:XML drawable没有参数,因此可能会有点复杂。
通常 1 我会尝试将所有单个<item>
内容分成单独的可绘制文件,然后将它们包含在<item android:drawable="..." />
中。那些可以在其他绘图中重复使用。
例如,您可以将以下项目移动到单独的文件中:
<item>
<shape android:shape="rectangle">
<solid android:color="#ffffff" />
</shape>
</item>
然后,您可以在任何需要的地方包含(重复使用):
<item android:drawable="@drawable/shared_drawable" />
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>
...
现在我们需要定义一个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
该脚本可以放入应用程序(模块)build.gradle
文件中。
现在,在编译时从单个模板文件生成包含不同包含位图的最终drawable。它们的名称为drawable_gen_sharpX.xml
,可以用作普通的drawable。