Android triangle (arrow) defined as an XML shape

Arrow icons are widely used in android applications. Some use cases are pagination, incrementing or decrementing numeric values or on next / previous buttons. The example of such arrow that I needed was gray triangle arrow like this one

tr

I decided to build such reusable arrow as an xml drawable, so that there is no need to generate plain graphic .png files each time. Thanks to it I can easily change the colour, size and arrow direction.

Source

I created arrow_up.xml file in drawables directory with contents:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item>
        <rotate
            android:fromDegrees="45"
            android:toDegrees="45"
            android:pivotX="-40%"
            android:pivotY="87%" >
            <shape
                android:shape="rectangle" >
                <stroke android:color="@color/transparent" android:width="10dp"/>
                <solid
                    android:color="@color/your_color_here" />
            </shape>
        </rotate>
    </item>
</layer-list>

The idea is to create rectangle shape (<shape/>), fill with gray solid color (<solid/>), rotate it 45 degrees (<rotate/>) and move it over X and Y axis (pivotX and pivotY) in a way that only half of the rectangle is visible (cut along the diagonal).

I also added thick border (<stroke/>) with transparent color. This is because my arrow is a button, so the invisible part around is needed to ease the click (it enlarges click detection area size).

How to use it

The usage is as simple as any other xml drawable shape. It is just enough to set it as view background. Here is button example:

<Button
	android:layout_width="70dp"
	android:layout_height="70dp"
	android:background="@drawable/arrow_up" />

If you need arrow pointing in other direction, you can just rotate it. Here is arrow down:

<Button
	android:layout_width="70dp"
	android:layout_height="70dp"
	android:rotation="180"
	android:background="@drawable/arrow_up" />

So comapred to png icon it is:

scalable, because you can change its size as you wish, without providing bigger or smaller png files for each screen density. And there is no ‘pixelization’ visible regardless of scale used
customizable, because you can easier adjust its color to better fit your UI or use it in other projectno need to regenerate png file and change it in project. Just change the xml attribute.

Quite tricky and nice :)

Did I help you?
I manage this blog and share my knowledge for free sacrificing my time. If you appreciate it and find this information helpful, please consider making a donation in order to keep this page alive and improve quality

Donate Button with Credit Cards

Thank You!

54 thoughts on “Android triangle (arrow) defined as an XML shape

    1. It is:
      – scalable, because you can change its size as you wish, without providing bigger or smaller png files for each screen density. And there is no ‘pixelization’ visible regardless of scale used
      – customizable, because you can easier adjust its color to better fit your UI or use it in other project – no need to regenerate png file and change it in project. Just change the xml attribute.

      1. How can we change the triangle inner color in different cases programatically. Something like in 1 case I need it grey and in other case I need it yellow, and want to change it at run time.

  1. Hey Jacek,
    Thanks for you post its great!
    I’ve created a triangle and it works great as a drawable,
    But i wanted to use it as a layer in a layer list and i’m having hard time positioning it according to its first frame’s list…

    Can you please provide some explanation about it ?

    Thanks!

    1. I am afraid that layer list is noy capable of placing items different but the default one.

      Maybe try to use relative layout in xml file

    1. Pivot X/Y are the X / Y coordinate of the center of rotation.

      Expressed either: in pixels relative to the object’s left edge (such as “5”), in percentage relative to the object’s left edge (such as “5%”), or in percentage relative to the parent container’s left edge (such as “5%p”).

    2. Pivot X/Y are the X / Y coordinate of the center of rotation.

      Expressed either: in pixels relative to the object’s left edge (such as “5”), in percentage relative to the object’s left edge (such as “5%”), or in percentage relative to the parent container’s left edge (such as “5%p”).

    3. Pivot X/Y are the X / Y coordinate of the center of rotation.

      Expressed either: in pixels relative to the object’s left edge (such as “5”), in percentage relative to the object’s left edge (such as “5%”), or in percentage relative to the parent container’s left edge (such as “5%p”).

  2. This is nice, but I’d like to make an equilateral triangle with rounded edges. I’m afraid it’s just not possible in XML. Why didn’t Android give us a triangle?

  3. how to i place this triangle in center position in an layout xml file .I can use the android:gravity function it is not work??

  4. Thanks for taking the time to share this. Am I correctly understanding the rotation when I say that this will only work within a square view? (ie a view with equal height and width)

    1. yes. if you need different type of triangle you probably need to draw it in png file

      1. I love the solution you posted. I am perfectly happy with a right angle for the triangle, I just want it to be in the center of a long rectangular view instead of a square shaped view. I think if I go this route I will have to create a square shaped view around the triangle and center that view inside the long rectangular view.

        Thanks again for the post. It was great to have a first hand example of how rotations and pivot points work.

  5. This doesn’t appear to work for me. The triangle renders pointing to the bottom right, and setting the rotation of the container that has it as a background only gives me a half a rectangle.

    It seems like you can’t rotate the triangle by any degrees other than multiples of 90 without some visual bug?

      1. What’s weird is that when I use your example, the arrow points diagonally instead of up, so I can’t even have it point in a horizontal or vertical direction. It’s always pointing towards a corner, and each 90 degree turn points to a different corner. What causes this?

    1. It is written in a post. set the triangle xml as a view background. Than this view can be rotated with ‘android:rotation’ like this:

  6. Nice tutorial dude, really helped me out a lot! I needed a triangle to put it over an ImageView using FrameLayout! Worked exactly I wanted!.. Thanks

  7. Hey nice work!
    But i want to change the solid color dynamically. How can i do this ?

    1. Well… I don’t think so. Is there any way in Android to place views with boundaries different than rectangular?

  8. Pingback: area pans
  9. im trying to create a tooltip by adding the arrow to a shape that has borderRadius so as to form a perfect tooltip but when i add the item link of the shape to the arrow.xml file, the arrow design automatically changes.
    I’ve tried all methods, still same result, it changes its shape from arrow to something like…a pentagon! Please how can i solve this?

Give Your feedback: