以编程方式获取布局的高度和宽度

时间:2014-02-21 06:13:20

标签: android android-layout

我设计了一个布局,其中LinearLayout有2个孩子LinearLayoutFrameLayout,在每个孩子中我都有不同的观点。

我只是想测量FrameLayout的高度和宽度,以便我可以达到我的目的。

在程序中我正在使用

int height,width;

FrameLayout fr=(FrameLayout)findviewbyid(R.id.fr);
height=fr.getHeight();
width=fr.getWidth();

为两个

返回值0

即使我尝试使用以下代码 int height,width;

FrameLayout fr=(FrameLayout)findviewbyid(R.id.fr);
height=fr.getMeasuredHeight();
width=fr.getMeasuredWidth();

返回相同的值0

最后我尝试使用以下代码, int height,width;

FrameLayout fr=(FrameLayout)findviewbyid(R.id.fr);
height=fr.getgetLayoutParams().height();
width=fr.getLayoutParams().width;

返回-2-1

我希望解决方案能够以编程方式获取任何布局的高度和宽度吗?

18 个答案:

答案 0 :(得分:114)

视图本身,它有自己的生命周期,基本如下:

  • 测量

  • 布局

  • 绘图

因此,根据您何时尝试获得宽度/高度,您可能看不到您期望看到的内容,例如,如果您在onCreate期间执行此操作,则该视图可能甚至不会在该时间进行测量,另一方面,如果你在按钮的onClick方法中这样做,很可能到目前为止该视图已被附加,测量,布局和绘制,因此,您将看到预期值,您应该实现ViewTreeObserver以确保您正在适当的时刻获得价值。

LinearLayout layout = (LinearLayout)findViewById(R.id.YOUD VIEW ID);
ViewTreeObserver vto = layout.getViewTreeObserver(); 
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 
    @Override 
    public void onGlobalLayout() { 
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
                this.layout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            } else {
                this.layout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            } 
        int width  = layout.getMeasuredWidth();
        int height = layout.getMeasuredHeight(); 

    } 
});

答案 1 :(得分:15)

作为CapDroid,你正在尝试在视图之前获取大小(如果绘制),另一种可能的解决方案是在视图上执行带有runnable的帖子:

mView.post(new Runnable() {
        @Override
        public void run() {
            int width = mView.getWidth();
            int height = mView.getHeight();
        }
}

答案 2 :(得分:14)

我认为你在OnCreate()方法中获得了高度和宽度,这就是为什么你总是得到0值,因为那时你的视图仍然没有被创建。

尝试通过点击某个按钮获得高度和宽度,或者..

答案 3 :(得分:6)

只要给你的身高,如果需要,你将获得身高甚至宽度。

/ **      *在视图呈现之前获取视图高度      * @param查看要测量的视图      * @return视图的高度      * /

public static int getViewHeight(View view) {
    WindowManager wm =
            (WindowManager) view.getContext().getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();

    int deviceWidth;

    if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2){
        Point size = new Point();
        display.getSize(size);
        deviceWidth = size.x;
    } else {
        deviceWidth = display.getWidth();
    }

    int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(deviceWidth, View.MeasureSpec.AT_MOST);
    int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
    view.measure(widthMeasureSpec, heightMeasureSpec);
    return view.getMeasuredHeight(); //        view.getMeasuredWidth();
}

答案 4 :(得分:6)

只想在这里添加答案,因为Koltin有一些方便的方法可以做到这一点,比添加和删除onGlobalLayoutListener时要麻烦得多:

view.doOnLayout {
    it.measuredWidth
    it.measuredHeight
}

您可以看到更多的便捷方法here

答案 5 :(得分:6)

如果得到-1或-2,它也可以是LayoutParams.WRAP_CONTENT(-2)或LayoutParams.MATCH_PARENT(-1)的数值。

答案 6 :(得分:3)

我有同样的问题,但在测量之前并不想在屏幕上绘图所以我在尝试获取高度和宽度之前使用了这种测量视图的方法。

