在onCreate()中要想获得View的高度,共有4中方法:
先上测试代码:
布局文件activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.sw.testdemo.MainActivity">
<LinearLayout
android:id="@+id/linearlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
</LinearLayout>
</ScrollView>
MainActivity.java的完整代码:
public class MainActivity extends AppCompatActivity { private static final String TAG = "TestDemo"; private LinearLayout mLinearLayout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mLinearLayout = (LinearLayout) findViewById(R.id.linearlayout); mLinearLayout.measure(0, 0); int measuredHeight = mLinearLayout.getMeasuredHeight(); int height = mLinearLayout.getHeight(); Log.d(TAG, "measuredHeight =" + measuredHeight + "height =" + height); // mLinearLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { // @TargetApi(Build.VERSION_CODES.JELLY_BEAN) // @Override // public void onGlobalLayout() { // mLinearLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this); // int measuredHeight = mLinearLayout.getMeasuredHeight(); // int height = mLinearLayout.getHeight(); // Log.d(TAG, "measuredHeight =" + measuredHeight + "height =" + height); // } // }); // mLinearLayout.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { // @Override // public boolean onPreDraw() { // mLinearLayout.getViewTreeObserver().removeOnPreDrawListener(this); // int measuredHeight = mLinearLayout.getMeasuredHeight(); // int height = mLinearLayout.getHeight(); // Log.d(TAG, "measuredHeight =" + measuredHeight + "height =" + height); // return true; // } // }); // int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); // int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); // mLinearLayout.measure(w, h); // int height = mLinearLayout.getHeight(); // int measuredHeight = mLinearLayout.getMeasuredHeight(); // Log.d(TAG, "measuredHeight = " + measuredHeight + "height = " + height); } }方法1:
在onCreate()方法中手动执行measure()方法,看结果:
01-20 21:45:58.121 1383-1383/? D/TestDemo: measuredHeight =2052height =0
可见可以得到measuredHeight,但是得不到height,因为measuredHeight实在View的onMeasure()方法执行之后就可以得到,而height则要等到整个视图布局完成以后才能得到。
方法2:
获取view的ViewTreeObserver对象vto,给vto添加布局监听:
01-20 21:54:08.605 8776-8776/? D/TestDemo: measuredHeight =2052height =2052
这时候两个值都可以得到,而且相等。
方法3:
还是利用vto,只是这回是添加绘图监听:
View的绘制过程是:onFinishInflate() --> onSizeChanged() --> onLayout() --> onMeasure() -->
onMeasure() --> onLayout() --> onDraw();
所以这时候两个值都可以得到,而且相等。
01-20 22:01:12.761 15155-15155/com.example.sw.testdemo D/TestDemo: measuredHeight =2052height =2052
方法4:
其实和方法一是一样的,只不过写法不同而已。测试结果如下:
01-20 22:02:39.697 16525-16525/com.example.sw.testdemo D/TestDemo: measuredHeight = 2052height = 0
二、如果给LinearLayout布局添加一个paddingTop属性呢:
给LinearLayout添加一个paddingTop = "10dp";的属性,用方法2测试,结果如下:
01-20 22:07:20.197 20861-20861/com.example.sw.testdemo D/TestDemo: measuredHeight =2082height =2082
可见,getMeasuredHeight和getHeight都是view内容的高度。
三、给LinearLayout添加一个paddingTop = "-10dp";的属性,用方法2测试,结果如下:
01-20 22:06:44.169 20278-20278/? D/TestDemo: measuredHeight =2052height =2052
四、把最外层嵌套的ScrollView去掉,测试结果如下:
01-20 22:12:49.433 26267-26267/? D/TestDemo: measuredHeight =1533height =1533
五、添加代码测量屏幕高度,测试结果如下:
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); DisplayMetrics outMetrics = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(outMetrics); int screenHeight = outMetrics.heightPixels; Log.d(TAG, "screenHeight = " + screenHeight);01-20 22:21:48.625 2137-2137/com.example.sw.testdemo D/TestDemo: screenHeight = 1776
01-20 22:21:48.713 2137-2137/com.example.sw.testdemo D/TestDemo: measuredHeight =1533height =1533
两者的差距应该是一个actionbar的高度。
总结:
在系统提供的原生控件中,getHeight()和getMeasuredHeight()永远是相等的,只有在自定义控件中如果measure()方法中传入的参数不是onMeasure()方法的参数时,两者会不相等。