V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
XhstormR
V2EX  ›  Android

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

  •  
  •   XhstormR · 2016-08-23 14:55:12 +08:00 · 10491 次点击
    这是一个创建于 3013 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    一般情况下 getMeasuredWidth 和 getWidth 方法的值是一致的,这里只要记住一般情况下除了在 onLayout 方法中调用 getMeasuredWidth 方法外其它的地方用 getWidth 方法就行了。
    kifile
        12
    kifile  
       2016-08-23 16:42:01 +08:00
    @XhstormR 没有遇到过,但是很明显能够猜到, mBottom-mTop!= mMeasuredHeight 的情况 一般都是发生在 ScrollView 等一系列自己控制了界面绘制区域的布局中。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   932 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 22:24 · PVG 06:24 · LAX 14:24 · JFK 17:24
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.