关于getMeasuredHeight和getHeight区别

本文详细解析了Android开发中View的getMeasuredHeight与getHeight两个方法的区别。getMeasuredHeight返回的是测量的高度,即通过onMeasure方法设置的高度;而getHeight则是View在屏幕上实际显示的高度,需在onLayout方法后调用才能获取准确值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于getMeasuredHeight和getHeight区别

getMeasuredHeight:是用于测量的高度,也就是View实际的高度(先暂时这么记,后面还有一个显示出来的高度),getMeasuredHeight的值是在onMeasure方法里面通过setMeasuredDimension();设置出来的。也就是说要在onMeasure方法之后调用,不能再之前,这样会得到0。
如果你的View没有设置setMeasuredDimension方法,而是android:layout_height="match_parent"那么你的getMeasuredHeight就等于你手机屏幕的宽度,Log.i("yaoyan"," "+ getMeasuredWidth());这里写图片描述博主手机分辨率还是蛮高的,如果你设置的android:layout_height="match_parent"为200dp,那么打印出来的是像素你可以通过View.getResources().getDisplayMetrics().density*200这样就可以转换为像素了。

getHeight:是指在屏幕上显示出来的高度(这里要强调一点就是不能再onCreate方法里面获得一个View的高度),这个方法得到的是View显示在桌面上的高度(跟前面测量的高度相对对应),因为View的onMeasure方法运行完之后还会运行一个onLayout方法,要等到onLayout运行完之后才能得到具体的值,这个方法是指View所在屏幕上的位置,通过View.layout(int Left,int Top,int Right,int Bottom)改变View在屏幕上的大小(这个方法只是改变形状上的大小,实际的View并没有改变)
下面来看代码
布局文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/RL"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

<com.xie.acer1.test.youyou
    android:id="@+id/youyou"
    android:background="#000000"
    android:layout_width="300dp"
    android:layout_height="300dp" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New Button"
        android:id="@+id/button"
        android:onClick="Button"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

</RelativeLayout>

自定义View文件

package com.xie.acer1.test;

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

/**
 * Created by acer1 on 2016/1/23.
 */
public class youyou extends View {
    public youyou(Context context) {
        super(context);
    }

    public youyou(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        Log.i("yaoyan","   "+ getMeasuredHeight()+"  "+getHeight());
        super.onDraw(canvas);
    }
}
package com.xie.acer1.test;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

public class MainActivity extends AppCompatActivity {

    private youyou y;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        y = (youyou) findViewById(R.id.youyou);
    }

    public void Button(View view){
        y = (youyou) findViewById(R.id.youyou);
        y.layout(y.getLeft(),y.getTop(),y.getRight(),y.getBottom()-10);
        System.out.println(y.getTop());
    }

}
这里在强调一点getLeft是设置View距离父View的距离,如果一个布局文件中有很多的LinearLayout或者RelativeLayout,一圈一圈的嵌套,容易搞混,一定是距离父窗体

这里写图片描述
这里写图片描述
这里写图片描述
这里可以看到每次点击Button按钮,View视图在距离底部在一点点的缩小,getHeight也越来越小,但是getMeasuredHeight却始终都没有变化,这就是实际测量视图的高度与手机可视高度的区别

注意看第一张图片,博主没有点击Button的时候getHeight和getMeasuredHeight是一样的。

也有很多初学者对getHeight和getMeasuredHeight的值为什么一样苦恼
可以看一下源码,究竟有什么区别

/**
     * Return the height of your view.
     *
     * @return The height of your view, in pixels.
     */
    @ViewDebug.ExportedProperty(category = "layout")
    public final int getHeight() {
        return mBottom - mTop;
    }

如果我们不特意设置View.layout方法,getHeight所得到的高度就是getMeasuredHeight实际高度,所以有的时候这两个值是一样的。

博主第一篇技术博客,写的不好请大家指出来,轻点喷。

<think>好的,我现在要解决用户的问题:如何正确使用mRecyclerView.getHeight()来获取RecyclerView的高度。首先,我需要回顾一下AndroidView的测量机制。RecyclerView作为ViewGroup的一种,其高度可能受到布局流程的影响,比如在Activity生命周期中,如果过早调用getHeight(),可能还未完成测量,导致返回0。 接下来,用户提到他们已经在布局文件中正确设置了RecyclerView,并且引用了相关的代码,比如通过findViewById获取实例,设置了LayoutManager等。这说明他们的基本配置是正确的。但问题出现在何时获取高度。这时候需要考虑View的生命周期,特别是onCreate方法中可能无法立即获取正确的尺寸,因为此时View还未被测量。 然后,我需要思考正确的获取时机。通常,在onWindowFocusChanged方法中,当窗口获得焦点时,View已经完成布局,这时候调用getHeight()可以得到正确的高度。另外,使用ViewTreeObserver的OnGlobalLayoutListener也是一个可行的方法,它会在布局变化时回调,确保在布局完成后获取高度。 此外,用户可能遇到动态改变RecyclerView内容的情况,比如数据更新后需要重新获取高度。这时候可能需要再次监听布局变化,或者在数据更新后手动触发测量。 还要注意,如果在子线程中直接调用getHeight()可能会有问题,需要确保在主线程中操作。同时,如果RecyclerView的布局参数设置为wrap_content,可能需要确保内容已经加载完成,否则高度可能不准确。 最后,需要检查用户是否正确添加了依赖库,如引用[4]中的recyclerview-v7库,确保RecyclerView本身能够正常工作。如果有其他布局问题,比如父容器的约束不正确,也可能影响高度的获取,需要综合考虑。</think>### 如何正确获取 RecyclerView 的高度? #### 1. 直接调用 `getHeight()` 的限制 在 `onCreate()` 或 `onResume()` 中直接调用 `mRecyclerView.getHeight()` 可能返回 `0`,因为此时视图尚未完成测量布局。例如: ```java // onCreate() 中直接调用会失效 int height = mRecyclerView.getHeight(); // 可能返回 0 ``` #### 2. 正确获取高度的三种方法 **方法一:使用 `ViewTreeObserver` 监听布局完成** ```java mRecyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { // 确保移除监听避免重复调用 mRecyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this); int height = mRecyclerView.getHeight(); Log.d("RecyclerViewHeight", "Height: " + height); } }); ``` *原理*:在视图树完成布局后触发回调,此时可获取准确高度[^3]。 **方法二:在 `onWindowFocusChanged` 中获取** ```java @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if (hasFocus) { int height = mRecyclerView.getHeight(); Log.d("RecyclerViewHeight", "Height: " + height); } } ``` *适用场景*:适用于需要窗口焦点稳定后的场景(如对话框)。 **方法三:手动触发测量** ```java mRecyclerView.post(new Runnable() { @Override public void run() { int widthSpec = View.MeasureSpec.makeMeasureSpec(mRecyclerView.getWidth(), View.MeasureSpec.EXACTLY); int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); mRecyclerView.measure(widthSpec, heightSpec); int height = mRecyclerView.getMeasuredHeight(); } }); ``` *注意*:此方法强制测量视图,适用于动态内容变化的场景[^2]。 #### 3. 常见问题排查 - **布局未完成**:确保在 `RecyclerView.setAdapter()` `RecyclerView.setLayoutManager()` 之后获取高度 - **动态数据加载**:若数据异步加载,需在数据填充完成后重新获取高度 - **布局参数冲突**:检查 XML 中是否设置了 `android:layout_height="wrap_content"` 或固定值
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值