为什么 getMeasuredHeight() 和 getHeight() 的值会相等,又 Bug 了?

2016-08-23 14:55:12 +08:00
 XhstormR

布局就是一个 ScrollView 包裹一个超长文章的 TextView ,超过屏幕显示了。

按网上所说, getHeight() 最大就是获取屏幕的高度,但是这里 getHeight() 却和 getMeasuredHeight() 的值相等,都超过我的屏幕高度 1280 了,和网上所说的不符啊。

代码也是最基础的,难道又 Bug 了,或者 getHeight() 和 getMeasuredHeight() 本来就相等?

Log 语句:

scrollView.getMeasuredHeight() + ":" + scrollView.getHeight() + ":" + scrollView.getChildAt(0).getMeasuredHeight() + ":" + scrollView.getChildAt(0).getHeight() + ":" + scrollView.getScrollY()

Log

08-23 14:42:34.428 3282-3282/com.example.system.myapplication I/Tag: 1230:1230:2733:2733:1503
08-23 14:42:34.428 3282-3282/com.example.system.myapplication I/Tag: 底部
08-23 14:42:34.870 3282-3282/com.example.system.myapplication I/Tag: 1230:1230:2733:2733:1248
08-23 14:42:35.355 3282-3282/com.example.system.myapplication I/Tag: 1230:1230:2733:2733:916
08-23 14:42:35.909 3282-3282/com.example.system.myapplication I/Tag: 1230:1230:2733:2733:464
08-23 14:42:36.458 3282-3282/com.example.system.myapplication I/Tag: 1230:1230:2733:2733:0
08-23 14:42:36.458 3282-3282/com.example.system.myapplication I/Tag: 顶部
08-23 14:42:37.998 3282-3282/com.example.system.myapplication I/Tag: 1230:1230:2733:2733:0
08-23 14:42:37.998 3282-3282/com.example.system.myapplication I/Tag: 顶部
08-23 14:42:38.927 3282-3282/com.example.system.myapplication I/Tag: 1230:1230:2733:2733:484

MainActivity.java

package com.example.system.myapplication;

import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ScrollView;
import android.widget.TextView;

public class MainActivity extends Activity implements View.OnTouchListener {
    private ScrollView scrollView;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);

        TextView textView = (TextView) findViewById(R.id.textView);
        textView.setText(getResources().getString(R.string.content));

        scrollView = (ScrollView) findViewById(R.id.scrollView);
        scrollView.setOnTouchListener(this);
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                Log.i("Tag", scrollView.getMeasuredHeight() + ":" + scrollView.getHeight() + ":" + scrollView.getChildAt(0).getMeasuredHeight() + ":" + scrollView.getChildAt(0).getHeight() + ":" + scrollView.getScrollY());
                if (scrollView.getScrollY() == 0) {
                    Log.i("Tag", "顶部");
                }
                if (scrollView.getScrollY() + scrollView.getHeight() == scrollView.getChildAt(0).getHeight()) {
                    Log.i("Tag", "底部");
                }
                break;
            case MotionEvent.ACTION_MOVE:
                break;
            case MotionEvent.ACTION_UP:
                break;
        }
        return false;
    }
}

main_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <ScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/scrollView">
        <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="New Text"
                android:textSize="20sp"
                android:id="@+id/textView"/>
    </ScrollView>

</LinearLayout>
10558 次点击
所在节点    Android
12 条回复
icris
2016-08-23 15:29:02 +08:00
理论跟事实冲突显然要否定理论,把那个网页关了就好。我搜了一下,这说法出处好像是 [“ PHP 码农的专栏”]( http://blog.csdn.net/xujainxing/article/details/8985063)
XhstormR
2016-08-23 15:35:32 +08:00
@icris 我也搜到过这篇文章,国内大部分文章都这么说,搞得我都怀疑是 Bug 了,以前听别人说国内博客真害人,现在也遇见了....
kifile
2016-08-23 15:37:21 +08:00
果然是被 ScrollView 包了
XhstormR
2016-08-23 15:43:10 +08:00
@kifile 你也遇见过?
GentleSadness
2016-08-23 15:43:19 +08:00
1230 excuse me ?
songwenhai
2016-08-23 15:47:11 +08:00
ScrollView 的 child , height 是用 UNSPECIFIED 来 measure 的
可以看一下 ScrollView 的 measureChild 方法
XhstormR
2016-08-23 15:48:01 +08:00
@GentleSadness 还有状态栏嘛,整个屏幕高度是 1280 。
icris
2016-08-23 15:48:34 +08:00
@kifile ScrollView 不是必须的,本来就没这回事儿,那个博客最近一条评论有实验 http://blog.csdn.net/dmk877/article/details/49734869
GentleSadness
2016-08-23 15:53:09 +08:00
到底谁告诉你,他们两个不相等的
XhstormR
2016-08-23 16:03:39 +08:00
不是 Bug ,是网上的博客有误, getHeight() 根本不是获取控件在屏幕中的高度。

下面的话摘自 http://blog.csdn.net/dmk877/article/details/49734869

```
我相信很多人对 getMeasuredWidth 和 getWidth 方法(getMeasuredHeight 和 getHeight 类似这里仅以 getMeasuredWidth 和 getWidth 为例)都有过疑惑,并且网上去查阅资料看后也似懂非懂感觉,甚至有网上的讲解是错的,看到这肯定有很多人会说有哪些是错的?你凭什么说别人是错的?凭什么让我们相信你说的是对的?对于这个问题,由于我刚开始查阅资料时看到网上有人说:“实际上在当屏幕可以包裹内容的时候,他们的值是相等的,只有当 view 超出屏幕后,才能看出他们的区别: getMeasuredWidth()是实际 View 的大小,与屏幕无关,而 getHeight 的大小此时则是屏幕的大小。当超出屏幕后 getMeasuredWidth()等于 getWidth()加上屏幕之外没有显示的大小”,相信不止我一个人看到这样的答案,当时我也觉着有道理由于水平有限,我就将上述说法记在了脑子里,但是随着学习的深入我发现这种说法是不正确的,下面我将详细的从源码的角度来分析这两者的区别以及为什么上面的说法是错误的,相信看完后肯定会有收获。
```
XhstormR
2016-08-23 16:08:37 +08:00
还是摘自 http://blog.csdn.net/dmk877/article/details/49734869

一般情况下 getMeasuredWidth 和 getWidth 方法的值是一致的,这里只要记住一般情况下除了在 onLayout 方法中调用 getMeasuredWidth 方法外其它的地方用 getWidth 方法就行了。
kifile
2016-08-23 16:42:01 +08:00
@XhstormR 没有遇到过,但是很明显能够猜到, mBottom-mTop!= mMeasuredHeight 的情况 一般都是发生在 ScrollView 等一系列自己控制了界面绘制区域的布局中。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/301189

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX