Issue
I'm trying to make a custom_button, and what I have so far is this, two states (pressed and enabled) have their own shape with a border:
<?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>
This works, but it specifies two identical buttons where only the colors are different. When I add the other button states and more look 'n feel this is gonna be more and more duplicating. Is there a way of having a base_button.xml drawable where the basic same-for-every-button attributes can be set and a custom_button.xml where attributes specific to the button state can be set in their corresponding tag?
Below is a pseudo-example of what I mean, but I don't know how to make that a reality. custom_button.xml handles the button states and base_button.xml specifies the basic characteristics of the button.
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>
Is this even possible in XML? I came across xsl:variable online, but couldn't get it to work. Any suggestions on how to this or alternative ways of achieving the same result are much appreciated!
Solution
You can use a ColorStateList for the colors. Define a ColorStateList for the widget's border and one for its fill. The state of the widget will be pushed down to the ColorStateList where the color will be selected. You can then define a drawable as follows:
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>
The ColorStateLists will look like this. (Forgive the color selection.)
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>
And finally, the sample layout file:
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>
Putting it all together, it will look like this:
Answered By - Cheticamp
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.