强制重新布局视图组,包括其所有子项

时间:2014-09-24 20:57:13

标签: android android-layout android-view

我正在编写一个可以放大的自定义布局(扩展FrameLayout)。它的所有子节点也都是自定义视图,它实际上通过getter方法从父节点获取比例因子并相应地缩放设置缩放尺寸,如

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

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

我正在使用ScaleGestureDetector来检测“缩放缩放”手势并更改布局的scaleFactor。然后我通过调用requestLayout强制在自定义布局上布局。不幸的是,这似乎对其孩子没有任何影响。孩子的onMeasure& onLayout永远不会被调用,即使父母通过其措施&布局周期。但是,如果我直接在其中一个孩子上调用requestLayout,那么只要该孩子根据父母中设置的比例因子进行缩放!

似乎除非在视图上专门调用requestLayout,否则它实际上不会再次测量自身,而是使用某种缓存。从视图的源代码中可以看出这一点

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

如何强迫孩子在父母的requestLayout上再次测量自己?

1 个答案:

答案 0 :(得分:4)

这将强制重新播放视图的孩子(假设视图的宽度和高度不需要更改)

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