26

在一个片段中,我正在使用多个子视图膨胀一个布局。我需要获取其中一个自定义视图的尺寸(宽度和高度)。

在自定义视图类中,我可以轻松完成。但是,如果我尝试从片段中做到这一点,我总是会得到 0 作为维度。

 public void onViewCreated(View view, Bundle savedInstanceState) {

    super.onViewCreated(view, savedInstanceState);
    View culoide = view.findViewWithTag(DRAW_AREA_TAG);
    Log.d("event", "culoide is: "+culoide.getWidth()); // always 0
}

我认为 onViewCreated 应该是获取它的正确位置,但是这确实发生了。我在 super.onViewCreated 之前尝试过,在调试中它看起来像 'findViewWithTag' 找到了正确的视图,仅使用 api 7 v4 支持进行了尝试。

有什么帮助吗?

4

7 回答 7

45

您必须等到第一次测量和布局之后才能获得getWidth()和的非零值getHeight()。你可以这样做ViewTreeObserver.OnGlobalLayouListener

public void onViewCreated(final View view, Bundle saved) {
    super.onViewCreated(view, saved);
    view.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
        public void onGlobalLayout() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
              view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            } else {
              view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            }

            // get width and height of the view
        }
    });
}
于 2013-06-04T19:03:16.843 回答
6

我的首选方法是向OnLayoutChangeListener要跟踪自身的视图添加一个

CustomView customView = ...

customView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
    @Override
    public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
        // Make changes
    }
});

如果您只想要初始布局,则可以在回调中删除侦听器。

于 2014-01-02T09:33:56.440 回答
3

使用ViewTreeObserver.OnGlobalLayoutListener, View.post(Runnable action)oronWindowFocusChanged()不是最好的解决方案。这篇文章(注:我是这篇文章的作者)解释了原因并提供了一个使用doOnLayoutkotlin 扩展的工作解决方案,它基于View.OnLayoutChangeListener. 如果你想在 Java 中使用它,在文章中有一个指向doOnLayout源代码的链接,它非常简单,你也可以在 Java 中做类似的事情。

于 2019-08-14T15:17:20.447 回答
2

您必须等到调用onSizeChanged()方法才能可靠地确定视图大小。

当此视图的大小发生更改时,这会在布局期间调用。如果您刚刚被添加到视图层次结构中,则会使用旧值 0 调用您。

于 2013-08-16T11:27:02.167 回答
1

试着打电话

culoide.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);

getWidth()首先,然后尝试getHeight()

于 2013-06-04T19:01:00.427 回答
0

尝试签入 onWindowFocusChanged 并且它应该具有有效值:

public void onWindowFocusChanged (boolean hasFocus) { }

我有一个类似的问题,我需要获取小部件的宽度和高度,这是我可以保证小部件报告它的大小正确的功能。

于 2013-06-04T18:54:39.720 回答
0

这是一个真正的痛苦,特别是因为您希望在片段生命周期中使用像 onViewCreated 这样的名称来表示视图已准备就绪。对我来说,像这样获得片段视图本身:

 override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)   
     getView()?.let{
                  it.doOnLayout{// do your UI work here }
                   }
    }

这确保片段 getView 实际上已经有一个布局传递。

于 2020-09-23T09:51:42.767 回答