2013-01-19 15 views
12

Dowiedziałem się, że setPivotX (także setPivotY) działa dziwnie w systemie Android. Jeśli ustawisz przestawny, gdy skala widoku jest ustawiona na 1.00f nic się nie dzieje (tylko zmiany przestawne). Jeśli jednak skala nie jest równa 1,0f (np. setScaleX(0.9f)), a widok przestawny, widok przesuwa się względnie (?) Do nowego obrotu. Czy to nie dziwne? Wiem, że pozycje poziome i pionowe (tłumaczenia) NIE są powiązane z wartością przestawną, ale dlaczego widok przesuwa się ze współczynnikiem skali innym niż 1.0f?setPivotX działa dziwnie na skalowanym widoku

Proszę to sprawdzić z częścią skalującą i bez niej.

public class ScaleView extends View { 

private final ScaleGestureDetector mScaleGestureDetector; 

public ScaleView(Context context, AttributeSet attrs) { 
    super(context, attrs); 


    //setScaleX(0.9f); 
    //setScaleY(0.9f); 

    mScaleGestureDetector = new ScaleGestureDetector(context, new ScaleGestureDetector.OnScaleGestureListener() { 

     @Override 
     public void onScaleEnd(ScaleGestureDetector detector) { 
      // does nothing intentionally 
     } 

     @Override 
     public boolean onScaleBegin(ScaleGestureDetector detector) { 
      setPivotX(detector.getFocusX()); 
      setPivotY(detector.getFocusY()); 
      return true; 
     } 

     @Override 
     public boolean onScale(ScaleGestureDetector detector) { 
      return false; 
     } 
    }); 
} 

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    mScaleGestureDetector.onTouchEvent(event); 
    return super.onTouchEvent(event); 
} 
} 

Jak ustawić tę samą pozycję widoku, która była przed zmianą osi obrotu?

Odpowiedz

8

Rozwiązałem problem. Oto kod roboczych:

@Override 
public boolean onScaleBegin(ScaleGestureDetector detector) { 
    float newX = detector.getFocusX(); 
    float newY = detector.getFocusY(); 
    setTranslationX(getTranslationX() + (getPivotX() - newX) * (1 - getScaleX())); 
    setTranslationY(getTranslationY() + (getPivotY() - newY) * (1 - getScaleY())); 
    setPivotX(newX); 
    setPivotY(newY); 
    return true; 
} 

Głównym problemem jest to, aby zrozumieć, jak działa obrotu na przeskalowane poglądów, wówczas nie powinno być żadnych problemów z dziwnego zachowania obrotu.

+5

Wydaje mi się, że to błąd w Androidzie. Skalowanie punktu obrotu odbywa się poprzez przekształcenie na oś obrotu, wykonanie skali i tłumaczenie z powrotem. Operacje 'setScale' powinny to robić, a widok nie powinien się przeskakiwać. Skalowanie to operacja, która nie powinna w widoczny sposób tłumaczyć widoków. –

+0

Witam, natknąłem się na ten sam problem i udało mi się to naprawić z twoją odpowiedzią. Nadal jednak zastanawiam się, jak działa narzędzie Pivot na skalowanych widokach. Czy możesz podać jakieś wskazówki, a może link? Z góry dzięki. – aleien

+0

@aleien przepraszam Nie mogę ci pomóc, nie sądzę, że istnieje jakakolwiek wskazówka dotycząca skalowania widoków za pomocą punktów przestawnych. – tomrozb

0

@aleien, mogę odpowiedzieć na twoje pytanie. Podczas ustawiania nowego przestawu właściwości widoku zostaną ponownie obliczone. Android przeskalowuje oryginalny widok z nową osią obrotu, ale ta sama wartość skali, która prowadzi do nowego skalowanego widoku, ma przesunięcie między starym skalowanym widokiem. Przesunięcie to tylko (getPivotX() - newX) * (1 - getScaleX()), aby przeciwdziałać temu przesunięciu, możemy użyć setTranslationX(). Mam nadzieję, że moja odpowiedź może ci pomóc!

+0

dzięki za montaż, @ Mario Nikolaus – Ryan