21

我正在处理一个片段,我想获得layout包含在xml fragment layout. 当我尝试代码时

RelativeLayout myLayout = view.findViewById(R.id.myLayout);
myLayout.getHeight();

它返回 0。我需要将这些尺寸放入 myLayout 其他对象中。

我尝试使用:

myLayout.getViewTreeObserver().addOnGlobalLayoutListener( 
    new ViewTreeObserver.OnGlobalLayoutListener(){

        @Override
        public void onGlobalLayout() {
            mHeight = myLayout.getHeight();  
            mWidth= myLayout.getWidth();
            System.out.println("width: "+mWidth+"   height: "+mHeight);
         }
});

但是这段代码被调用了很多时间,我不知道它是什么时候执行的。我需要将这些维度纳入 public void onActivityCreated ()方法。可能吗?

4

3 回答 3

36

有一个更干净的解决方案,只需View.post()在片段的根视图上使用该方法,您就可以调用getMeasuredHeight()/getMeasuredWidth()并获取实际值。

例如

public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View root = inflater.inflate(R.layout.myfragment, container, false);

    root.post(new Runnable() {
        @Override
        public void run() {
            // for instance
            int height = root.getMeasuredHeight(); 
        }
    });

    return root;
}

非常整洁,没有乱七八糟的东西ViewTreeObserver

我只用 android-23 设备对此进行了测试,但 API 从级别 1 开始就有这种方法。

无论如何,WFM。

于 2016-02-25T19:16:47.097 回答
11

每当视图发生小的变化时,都会调用 addOnGlobalLayoutListener。所以你需要从视图中移除这个监听器。

简单用法:

public static void removeOnGlobalLayoutListener(View v, ViewTreeObserver.OnGlobalLayoutListener listener){
if (Build.VERSION.SDK_INT < 16) {
    v.getViewTreeObserver().removeGlobalOnLayoutListener(listener);
} else {
    v.getViewTreeObserver().removeOnGlobalLayoutListener(listener);
}

}

我建议你检查:

if (myLayout.getHeight()>0 && myLayout.getWidth()>0) {
// Do some code...
removeOnGlobalLayoutListener(..)
}
于 2014-02-09T08:04:05.337 回答
2

onActivityCreated中,视图尚未测量。

所以不,你不能从那里得到测量结果。onGlobalLayout是个好地方。布局在测量后直接发生。

如果您只想执行一次,您可以在之后移除您的侦听器。请注意,布局可以改变大小(例如,出现软键盘)

于 2013-06-05T11:14:45.763 回答