Android XML:自定义按钮可绘制,每个按钮状态不重复 xml?
Android XML: Custom button drawable without duplicate xml for each button state?
我正在尝试制作一个 custom_button,到目前为止我所拥有的是,两个状态(按下和启用)有自己的形状和边框:
<?xml version='1.0' encoding='utf-8'?>
<selector xmlns:android='http://schemas.android.com/apk/res/android'>
<!-- Pressed -->
<item android:state_pressed='true'>
<layer-list>
<item> <!-- Border -->
<shape
android:shape='rectangle'>
<solid android:color='@color/Foreground'/>
</shape>
</item>
<item android:bottom='2dp' android:top='2dp' android:left='2dp' android:right='2dp'> <!-- Color -->
<shape
android:shape='rectangle'>
<solid android:color='@color/WidgetSoft'/>
</shape>
</item>
</layer-list>
</item>
<!-- Enabled -->
<item>
<layer-list>
<item> <!-- Border -->
<shape
android:shape='rectangle'>
<solid android:color='@color/Foreground'/>
</shape>
</item> <!-- Color -->
<item android:bottom='2dp' android:top='2dp' android:left='2dp' android:right='2dp'> <!-- Base Color -->
<shape
android:shape='rectangle'>
<solid android:color='@color/Widget'/>
</shape>
</item>
</layer-list>
</item>
</selector>
这有效,但它指定了两个相同的按钮,只是颜色不同。当我添加其他按钮状态和更多外观时,这会越来越重复。有没有一种方法可以让 base_button.xml 可绘制,其中可以设置每个按钮的基本相同属性和 custom_button.xml 在哪里可以在相应的标签中设置特定于按钮状态的属性?
下面是我的意思的伪示例,但我不知道如何使它成为现实。 custom_button.xml 处理按钮状态,base_button.xml 指定按钮的基本特征。
custom_button.xml:
<?xml version='1.0' encoding='utf-8'?>
<selector xmlns:android='http://schemas.android.com/apk/res/android'>
<!-- Pressed -->
<item android:state_pressed='true' android:drawable='@drawable/base_button'>
<!-- SET GLOBAL_BORDER_COLOR TO '@color/btnPressedBorder' -->
<!-- SET GLOBAL_BASE_COLOR TO '@color/btnPressedBase' -->
</item>
<!-- Enabled -->
<item android:drawable='@drawable/base_button'>
<!-- SET GLOBAL_BORDER_COLOR TO '@color/btnEnabledBorder' -->
<!-- SET GLOBAL_BASE_COLOR TO '@color/btnEnabledBase' -->
</item>
</selector>
base_button.xml:
<?xml version='1.0' encoding='utf-8'?>
<layer-list xmlns:android='http://schemas.android.com/apk/res/android'>
<item>
<shape
android:shape='rectangle'>
<solid android:color= GLOBAL_BORDER_COLOR />
</shape>
</item>
<item android:bottom='2dp' android:top='2dp' android:left='2dp' android:right='2dp'>
<shape
android:shape='rectangle'>
<solid android:color= GLOBAL_BASE_COLOR />
</shape>
</item>
</layer-list>
这在 XML 中甚至可能吗?我在网上遇到了 xsl:variable,但无法正常工作。非常感谢任何关于如何实现相同结果的建议或替代方法!
您可以使用 ColorStateList 作为颜色。为小部件的边框定义一个 ColorStateList,并为其填充定义一个。小部件的状态将被下推到 ColorStateList,其中将选择颜色。然后,您可以按如下方式定义可绘制对象:
base_button.xml
<layer-list>
<item>
<shape android:shape='rectangle'>
<solid android:color="@color/widget_border" />
</shape>
</item>
<item
android:bottom='2dp'
android:left='2dp'
android:right='2dp'
android:top='2dp'>
<shape android:shape='rectangle'>
<solid android:color="@color/widget_fill" />
</shape>
</item>
</layer-list>
ColorStateLists 看起来像这样。 (请原谅颜色选择。)
widget_fill.xml
<selector>
<item android:color="@android:color/holo_red_light" android:state_pressed="true" />
<item android:color="@android:color/holo_blue_light" android:state_enabled="true" />
</selector>
widget_border.xml
<selector>
<item android:color="@android:color/black" android:state_pressed="true" />
<item android:color="@android:color/holo_red_light" android:state_enabled="true" />
</selector>
最后,示例布局文件:
activity_main.xml
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:background="@drawable/base_button"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
将所有内容放在一起,将如下所示:
我正在尝试制作一个 custom_button,到目前为止我所拥有的是,两个状态(按下和启用)有自己的形状和边框:
<?xml version='1.0' encoding='utf-8'?>
<selector xmlns:android='http://schemas.android.com/apk/res/android'>
<!-- Pressed -->
<item android:state_pressed='true'>
<layer-list>
<item> <!-- Border -->
<shape
android:shape='rectangle'>
<solid android:color='@color/Foreground'/>
</shape>
</item>
<item android:bottom='2dp' android:top='2dp' android:left='2dp' android:right='2dp'> <!-- Color -->
<shape
android:shape='rectangle'>
<solid android:color='@color/WidgetSoft'/>
</shape>
</item>
</layer-list>
</item>
<!-- Enabled -->
<item>
<layer-list>
<item> <!-- Border -->
<shape
android:shape='rectangle'>
<solid android:color='@color/Foreground'/>
</shape>
</item> <!-- Color -->
<item android:bottom='2dp' android:top='2dp' android:left='2dp' android:right='2dp'> <!-- Base Color -->
<shape
android:shape='rectangle'>
<solid android:color='@color/Widget'/>
</shape>
</item>
</layer-list>
</item>
</selector>
这有效,但它指定了两个相同的按钮,只是颜色不同。当我添加其他按钮状态和更多外观时,这会越来越重复。有没有一种方法可以让 base_button.xml 可绘制,其中可以设置每个按钮的基本相同属性和 custom_button.xml 在哪里可以在相应的标签中设置特定于按钮状态的属性?
下面是我的意思的伪示例,但我不知道如何使它成为现实。 custom_button.xml 处理按钮状态,base_button.xml 指定按钮的基本特征。
custom_button.xml:
<?xml version='1.0' encoding='utf-8'?>
<selector xmlns:android='http://schemas.android.com/apk/res/android'>
<!-- Pressed -->
<item android:state_pressed='true' android:drawable='@drawable/base_button'>
<!-- SET GLOBAL_BORDER_COLOR TO '@color/btnPressedBorder' -->
<!-- SET GLOBAL_BASE_COLOR TO '@color/btnPressedBase' -->
</item>
<!-- Enabled -->
<item android:drawable='@drawable/base_button'>
<!-- SET GLOBAL_BORDER_COLOR TO '@color/btnEnabledBorder' -->
<!-- SET GLOBAL_BASE_COLOR TO '@color/btnEnabledBase' -->
</item>
</selector>
base_button.xml:
<?xml version='1.0' encoding='utf-8'?>
<layer-list xmlns:android='http://schemas.android.com/apk/res/android'>
<item>
<shape
android:shape='rectangle'>
<solid android:color= GLOBAL_BORDER_COLOR />
</shape>
</item>
<item android:bottom='2dp' android:top='2dp' android:left='2dp' android:right='2dp'>
<shape
android:shape='rectangle'>
<solid android:color= GLOBAL_BASE_COLOR />
</shape>
</item>
</layer-list>
这在 XML 中甚至可能吗?我在网上遇到了 xsl:variable,但无法正常工作。非常感谢任何关于如何实现相同结果的建议或替代方法!
您可以使用 ColorStateList 作为颜色。为小部件的边框定义一个 ColorStateList,并为其填充定义一个。小部件的状态将被下推到 ColorStateList,其中将选择颜色。然后,您可以按如下方式定义可绘制对象:
base_button.xml
<layer-list>
<item>
<shape android:shape='rectangle'>
<solid android:color="@color/widget_border" />
</shape>
</item>
<item
android:bottom='2dp'
android:left='2dp'
android:right='2dp'
android:top='2dp'>
<shape android:shape='rectangle'>
<solid android:color="@color/widget_fill" />
</shape>
</item>
</layer-list>
ColorStateLists 看起来像这样。 (请原谅颜色选择。)
widget_fill.xml
<selector>
<item android:color="@android:color/holo_red_light" android:state_pressed="true" />
<item android:color="@android:color/holo_blue_light" android:state_enabled="true" />
</selector>
widget_border.xml
<selector>
<item android:color="@android:color/black" android:state_pressed="true" />
<item android:color="@android:color/holo_red_light" android:state_enabled="true" />
</selector>
最后,示例布局文件:
activity_main.xml
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:background="@drawable/base_button"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
将所有内容放在一起,将如下所示: