当前位置: 首页 > news >正文

(面试)获取View宽高的几种方式

Android 中获取 View 宽高的几种方式,以及它们的适用场景和注意事项:

1. View.getWidth()View.getHeight()

  • 原理: 直接从 View 对象中获取已经计算好的宽度和高度。

  • 优点: 简单直接。

  • 缺点: onCreate()onStart() 等生命周期方法中,View 可能还没有完成测量,此时获取到的值可能是 0。 通常在 onResume() 之后才能保证获取到正确的值。
    问题本质:

  1. onCreate()setContentView() 仅加载布局,未开始测量。
  2. onStart()/onResume():界面可见,但测量可能仍未完成(尤其是复杂布局或异步数据加载时)。
  • 适用场景: 在 View 已经完成布局之后,需要获取其宽高时使用。例如,在用户交互事件(如点击事件)中,或者在 onWindowFocusChanged(boolean hasFocus) 方法中。

  • 代码示例:

    @Override
    protected void onResume() {super.onResume();int width = myView.getWidth();int height = myView.getHeight();Log.d("ViewSize", "Width: " + width + ", Height: " + height);
    }
    

    2. View.getMeasuredWidth()View.getMeasuredHeight()

  • 原理: 获取 View 的测量宽度和测量高度。 View 在布局过程中会经过测量阶段,getMeasuredWidth()getMeasuredHeight() 返回的就是测量阶段计算出的宽高

  • 优点:getWidth()getHeight() 更早获取到 View 的宽高信息。

  • 缺点: 测量宽高可能与最终显示的宽高不同 例如,如果 View 的 layout_widthlayout_height 设置为 wrap_content,并且父容器对其进行了限制,那么测量宽高可能只是一个预估值。 此外,如果 View 进行了重新测量,getMeasuredWidth()getMeasuredHeight() 的值也会发生变化。

  • 适用场景: 在 View 还没有完全布局完成,但需要提前知道其大致宽高信息时使用。例如,在自定义 View 的 onMeasure() 方法中。

  • 代码示例:

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int measuredWidth = getMeasuredWidth();int measuredHeight = getMeasuredHeight();Log.d("ViewSize", "Measured Width: " + measuredWidth + ", Measured Height: " + measuredHeight);
    }
    

    3. ViewTreeObserver.OnGlobalLayoutListener

  • ViewTreeObserver.OnGlobalLayoutListener 是 Android 中用于监听 视图树(ViewTree)全局布局变化 的接口,常用于在 View 完成测量和布局后 获取其宽高、位置等属性。

  • 优点: 可以保证在 View 已经完成布局之后获取到正确的宽高值 即使 View 的宽高在布局过程中发生了变化,也能及时获取到最新的值。

  • 缺点: 需要注册监听器,并且在获取到宽高后需要移除监听器,否则会造成性能问题。

  • 适用场景: 需要在 View 布局完成后立即获取其宽高,并且需要保证获取到的值是准确的。

  • 代码示例:

    @Override
    protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);myView = findViewById(R.id.my_view);ViewTreeObserver vto = myView.getViewTreeObserver();vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {@Overridepublic void onGlobalLayout() {myView.getViewTreeObserver().removeOnGlobalLayoutListener(this);int width = myView.getWidth();int height = myView.getHeight();Log.d("ViewSize", "Width: " + width + ", Height: " + height);}});
    }
    

    4. View.post(Runnable)

  • 原理: 将一个 Runnable 对象添加到 View 的消息队列中,该 Runnable 对象会在 View 布局完成后执行。

  • 优点: 可以保证在 View 已经完成布局之后获取到正确的宽高值,并且代码简洁。

  • 缺点: 相对于 OnGlobalLayoutListener,可能稍微延迟一点执行

  • 适用场景: 需要在 View 布局完成后立即获取其宽高,并且对执行时间要求不高。

  • 代码示例:

    @Override
    protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);myView = findViewById(R.id.my_view);myView.post(new Runnable() {@Overridepublic void run() {int width = myView.getWidth();int height = myView.getHeight();Log.d("ViewSize", "Width: " + width + ", Height: " + height);}});
    }
    

    5. View.addOnLayoutChangeListener(OnLayoutChangeListener) (API Level 11+)

  • 原理: 监听 View 的布局变化。 当 View 的布局发生改变时,onLayoutChange() 方法会被调用。

  • 优点: 可以监听 View 的布局变化,并在布局变化后获取最新的宽高值。

  • 缺点: 只在 API Level 11 及以上可用。

  • 适用场景: 需要在 View 布局变化后立即获取其宽高,并且需要监听 View 的布局变化。

  • 代码示例:

    @Override
    protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);myView = findViewById(R.id.my_view);myView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {@Overridepublic void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {int width = myView.getWidth();int height = myView.getHeight();Log.d("ViewSize", "Width: " + width + ", Height: " + height);}});
    }
    

相关文章:

  • 从模式到架构:Java 工厂模式的设计哲学与工程化实践
  • unix/linux source 命令,其发展历程详细时间线、由来、历史背景
  • 函数栈帧深度解析:从寄存器操作看函数调用机制
  • 通过WiFi无线连接小米手机摄像头到电脑的方法
  • 多模态AI的企业应用场景:视觉+语言模型的商业价值挖掘
  • unix/linux source 命令,其基本属性、语法、操作、api
  • 华为深度学习面试手撕题:手写nn.Conv2d()函数
  • 2023年电赛C题——电感电容测量装置
  • Go语言字符串类型详解
  • 计算机网络第1章(下):网络性能指标与分层模型全面解析
  • 计算机网络第1章(上):网络组成与三种交换方式全解析
  • 清理 pycharm 无效解释器
  • GraphQL 入门篇:基础查询语法
  • 麦克风和电脑内播放声音实时识别转文字软件FunASR整合包V5下载
  • 科技修真的解决方案
  • 网页前端开发(基础进阶2)
  • 基于 Flickr30k-Entities 数据集 的 Phrase Localization
  • 【中国企业数字化转型之路】企业的资源投入与数字化转型的产出效益平衡探索(上篇)
  • ps填充图层
  • linux驱动开发(1)-内核模块
  • seo顾问是什么/seo培训学院
  • 做队徽的网站/软文代写新闻稿
  • 手机怎么做自己的网站/如何推销自己的产品
  • 雁塔区住房和城乡建设局网站/重庆整站seo
  • 优化网站设计有哪些方法/xp优化大师
  • 沈阳网站前端/百度做广告多少钱