113

I am creating an app, with resources that can be reused (because buttons are always the same, but mirrored or rotated). I do want to use the same resource so I don't have to add 3 more resources that are exactly like the original but rotated. But I also don't want to mix the code with things that can be declared in the XML or make transformations with a matrix that will cost processing time.

I've got a two state button declared in an XML.

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true"
          android:drawable="@drawable/and_card_details_button_down_left_onclick" /> <!-- pressed -->
    <item android:drawable="@drawable/and_card_details_button_down_left" /> <!-- default -->
</selector>

and I want to reuse the drawable because it will be the same but rotated 90º and 45º and I assign to the button as a drawable.

<Button android:id="@+id/Details_Buttons_Top_Left_Button"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="@drawable/details_menu_large_button" />

I know that I can rotate it with a RotateDrawable or with a Matrix but as I already explained I don't like that approach.

Is it possible to achieve that directly on the XML or what do you think that will be the best way to do it? Put all resources but rotated, rotate them in the code?

--- EDIT --- The answer of @dmaxi works great, this is how to combine it with an item list :)

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_pressed="true">
        <rotate 
        android:fromDegrees="90"
        android:toDegrees="90"
        android:pivotX="50%"
        android:pivotY="50%"
        android:drawable="@drawable/and_card_details_button_up_onclick"/>
    </item>

    <item>
        <rotate
        android:fromDegrees="90"
        android:toDegrees="90"
        android:pivotX="50%"
        android:pivotY="50%"
        android:drawable="@drawable/and_card_details_button_up_onclick"/>
    </item>

</selector>
ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
Goofyahead
  • 5,874
  • 6
  • 29
  • 33
  • 4
    No need to apologize your english is just fine. And welcome to SO! – PeeHaa Jan 03 '12 at 19:40
  • look in to the same problem on this thread http://stackoverflow.com/questions/14727426/andriod-how-to-create-the-stack-kind-of-image-backgrounds any suggestion would be great! – sukarno Feb 07 '13 at 06:32
  • Vector based drawables greatly simplifies matters (answer below). – samus Aug 31 '18 at 18:53

4 Answers4

146

I could rotate in XML:

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android" 
        android:fromDegrees="90"
        android:toDegrees="90"
        android:pivotX="50%"
        android:pivotY="50%"
        android:drawable="@drawable/mainmenu_background">
</rotate>

The fromDegrees is important.

Basically this is a rotate animation defined in XML. With fromDegrees you define the initial rotated state. The toDegrees is the final rotated state of the drawable in the animation sequence but can be anything if you don't want to use animation.

I don't think it allocates resources for animation as it doesn't have to be loaded as animation. As a drawable it is rendered as it's initial state and should be put in the drawable resource folder. To use it as an animation you should put it in anim resource folder and can start the animation like this (just an example):

Animation rotation = AnimationUtils.loadAnimation(this, R.anim.rotation);
rotation.setRepeatCount(Animation.INFINITE);
myView.startAnimation(rotation);
Reinstate Monica
  • 2,767
  • 3
  • 31
  • 40
dmaxi
  • 3,267
  • 1
  • 18
  • 15
  • 1
    Thanks that's perfect! i combined that with the item and its exactly what i need, i want to post the code, i don't know if its better to edit your answer or my question... And for mirroring the image do i have to play with pivot x & y? – Goofyahead Jan 04 '12 at 09:48
  • Well, I'm happy I could help, edit the answer if you wish. pivotX and pivotY defines the center point of the rotation. For mirroring I don't have idea because this XML can only define 2D rotation. – dmaxi Jan 04 '12 at 18:32
  • 1
    @dmaxi This is rotating the drawable via a rotation animation isn't it? Wouldn't that be somewhat inefficient? – starkej2 Jun 23 '14 at 15:12
  • I made this but from 0 to 360 degrees because i want a full rotation, the problem is in small screens it rotates deformed, any clue? – firetrap Oct 07 '14 at 10:08
  • Why should "fromDegrees" be the same as "toDegrees" ? Why shouldn't it be 0? – android developer Feb 24 '15 at 12:26
  • I added explanatory text chaps, I hope it helps. – dmaxi Feb 24 '15 at 21:47
  • 1
    There was a bug in Android M affecting this exact rotate drawable, it disappears completely, so if you choose this sollution then it will be broken in M. Was fixed for N. – androidguy Jul 28 '17 at 22:04
  • @androidguy This should really be added to the answer. – reVerse Oct 30 '18 at 10:41
  • 1
    Unable to rotate svg drawable. Any idea? – masoomyf May 26 '19 at 13:10
  • This doesn't work with vector drawables – Konstantin Konopko May 29 '23 at 20:17
38

I could rotate left arrow right in XML as:

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="180"
    android:toDegrees="0"
    android:drawable="@drawable/left">
</rotate>

Attached image for reference.

enter image description here

Community
  • 1
  • 1
amko0l
  • 379
  • 3
  • 5
29

If vector based drawables are used, in conjunction with an ImageView, style, and color state list, your button can be refactored as follows:

Note: Vector drawables are significantly smaller than images, so extra, explicit definitions don't incur much overhead, and makes for clear, explicit code (although I've read that hand modifying vector assets should be avoided, I'd rather deal with the overhead of updating a couple of files than having transformations on one):

Note: Android Studio is a great source for vector assets.

res\values\styles.xml

<!--ImageView-->
<style name="Details_Buttons_Top_Left_Button">
  <item name="android:layout_width">match_parent</item>
  <item name="android:layout_height">match_parent</item>    
  <item name="android:tint">@color/button_csl</item>    
</style>

res\color\button_csl.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">  
  <item android:state_enabled="false" android:color="@color/grey_disabled"/>
  <item android:state_pressed="true" android:color="@color/orange_hilite"/>
  <item android:color="@color/black"/>  
</selector>

details_menu_large_button.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:state_pressed="true"
        android:drawable="@drawable/and_card_details_button_down_left_onclick" /> <!-- pressed -->
  <item android:drawable="@drawable/and_card_details_button_down_left" /> <!-- default -->
</selector>

Details_Buttons_Top_Left_Button

<ImageView android:id="@+id/Details_Buttons_Top_Left_Button"
           style="@style/Details_Buttons_Top_Left_Button"
           android:src="@drawable/details_menu_large_button" />

and_card_details_button_down_left.xml (ic_play_arrow_black_24dp.xml)

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">  
  <path
        android:fillColor="#FF000000"
        android:pathData="M8,5v14l11,-7z"/>

</vector>

and_card_details_button_down_left_onclick.xml (ic_play_arrow_black_24dp.xml modified)

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">
  <group android:name="rotationGroup"
         android:pivotX="12"
         android:pivotY="12"
         android:rotation="90" >
    <path
          android:fillColor="#FF000000"
          android:pathData="M8,5v14l11,-7z"/>
  </group>
</vector>
samus
  • 6,102
  • 6
  • 31
  • 69
6

If you want to rotation drawable in xml file then simple add android:rotation="180" in ImageView

<ImageView
    android:id="@+id/imageview"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_dropdown"
    android:rotation="180"/>

Programatically

val image = findViewById(R.id.imageview)
image.rotation = 180f
Dinesh
  • 1,410
  • 2
  • 16
  • 29