【问题标题】:get layout height and width at run time android在运行时获取布局高度和宽度android
【发布时间】:2012-08-17 15:07:07
【问题描述】:

如何获取在 xml 中定义为高度和宽度的 fill_parent 的线性布局的宽度和高度?我已经尝试过 onmeasure 方法,但我不知道为什么它没有给出确切的值。在 oncreate 方法完成之前,我需要在 Activity 中使用这些值。

【问题讨论】:

  • IIRC 在测量之前您无法获得任何东西的高度/宽度。它在 onSizeChanged 被调用时被分配,如果你覆盖 onLayout 所有视图都应该有一个高度和宽度
  • @tom502 你能给我一个链接或一段代码吗?这将非常有帮助。

标签: android-layout


【解决方案1】:

假设我必须获得在 XML 中定义的 LinearLayout 宽度。我必须通过 XML 获得它的参考。将LinearLayout l 定义为实例。

 l = (LinearLayout)findviewbyid(R.id.l1);
ViewTreeObserver observer = l.getViewTreeObserver();
        observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

            @Override
            public void onGlobalLayout() {
                // TODO Auto-generated method stub
                init();
            l.getViewTreeObserver().removeGlobalOnLayoutListener(
                    this);
        }
    });

protected void init() {
        int a= l.getHeight();
            int b = l.getWidth();
Toast.makeText(getActivity,""+a+" "+b,3000).show();
    } 
    callfragment();
}  

【讨论】:

  • 注意!它不会在 onCreate 完成之前为您提供值。虽然我在 onCreate 方法中调用了它,但它的覆盖方法将被延迟调用。所以看起来你的应用程序运行缓慢,但它解决了我的目的。
【解决方案2】:

宽度和高度值是在布局创建后设置的,当元素被放置后,它们就会被测量。在第一次调用 onSizeChanged 时,参数将为 0,因此如果您使用该检查来检查它。

这里有更多细节 https://groups.google.com/forum/?fromgroups=#!topic/android-developers/nNEp6xBnPiw

这里是http://developer.android.com/reference/android/view/View.html#Layout

onLayout的使用方法如下:

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    int width = someView.getWidth();
    int height = someView.getHeight();
}

【讨论】:

    【解决方案3】:

    要让它工作,您需要检查所需的高度值是否大于 0 - 然后首先删除 onGlobalLayout 侦听器,然后对高度执行任何您想要的操作。侦听器连续调用其方法,并且在第一次调用时不能保证正确测量视图。

        final LinearLayout parent = (LinearLayout) findViewById(R.id.parentView);
        parent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                int availableHeight = parent.getMeasuredHeight();
                if(availableHeight>0) {
                    parent.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                    //save height here and do whatever you want with it
                }
            }
        });
    

    【讨论】:

    • 这成功了 - 谢谢。从 API 级别 16 开始不推荐删除侦听器调用。这篇文章描述了如何支持对早期和后期 API 的调用stackoverflow.com/a/23741481/2162226
    【解决方案4】:

    您可以在布局中添加布局更改侦听器并获取最新的高度和宽度,甚至是上次更改之前的高度和宽度。

    在 API 级别 11 中添加

    添加一个监听器,当视图的边界改变时会被调用 由于布局处理。

    LinearLayout myLinearLayout = (LinearLayout) findViewById(R.id.my_linear_layout);
    myLinearLayout.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) {
                // Preventing extra work because method will be called many times.
                if(height == (bottom - top))
                    return;
                
                height = (bottom - top);
                // do something here...
               }
         });
    

    【讨论】:

    • 由于某种原因,在方向更改后不会调用它
    【解决方案5】:

    基于 MGDroid 对 API 16+ 的回答使用 Kotlin 的通用方法。

    /**
     * Align height of a container from wrap-content to actual height at runtime.
     * */
    private fun <T: ViewGroup> alignContainerHeight(container: T) {
        container.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
            override fun onGlobalLayout() {
    
                // Obtain runtime height
                val availableHeight = container.measuredHeight
    
                if (availableHeight > 0) {
                    container.viewTreeObserver.removeOnGlobalLayoutListener(this)
                    setContainerHeight(container, availableHeight)
                }
            }
        })
    }
    
    /**
     * Note: Assumes that the parent is a LinearLayout.
     * */
    private fun <T : ViewGroup> setContainerHeight(container: T, availableHeight: Int) {
        val availableWidth = container.measuredWidth
        val params = LinearLayout.LayoutParams(availableWidth, availableHeight)
    
        // Note: getLayoutParams() returns null if no parent exists
        if (container.layoutParams != null) {
            container.layoutParams = params
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-03
      • 1970-01-01
      • 2014-02-16
      相关资源
      最近更新 更多