Czy można obrócić element rysunkowy w opisie XML?

102

Tworzę aplikację z zasobami, które można ponownie wykorzystać (ponieważ przyciski są zawsze takie same, ale lustrzane lub obrócone). Chcę użyć tego samego zasobu, więc nie muszę dodawać 3 dodatkowych zasobów, które są dokładnie takie same, jak oryginalne, ale są obracane. Ale nie chcę też mieszać kodu z rzeczami, które można zadeklarować w XML lub dokonywać transformacji za pomocą macierzy, która będzie kosztować czas przetwarzania.

Mam przycisk z dwoma stanami zadeklarowany w 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>

i chcę ponownie wykorzystać element do rysowania, ponieważ będzie taki sam, ale obrócony o 90º i 45º i przypisuję przycisk jako element do rysowania.

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

Wiem, że mogę to obrócić za pomocą a RotateDrawablelub a, Matrixale jak już wyjaśniłem, nie podoba mi się to podejście.

Czy można to osiągnąć bezpośrednio w XML lub jak myślisz, jaki będzie najlepszy sposób na zrobienie tego? Umieścić wszystkie zasoby oprócz rotacji, obrócić je w kodzie?

--- EDYTUJ --- Odpowiedź @dmaxi działa świetnie, tak można ją połączyć z listą pozycji :)

<?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
źródło
4
Nie musisz przepraszać swojego angielskiego, jest w porządku. Witamy w SO!
PeeHaa,
spójrz na ten sam problem w tym wątku stackoverflow.com/questions/14727426/ ... każda sugestia byłaby świetna!
sukarno,
Rysunki oparte na wektorach znacznie upraszczają sprawę (odpowiedź poniżej).
samis

Odpowiedzi:

136

Mógłbym obracać w 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>

To fromDegreesjest ważne.

Zasadniczo jest to animacja obracania zdefiniowana w XML. Wraz z fromDegreesokreśleniem początkowego stanu obróconego. Jest toDegreesto ostatni obrócony stan elementu do rysowania w sekwencji animacji, ale może to być wszystko, jeśli nie chcesz używać animacji.

Nie sądzę, aby przydzielał zasoby do animacji, ponieważ nie musi być ładowany jako animacja. Jako plik do rysowania jest renderowany w stanie początkowym i powinien zostać umieszczony w drawablefolderze zasobów. Aby użyć go jako animacji, należy umieścić go w animfolderze zasobów i rozpocząć animację w ten sposób (tylko przykład):

Animation rotation = AnimationUtils.loadAnimation(this, R.anim.rotation);
rotation.setRepeatCount(Animation.INFINITE);
myView.startAnimation(rotation);
dmaxi
źródło
1
Dzięki, świetnie! połączyłem to z przedmiotem i dokładnie tym, czego potrzebuję, chcę opublikować kod, nie wiem, czy lepiej będzie edytować twoją odpowiedź lub moje pytanie ... A żeby wykonać kopię lustrzaną obrazu, muszę bawić się pivotem x & y?
Goofyahead
Cóż, cieszę się, że mogłem pomóc, edytuj odpowiedź, jeśli chcesz. pivotX i pivotY definiuje środek obrotu. Nie mam pomysłu na tworzenie kopii lustrzanych, ponieważ ten XML może definiować tylko obrót 2D.
dmaxi
1
@dmaxi To jest obracanie rysunku poprzez animację obrotu, prawda? Czy nie byłoby to trochę nieefektywne?
starkej2
Zrobiłem to ale od 0 do 360 stopni bo chcę pełnego obrotu, problem w małych ekranach obraca się zdeformowany, jakaś wskazówka?
firetrap
1
Wystąpił błąd w Androidzie M wpływający na to dokładne obracanie do rysowania, znika on całkowicie, więc jeśli wybierzesz to rozwiązanie, zostanie uszkodzony w M. Został naprawiony dla N.
androidguy
35

Mogę obrócić strzałkę w lewo w prawo w XML jako:

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

Załączony obraz w celach informacyjnych.

wprowadź opis obrazu tutaj

amko0l
źródło
robię to, ale nie mogę ustawić tła do układu żadnego pomysłu?
Mateen Chaudhry,
18

Jeśli używane są rysunki oparte na wektorach, w połączeniu z ImageView , listą stylów i stanów kolorów, przycisk można refaktoryzować w następujący sposób:

Uwaga: rysunki wektorowe są znacznie mniejsze niż obrazy, więc dodatkowe, wyraźne definicje nie powodują dużego narzutu i stanowią jasny, wyraźny kod (chociaż czytałem, że należy unikać ręcznego modyfikowania zasobów wektorowych, wolałbym zajmować się obciążenie związane z aktualizacją kilku plików niż posiadanie transformacji w jednym):

Uwaga: Android Studio to świetne źródło zasobów wektorowych.

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 (zmodyfikowano 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">
  <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 jest
źródło
3
rotationGroup
Dobra
0

Jeśli chcesz rotationrozciągliwej w xmlpliku wtedy prosty dodatek android:rotation="180"wImageView

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_dropdown"
    android:rotation="180"/>
Dinesh
źródło