2011-11-11 8 views
12

Mam niestandardowy widok, w którym używam transformacji. Do tej pory tak dobrze, funkcja jak setRotationY(), setScaleX(), setTranslationY() lub nawet getMatrix() działa zgodnie z oczekiwaniami, jestem w stanie manipulować mój widok i wyświetla się dobrze. Tam, gdzie uderzyłem w ścianę, wiele funkcji zachowuje się dziwnie po tym. Na przykład funkcja taka jak getHitRect() zwraca całkowicie dziwne wartości! To nie pomaga moim wydarzeniom dotykowym.Jak uzyskać prawidłowe granice widoku po transformacji Macierz

Próbowałem przeładować funkcję, ale nadal nie działa, szczególnie przy użyciu obracania lub skalowania (Tłumaczenie działa poprawnie). Myślę, że to ma coś wspólnego z tym, że matryca jest wyrażana w podrzędnej współrzędnej, więc w jaki sposób mogę ją uzyskać we współrzędnej rodziców?

@Override 
    public void getHitRect(Rect outRect){ 

     RectF rect = new RectF(); 
     rect.top = (float) this.getTop(); 
     rect.bottom = (float) this.getBottom(); 
     rect.left = (float) this.getLeft(); 
     rect.right = (float) this.getRight();  

    this.getMatrix().mapRect(rect); 
     rect.round(outRect); 
    } 

Czy mogę uzyskać prostszą wartość bezpośrednio z jakiejś funkcji? Podobnie jak nowa wysokość, szerokość, góra lub dół.

Odpowiedz

8

Kiedy przesłanianie „getChildStaticTransformation” sposobu ViewGroup lub nawet przy użyciu funkcji transformacji jak setRotationY(), setScaleX(), setTranslationY(), getMatrix() (dostępny od 11 API), które mają wpływ tylko Matrix renderowania. W wyniku tego Twój niestandardowy widok podrzędny zwróci Bounds "Rects" z dala od miejsca, w którym dziecko otrzymuje remis. To nie jest problem przez większość czasu, ale kiedy zaczynasz być chętny do kliknięcia ... kłopoty się zaczynają ... Oto jak rozwiązuję problem. Jestem pewna, że ​​mogą być lepsze sposoby, ale ponieważ nie znalazłem wielu rzeczy na ten temat, oto jest.

W ViewGroup przeciążeniem:

public interface Itransformable { 
    public void setTransformationMatrix(Matrix trsMatrix); 
} 

@Override 
protected boolean getChildStaticTransformation(View child, Transformation t) { 
    if (child instanceof Itransformable){ 
     t.clear(); 
     t.setTransformationType(Transformation.TYPE_MATRIX); 
     ... 
     // Do whatever transformation you want here 
     ... 
     ((Itransformable)child).setTransformationMatrix(t.getMatrix()); 
     return true; 
    } else { 
     return false; 
    } 
} 

Oto Dziecko Widok niestandardowy: Należy pamiętać, że nie jestem przechowywania bezpośrednio macierz transformacji w widoku niestandardowym ale zamiast przekształcony Rect. Jeśli chcesz przejść do przechowywania macierzy (np. Do późniejszej transformacji, takiej jak punkt ...), możesz potrzebować sklonować ją, ponieważ matryca zmieni się w jakiś dziwny sposób, tak jak jest to recykling lub coś podobnego.

public class MyCustomView extends View implements MyViewGroup.Itransformable{ 

private Rect mViewRect = null; 

public void setTransformationMatrix(Matrix trsMatrix){ 
    if (trsMatrix!=null){ 
     RectF rect = new RectF(); 
     rect.top = 0; 
     rect.bottom = (float) this.getHeight(); 
     rect.left = 0; 
     rect.right = (float) this.getWidth(); 

     trsMatrix.mapRect(rect); 
     rect.offset((float) this.getLeft(), (float) this.getTop()); 

     if (mViewRect == null) mViewRect = new Rect(); 
     rect.round(mViewRect); 
    } 
} 

public Rect getTransformatedRect() { 
    if (mViewRect!=null){ 
     // OutOfScreen WorkArround - As the view is not Displayed, mViewRect doesn't get updated. 
     if(getRight() < 0 || getLeft() > mParentWidth){ 
      return new Rect(getLeft(),getTop(),getRight(),getBottom()); 
     } else { 
      return mViewRect; 
     } 
    } else { 
     return new Rect(getLeft(),getTop(),getRight(),getBottom()); 
    } 
} 

@Override 
public void getHitRect(Rect outRect){ 

    if (mViewRect == null){ 
     super.getHitRect(outRect); 
    } else { 
     outRect.set(getTransformatedRect()); 
    } 
} 
+0

Bardzo dziękuję za odpowiedź, to mi pomaga :) –

+0

Inną rzeczą dla systemu Android> = 4.0: 'getHitRect()' nie zostanie wywołana automatycznie, jeśli jesteś na widoku kliknięcie. Aby dodać kompatybilność dla projektów używających SDK <4.0, użycie 'isTransformedTouchPointInView()' na rodzica działa, nawet jeśli nie jest idealne. –

Powiązane problemy