Android: 通过 ViewTreeObserver 设置视图高度

Android: set view height via ViewTreeObserver

我有两个表:TableA 和 TableB。 TableA 的第一行高度为 22,TableB 的第一行高度为 77。我想将 TableA 的第一行等同于 TableB 的第一行,为此我使用以下代码:

void resizeHeaderHeight() {
    final int[] heightA = new int[1];
    final int[] heightB = new int[1];

    TableRow TableA_Row = (TableRow) this.tableA.getChildAt(0);
    TableRow TableB_Row = (TableRow) this.tableB.getChildAt(0);

    final TextView textViewA = (TextView) TableA_Row.getChildAt(0);
    final TextView textViewB = (TextView) TableB_Row.getChildAt(0);


    ViewTreeObserver vto = textViewB.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            textViewA.getViewTreeObserver();
            textViewB.getViewTreeObserver();
            heightA[0] = textViewA.getMeasuredHeight();
            heightB[0] = textViewB.getMeasuredHeight();
            Log.d(TAG, "TableA_Row height = " + heightA[0]);
            Log.d(TAG, "TableB_Row height = " + heightB[0]);

            textViewA.setHeight(heightB[0]);
        }
    });
}

但我怀疑这是否是正确的方法?

因为当我查看 logcat 时,它总是打印我的日志,但如果我删除 textViewA.setHeight(heightB[0]); 它只打印一次日志。

假设您的布局设计正确并且这种设置高度的方式 textViewB 是您真正想要的...

您应该在不再需要时立即删除 OnGlobalLayoutListener。您没有这样做,onGlobalLayout 回调会在 ViewTree 布局发生任何变化时被调用。所以回答你的问题:你使用 ViewTreeObserver 的方式不是最好的...

这样比较好:

void resizeHeaderHeight() {
    TableRow TableA_Row = (TableRow) this.tableA.getChildAt(0);
    TableRow TableB_Row = (TableRow) this.tableB.getChildAt(0);

    final TextView textViewA = (TextView) TableA_Row.getChildAt(0);
    final TextView textViewB = (TextView) TableB_Row.getChildAt(0);

    textViewB.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            int heightB = textViewB.getHeight();
            if (heightB > 0) {
                // removing OnGlobalLayoutListener
                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
                    textViewB.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                } else {
                    textViewB.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                }

                // setting height
                textViewA.setHeight(heightB);
            }
        }
    });
}