Est-il possible de faire pivoter un dessinable dans la description xml?

102

Je crée une application, avec des ressources qui peuvent être réutilisées (car les boutons sont toujours les mêmes, mais en miroir ou en rotation). Je souhaite utiliser la même ressource afin de ne pas avoir à ajouter 3 autres ressources qui sont exactement comme l'original mais pivotées. Mais je ne veux pas non plus mélanger le code avec des choses qui peuvent être déclarées dans le XML ou faire des transformations avec une matrice qui coûtera du temps de traitement.

J'ai un bouton à deux états déclaré dans un 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>

et je veux réutiliser le dessinable car il sera le même mais tourné de 90 ° et 45 ° et j'assigne le bouton comme dessinable.

<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" />

Je sais que je peux le faire pivoter avec un RotateDrawableou avec un Matrixmais comme je l'ai déjà expliqué, je n'aime pas cette approche.

Est-il possible d'y parvenir directement sur le XML ou quelle sera selon vous la meilleure façon de le faire? Mettre toutes les ressources mais en rotation, les faire pivoter dans le code?

--- EDIT --- La réponse de @dmaxi fonctionne très bien, voici comment la combiner avec une liste d'articles :)

<?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>
Goofyahead
la source
4
Pas besoin de vous excuser, votre anglais est très bien. Et bienvenue à SO!
PeeHaa
Regardez le même problème sur ce thread stackoverflow.com/questions/14727426/… toute suggestion serait géniale!
sukarno
Les dessins vectoriels simplifient considérablement les choses (réponse ci-dessous).
samis

Réponses:

136

Je pourrais tourner en 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>

Le fromDegreesest important.

Il s'agit essentiellement d'une animation de rotation définie en XML. Avec fromDegreesvous définissez l'état de rotation initial. Le toDegreesest l'état de rotation final du dessinable dans la séquence d'animation, mais peut être n'importe quoi si vous ne souhaitez pas utiliser d'animation.

Je ne pense pas qu'il alloue des ressources pour l'animation car il ne doit pas être chargé en tant qu'animation. En tant que dessinable, il est rendu dans son état initial et doit être placé dans le drawabledossier de ressources. Pour l'utiliser comme animation, vous devez le mettre dans le animdossier de ressources et pouvez démarrer l'animation comme ceci (juste un exemple):

Animation rotation = AnimationUtils.loadAnimation(this, R.anim.rotation);
rotation.setRepeatCount(Animation.INFINITE);
myView.startAnimation(rotation);
dmaxi
la source
1
Merci c'est parfait! J'ai combiné cela avec l'article et c'est exactement ce dont j'ai besoin, je veux publier le code, je ne sais pas s'il vaut mieux modifier votre réponse ou ma question ... Et pour refléter l'image, dois-je jouer avec le pivot x & y?
Goofyahead
Eh bien, je suis heureux de pouvoir vous aider, modifier la réponse si vous le souhaitez. pivotX et pivotY définissent le point central de la rotation. Pour la mise en miroir, je n'ai aucune idée car ce XML ne peut définir que la rotation 2D.
dmaxi le
1
@dmaxi Ceci fait tourner le dessinable via une animation de rotation n'est-ce pas? Ne serait-ce pas quelque peu inefficace?
starkej2
J'ai fait ça mais de 0 à 360 degrés car je veux une rotation complète, le problème c'est dans les petits écrans qu'il tourne déformé, un indice?
firetrap
1
Il y avait un bogue dans Android M affectant cette rotation exacte tirable, il disparaît complètement, donc si vous choisissez cette solution, il sera cassé dans M. A été corrigé pour N.
androidguy
35

Je pourrais faire pivoter la flèche gauche vers la droite dans XML comme:

<?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>

Image jointe pour référence.

entrez la description de l'image ici

amko0l
la source
Je fais cela mais je ne peux pas définir l'arrière-plan pour mettre en page une idée?
Mateen Chaudhry
18

Si des dessins vectoriels sont utilisés, en conjonction avec une liste ImageView , style et état de couleur, votre bouton peut être refactoré comme suit:

Remarque: les dessins vectoriels sont nettement plus petits que les images, donc les définitions supplémentaires et explicites n'entraînent pas beaucoup de frais généraux et permettent un code clair et explicite (même si j'ai lu que la modification manuelle des actifs vectoriels devrait être évitée, je préfère traiter avec la surcharge de mettre à jour quelques fichiers que d'avoir des transformations sur un):

Remarque: Android Studio est une excellente source d'actifs vectoriels.

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 modifié)

<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>
Sam est
la source
3
Belle réponse pour l' rotationGroupattribut, il fait très bien tourner le vecteur
blueware
0

Si vous voulez rotationétirables dans le xmlfichier , puis ajouter simplement android:rotation="180"dansImageView

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_dropdown"
    android:rotation="180"/>
Dinesh
la source