I am writing a custom layout (which extends FrameLayout ) that can be scaled up. All of his children are also regular representations, which actually get a scale factor from their parent using the getter method and scale accordingly, setting scaled sizes such as
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); float scaleFactor = ((CustomLayout) getParent()).getCurrentScale(); setMeasuredDimension((int) (getMeasuredWidth() * scaleFactor), (int) (getMeasuredHeight() * scaleFactor)); }
I use ScaleGestureDetector to detect pinch to zoom gestures and scaleFactor layout changes. Then I format the layout on the custom layout by calling requestLayout . Unfortunately, this does not affect children. The onMeasure and onLayout never called, even if the parent goes through a dimension and layout cycle. But, if I directly call requestLayout on one of the children, only this child gets the scaling in accordance with the scaling factor set in the parent !!
It seems that if requestLayout not only called only in the view, it no longer measures itself and uses some kind of cache instead. This can be seen from the source code for the view, which says
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; }
How to make children also measure themselves again when calling requestLayout on their parent?
source share