在一个碎片中获取Android布局的高度和宽度

22

我正在处理一个碎片(fragment)并且我想得到包含在 XML 碎片布局中的 layout 的尺寸。当我尝试以下代码时:

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

它返回0。 我需要这些尺寸来放置其他对象到我的布局中。

我尝试使用:

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 () 方法中。这可能吗?

我需要把这些维度放到 public void onActivityCreated () 方法中。这可能吗?

我的布局是什么?请提及代码。 - Sam
这是在XML中声明的相对布局的引用。 - lory105
发布我的布局XML文件。 - Sam
你找到解决方案了吗? - M. Reza Nasirloo
3个回答

38

有一个更简洁的解决方案,只需在您的片段的根视图上使用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 从 level 1 就有了这个方法。

无论如何,WFM。


如果您需要从片段类而不是活动中测量,请使用onViewCreated。 - Fernando Gallego
1
@FernandoGallego 不,在 onViewCreated 中宽度和高度返回0。 - Minas Mina
这是记录在案的行为吗? - funct7
@funct7 是什么文档?getMeasuredHeight() 在可见或View.post之前不可用? - Staffan

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

2
onActivityCreated中,视图尚未被测量。
因此,您无法从那里获取测量值。 onGlobalLayout是一个很好的地方来做这件事。布局发生在测量之后。
如果您只想执行一次,则可以在此之后删除侦听器。请注意,布局的大小可能会更改(例如,软键盘出现)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接