2014-09-24 3 views
5

Ich schreibe ein benutzerdefiniertes Layout (das FrameLayout erweitert), die vergrößert werden kann. Alle seine Kinder sind auch benutzerdefinierte Ansichten, die tatsächlich den Skalierungsfaktor von ihrem Eltern via erhalten würde eine Getter-Methode und skaliert entsprechend durch die skalierten Dimensionen wieForce-Re-Layout auf einer Viewgroup einschließlich aller seiner Kinder

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 

    float scaleFactor = ((CustomLayout) getParent()).getCurrentScale(); 
    setMeasuredDimension((int) (getMeasuredWidth() * scaleFactor), (int) (getMeasuredHeight() * scaleFactor)); 
} 

Einstellung ich ScaleGestureDetector bin mit dem „pinch to zoom“ Geste zu erkennen und der Skalierungsfaktor Layout ändern. Dann erzwinge ich ein Layout auf dem benutzerdefinierten Layout durch den Aufruf requestLayout. Leider scheint dies keine Auswirkungen auf seine Kinder zu haben. Die onMeasure & onLayout der Kinder werden nie aufgerufen, auch wenn das Elternelement seinen Takt & Layout-Zyklus durchläuft. Aber, wenn ich requestLayout auf einem der Kinder direkt anrufe, wird gerade dieses Kind entsprechend dem Skalierungsfaktor skaliert, der im Elternteil eingestellt wird !!

Es scheint, dass, es sei denn requestLayout wird ausschließlich auf eine Ansicht aufgerufen, es misst sich nicht wieder selbst und verwendet stattdessen eine Art von Cache. Dies ergibt sich aus dem Quellcode für Ansicht, die sagt

if (mAttachInfo != null && mAttachInfo.mViewRequestingLayout == null) { 
     // Only trigger request-during-layout logic if this is the view requesting it, 
     // not the views in its parent hierarchy 
     ViewRootImpl viewRoot = getViewRootImpl(); 
     if (viewRoot != null && viewRoot.isInLayout()) { 
      if (!viewRoot.requestLayoutDuringLayout(this)) { 
       return; 
      } 
     } 
     mAttachInfo.mViewRequestingLayout = this; 
    } 

Wie kann ich die Kinder auch dazu zwingen, sich auf requestLayout auf ihre Eltern rufen erneut messen zu gehen?

Antwort

4

Dies wird Neu-Layout der Kinder Ansicht erzwingen (vorausgesetzt, dass eigene Breite Ansicht und Höhe muss nicht geändert werden)

private static void relayoutChildren(View view) { 
    view.measure(
     View.MeasureSpec.makeMeasureSpec(view.getMeasuredWidth(), View.MeasureSpec.EXACTLY), 
     View.MeasureSpec.makeMeasureSpec(view.getMeasuredHeight(), View.MeasureSpec.EXACTLY)); 
    view.layout(view.getLeft(), view.getTop(), view.getRight(), view.getBottom()); 
}