Issue
We have an Android app which has a view with a row of buttons at the top. Each of the three buttons in the row is made up of an icon inside a circle with the text that describes it below the circle (something like this wireframe, though I picked the icons at random since I'm not allowed to share the actual ones):
Originally, these buttons were designed having the icon, circle background, and circle border as a raster image (with multiple densities, as required) and the following code (repeated three times, once for each button):
<LinearLayout
android:id="@+id/button1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/button1Image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:clickable="false"
android:contentDescription="@string/button1Text"
android:src="@drawable/button1Image" />
<TextView
android:id="@+id/txtButton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="3dp"
android:text="@string/button1Text"
android:textColor="@android:color/white"
android:textSize="14sp" />
</LinearLayout>
I have been given the task of modernizing this code, because the icons we are using are actually all originally vector icons (from the Material Design Library) and we should be able to just use the vectors and not need to worry about rasterizing and pixel density.
What I would like to do is remove the circle from the icon itself (so I can use the Material vector icons without modifying them) and have the button background add the circle. (This also allows me to change the color of the circle based on the app variant without having many different sets of images.)
I have seen many examples of how to make a circular button with both the icon and the text inside it, but I cannot seem to figure out how to make a single button that looks the way I want.
How can I make a nice reusable component that takes the vector icon and text and gives me this layout for each button?
CLARIFICATION: What I would like to do here is remove the circles from the icons and have the circle be the background of the button. I know I can do that with two buttons, one for the text with no background and one for the image with a background, but I want to know if there is a way I can do this with a single XML tag since I have a whole bunch of them.
Solution
You can use button and set icon of button using android:drawableTop="@drawable/icon"
.
Here is full code:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:background="@android:color/transparent"
android:drawableTop="@drawable/ic_launcher_background"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
Updated: What you can do in that case is to create custom component and set top icon from there. Here are steps I tried and it worked:
Create
attrs.xml
file inres/values folder
and topIcon as attribute name:<?xml version="1.0" encoding="utf-8"?> <resources> <attr name="topIcon" format="reference" /> <declare-styleable name="CustomButton"> <attr name="topIcon" /> </declare-styleable> </resources>
Create
CustomButton
class and add circle drawable as background layer using LayerDrawable:public class CustomButton extends Button { public CustomButton(Context context, AttributeSet attrs) { super(context, attrs); if (attrs != null) { TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomButton); Drawable topIcon = typedArray.getDrawable(R.styleable.CustomButton_topIcon); LayerDrawable layerDrawable = new LayerDrawable( new Drawable[]{getResources().getDrawable(R.drawable.circle), topIcon} ); setCompoundDrawablesWithIntrinsicBounds(null, layerDrawable, null, null); typedArray.recycle(); } } }
Use created component from layout file and set
topIcon
attribute. Also, as we extend Button class, you can use any other attributes of it. Make sure package name is correct:<com.natigbabayev.experimental.CustomButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" app:topIcon="@android:drawable/ic_input_add"/>
Answered By - Natig Babayev
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.