Skip to content

Activity中获取View的宽高

有些时候我们需要获取到View的宽高信息。

在onCreate和onResume中尝试view.getWidth()或是view.getHeiht()时,我们会发现获取到的是0。

Activity视图在创建完成后,各个子view并不一定被加载完成。 获取宽高正确的方法有哪些呢?

方法1 - 在Activity的onWindowFocusChanged获取宽高

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        // 在这里我们可以获取到View的真实宽高
        Log.d(TAG, "onWindowFocusChanged: mBtn1.getWidth == " + mBtn1.getWidth());
    }

方法2 - 使用ViewTreeObserver的OnGlobalLayoutListener回调

获取View的ViewTreeObserver,添加回调

    ViewTreeObserver vto = mBtn1.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            int height = mBtn1.getHeight();
            int width = mBtn1.getWidth();
            Log.d(TAG, "onGlobalLayout: mBtn1 " + width + ", " + height);
            mBtn1.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        }
    });

方法3 - 使用View.post(Runnable action)方法

例如我们在onCreate中post一个Runnable

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBtn1 = findViewById(R.id.btn1);
        Log.d(TAG, "mBtn1 post runnable");
        mBtn1.post(new Runnable() {
            @Override
            public void run() {
                Log.d(TAG, "mBtn1: " + mBtn1.getWidth() + ", " + mBtn1.getHeight());
            }
        });
    }

/* log
06-19 11:54:17.865 28009-28009/com.rustfisher.basic4 D/rustApp: mBtn1 post runnable
06-19 11:54:17.867 28009-28009/com.rustfisher.basic4 D/rustApp: [act2] onResume
06-19 11:54:17.899 28009-28009/com.rustfisher.basic4 D/rustApp: mBtn1: 355, 144
*/

可以获取到view的宽高。从log的时间上可以看出,在view加载完毕后,执行的Runnable。

应用 - 动态调整ImageView的宽高

获取到view的宽高后,我们可以动态地调整ImageView的高度。 假设图片宽高为704 * 440。xml中设置scaleType为fitXY。已知ImageView的宽度是固定的,我们可以调整高度。

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scaleType="fitXY"/>

根据图片真实大小来重设ImageView的高度。

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        resetIntroIvParams();
    }

    private void resetIntroIvParams() {
        int height = mIntroIv.getHeight(); // 704 * 440
        int wid = mIntroIv.getWidth();
        if (height > 0 && wid > 0) {
            ViewGroup.LayoutParams layoutParams = mIntroIv.getLayoutParams();
            layoutParams.height = (int) (wid * 440.0 / 704.0);
            mIntroIv.setLayoutParams(layoutParams);
        }
    }