使用示例:

layoutView(view);
int height = view.getHeight();

//...

void layoutView(View view) {
    view.setDrawingCacheEnabled(true);
    int wrapContentSpec = 
        MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
    view.measure(wrapContentSpec, wrapContentSpec);
    view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
}

答案 7 :(得分:3)

尝试这种方法:

int width = mView.getMeasuredWidth();

int height = mView.getMeasuredHeight();

int width = mTextView.getMeasuredWidth();

int height = mTextView.getMeasuredHeight();

答案 8 :(得分:2)

最简单的方法是使用ViewTreeObserver,如果直接使用.height或.width,则值为0,因为视图在我们的屏幕上绘制之前没有大小。以下示例将说明如何使用ViewTreeObserver

ViewTreeObserver viewTreeObserver = YOUR_VIEW_TO_MEASURE.getViewTreeObserver();
        if (viewTreeObserver.isAlive()) {
            viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {

                    YOUR_VIEW_TO_MEASURE.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    int viewHeight = YOUR_VIEW_TO_MEASURE.getHeight();
                    int viewWeight = YOUR_VIEW_TO_MEASURE.getWidth();

                }
            });
        }

如果你需要在方法上使用它,请像这样使用并保存值,你可以使用全局变量。

答案 9 :(得分:1)

第一个代码段是正确的,但您需要在执行 onMeasure()后将其称为。否则,尚未测量视图的大小。

答案 10 :(得分:1)

对于框架:

height=fr.getHeight();
width=fr.getWidth();

对于屏幕:

width = getWindowManager().getDefaultDisplay().getWidth();
height = getWindowManager().getDefaultDisplay().getHeight();

答案 11 :(得分:0)

我使用DisplayMetrics来获取屏幕大小,然后我可以为%age中的元素指定宽度/高度

就像这样

NSError *error;
if (![[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:&error])
{
    NSLog(@"audio session error: %@", error);
}

非常适合我!

答案 12 :(得分:0)

尝试使用this链接

中的代码
ViewTreeObserver viewTreeObserver = view.getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
 viewTreeObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
  view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
  viewWidth = view.getWidth();
  viewHeight = view.getHeight();
}
 });
}

希望这会有所帮助。

答案 13 :(得分:0)

在Kotlin中,您可以简单地执行以下操作:

fr.post {
    height=fr.height;
    width=fr.width;
}

答案 14 :(得分:0)

我刚遇到这个问题时以为我会为kotlin编写它,

my_view.viewTreeObserver.addOnGlobalLayoutListener {
       // here your view is measured
       // get height using my_view.height
       // get width using my_view.width
    }

my_view.post {
       // here your view is measured
       // get height using my_view.height
       // get width using my_view.width
    }

答案 15 :(得分:0)

您也可以使用协程,就像这样:

CoroutineScope(Dispatchers.Main).launch {
        delay(10)
        val width = view.width()
        val height= view.height()
        // do your job ....
    }

答案 16 :(得分:0)

检查行为 非常简单的解决方案

  override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        Log.d(LOG, "MainActivity - onCreate() called")

        fragments_frame.post {
            Log.d(LOG, " fragments_frame.height:${fragments_frame.width}")
            Log.d(LOG, " fragments_frame.height:${fragments_frame.measuredWidth}")
        }
}

答案 17 :(得分:0)

如果你用 Kotlin 编写代码,请使用这个不错的扩展函数:

inline fun View.getDimensions(crossinline onDimensionsReady: (Int, Int) -> Unit) {
    lateinit var layoutListener: ViewTreeObserver.OnGlobalLayoutListener
    layoutListener = ViewTreeObserver.OnGlobalLayoutListener {
        viewTreeObserver.removeOnGlobalLayoutListener(layoutListener)
        onDimensionsReady(width, height)
    }
    viewTreeObserver.addOnGlobalLayoutListener(layoutListener)
}

用法:

view.getDimensions { width, height ->
    println("width = $width")
    println("height = $height")
}