蓝桉云顶

Good Luck To You!

Android中如何准确获取View在布局中的高度与宽度?

在Android中获取View在布局中的高度与宽度,可以通过多种方法实现。常见的方法包括使用View.measure()ViewTreeObserver监听事件、重写onSizeChanged()onLayout()方法等。使用ViewTreeObserver.OnGlobalLayoutListener可以在视图绘制完成后获取其宽高。

在Android开发中,获取View组件的宽度和高度是一项常见的需求,由于View的绘制过程涉及到多个阶段,如测量(measure)、布局(layout)和绘制(draw),直接调用getWidth()或getHeight()方法在某些情况下可能无法得到预期的结果,本文将详细介绍几种有效的方法来获取View在布局中的实际宽度和高度,并提供相应的代码示例和表格归纳。

一、使用View.measure方法

这种方法通过手动测量View来获取其宽度和高度,不过,这种方法得到的尺寸可能与最终绘制时的尺寸不一致,因为它没有考虑父布局的影响。

示例代码:

int width = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
int height = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
view.measure(width, height);
int measuredWidth = view.getMeasuredWidth(); // 获取宽度
int measuredHeight = view.getMeasuredHeight(); // 获取高度

二、使用ViewTreeObserver.OnPreDrawListener监听事件

在视图将要绘制时调用该监听事件,可以获取到视图即将绘制时的宽度和高度,需要注意的是,这个监听器会被多次调用,因此获取到尺寸后需要移除监听器。

示例代码:

view.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
    @Override
    public boolean onPreDraw() {
        view.getViewTreeObserver().removeOnPreDrawListener(this);
        int width = view.getWidth(); // 获取宽度
        int height = view.getHeight(); // 获取高度
        return true;
    }
});

三、使用ViewTreeObserver.OnGlobalLayoutListener监听事件

当布局发生改变或者某个视图的可视状态发生改变时,会调用该事件,这是最常用的方法之一,因为它确保了在视图布局完成后获取尺寸。

示例代码:

view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        if (Build.VERSION.SDK_INT >= 16) {
            view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        } else {
            view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
        }
        int width = view.getWidth(); // 获取宽度
        int height = view.getHeight(); // 获取高度
    }
});

四、使用View.post方法

Runnable对象中的方法会在View的measure、layout等事件完成后触发,这个方法只会执行一次,且逻辑简单,是推荐使用的方法之一。

示例代码:

view.post(new Runnable() {
    @Override
    public void run() {
        int width = view.getWidth(); // 获取宽度
        int height = view.getHeight(); // 获取高度
    }
});

五、重写View的onSizeChanged方法(不推荐)

虽然可以通过重写onSizeChanged方法来获取视图的大小变化,但由于该方法会被多次调用,且需要继承View类,因此一般不推荐使用。

示例代码:

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    int width = w; // 获取宽度
    int height = h; // 获取高度
}

六、重写View的onLayout方法(不推荐)

与onSizeChanged类似,onLayout方法也会被多次调用,且需要继承View类,因此也不推荐使用。

示例代码:

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    super.onLayout(changed, l, t, r, b);
    int width = r l; // 获取宽度
    int height = b t; // 获取高度
}

七、使用View.OnLayoutChangeListener监听事件(API >= 11)

在视图的layout改变时调用该事件,但同样需要移除监听器以避免多次调用。

示例代码:

view.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
    @Override
    public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
        view.removeOnLayoutChangeListener(this);
        int width = right left; // 获取宽度
        int height = bottom top; // 获取高度
    }
});

以下是各方法的比较表格:

方法 适用场景 优点 缺点 示例代码位置
View.measure 手动测量View 简单直接 不考虑父布局影响 [方法一](#)
ViewTreeObserver.OnPreDrawListener 视图将要绘制时 可获取即将绘制时的尺寸 需移除监听器 [方法二](#)
ViewTreeObserver.OnGlobalLayoutListener 布局或视图状态改变时 确保布局完成后获取尺寸 需移除监听器 [方法三](#)
View.post View事件完成后 逻辑简单,只执行一次 [方法四](#)
重写onSizeChanged 视图大小变化时 不推荐,多次调用 需继承View类 [方法五](#)
重写onLayout 视图布局时 不推荐,多次调用 需继承View类 [方法六](#)
View.OnLayoutChangeListener 视图layout改变时(API >= 11) 需移除监听器 [方法七](#)

推荐使用ViewTreeObserver.OnGlobalLayoutListener或View.post方法来获取View在布局中的实际宽度和高度,因为它们既简单又有效。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

«    2024年11月    »
123
45678910
11121314151617
18192021222324
252627282930
控制面板
您好,欢迎到访网站!
  查看权限
网站分类
搜索
最新留言
文章归档
网站收藏
友情链接