2011-11-11 4 views
12

J'ai une vue personnalisée où j'utilise des transformations. Jusqu'à présent, si bon, fonctionner comme setRotationY(), setScaleX(), setTranslationY() ou même getMatrix() travail comme prévu, je peux manipuler mon point de vue et il affiche bien. Où je frappe le mur, c'est qu'un certain nombre de fonctions se comportent étrangement après cela. Par exemple, la fonction getHitRect() renvoie des valeurs totalement étranges! Cela n'aide pas mes événements tactiles.Comment obtenir les limites appropriées d'une vue après transformation Matrice

J'ai essayé de surcharger la fonction mais il est encore loin de travailler en particulier lors de l'utilisation de rotation ou mise à l'échelle (traduction fonctionne très bien à travers). Je pense que cela a quelque chose à voir avec le fait que la matrice est exprimée en coordonnées enfant, alors comment puis-je l'obtenir dans la coordination des parents? Puis-je obtenir une valeur plus directe directement à partir de certaines fonctions? Comme la nouvelle hauteur, largeur, haut ou bas.

Répondre

8

Lors de la substitution de la méthode « getChildStaticTransformation » du ViewGroup ou même en utilisant la fonction de transformation comme setRotationY(), setScaleX(), setTranslationY(), getMatrix() (disponible à partir de l'API 11) vous affecte seulement la matrice de rendu. Par conséquent, votre vue enfant personnalisée renverra des "rects" éloignés loin de l'endroit où votre enfant obtient le tirage. Ce n'est pas un problème la plupart du temps, mais quand vous commencez à vouloir cliquer dessus, les problèmes commencent ... Voici comment je contourne le problème. Je suis sûr qu'il pourrait y avoir de meilleurs moyens, mais comme je n'ai pas trouvé beaucoup de choses sur le sujet, ça l'est.

Dans la ViewGroup surcharge:

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; 
    } 
} 

Voici l'enfant personnalisé Vue: Notez que je ne suis pas stocker directement la matrice de transformation dans la vue personnalisée, mais plutôt le Rect transformé. Si vous voulez aller pour stocker la matrice (c'est-à-dire pour une transformation ultérieure comme le point ...), vous devrez peut-être la cloner car la matrice se modifiera d'une manière étrange comme si elle était recyclée ou quelque chose.

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

Merci beaucoup pour votre réponse, il me aide :) –

+0

Une autre chose pour Android> = 4.0: 'getHitRect()' ne sera pas appelée automatiquement si vous cliquez sur votre point de vue. Pour ajouter de la compatibilité pour les projets utilisant SDK <4.0, l'utilisation de 'isTransformedTouchPointInView()' sur le parent fonctionne même si ce n'est pas parfait. –

Questions connexes