(面試)獲取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);}});
    }
    

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/82231.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/82231.shtml
英文地址,請注明出處:http://en.pswp.cn/web/82231.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

PostgreSQL pgrowlocks 擴展

PostgreSQL pgrowlocks 擴展 pgrowlocks 是 PostgreSQL 的一個系統擴展,用于顯示表中行級鎖定信息。這個擴展特別適合診斷鎖爭用問題和性能調優。 一、擴展安裝與啟用 1. 安裝擴展 -- 使用超級用戶安裝 CREATE EXTENSION pgrowlocks;2. 驗證安裝 -- 查看擴展是…

JavaSE知識總結 ~個人筆記以及不斷思考~持續更新

目錄 字符串常量池 如果是創建對象還會嗎? Integer也是在字串常量池中復用? 字符串拼接 為什么String是不可變的? String的不可變性是怎么做的? 外部代碼不能創建對象? 構造方法不是私有的嗎? 怎么…

使用HTTPS進行傳輸加密

文章目錄 說明示例(公網上的公開web)安裝SSL證書Certbot 的 Webroot 模式 和 Standalone 模式的區別**Webroot 模式****Standalone 模式** 技術對比表Node.js 場景下的最佳實踐推薦方案:**Webroot 模式**Standalone 模式應急使用:…

驅動開發(2)|魯班貓rk3568簡單GPIO波形操控

上篇文章寫了如何下載內核源碼、編譯源碼的詳細步驟,以及一個簡單的官方demo編譯,今天分享一下如何根據板子的引腳寫自己控制GPIO進行高低電平反轉。 想要控制GPIO之前要學會看自己的引腳分布圖,我用的是魯班貓RK3568,引腳分布圖如…

ArcGIS Pro 3.4 二次開發 - 布局

環境:ArcGIS Pro SDK 3.4 + .NET 8 文章目錄 布局1 布局工程項1.1 引用布局工程項及其關聯的布局1.2 在新視圖中打開布局工程項1.3 激活已打開的布局視圖1.4 引用活動布局視圖1.5 將 pagx 導入工程1.6 移除布局工程項1.7 創建并打開一個新的基本布局1.8 使用修改后的CIM創建新…

OpenCV 圖像像素的算術操作

一、知識點 1、operator (1)、MatExpr operator (const Mat & a, const Mat & b); a、a和b的行數、列數、通道數得相同。 b、a和b的每個像素的每個通道值分別相加。 (2)、MatExpr operator (const Mat & a, const Scalar & s); a、若a…

音視頻中的復用器

🎬 什么是復用器(Muxer)? 復用器(muxer)是負責把音頻、視頻、字幕等多個媒體流打包(封裝)成一個單一的文件格式的組件。 💡 舉個形象的例子: 假設你有兩樣東…

數據庫安全性

一、計算機安全性概論 (一)核心概念 數據庫安全性:保護數據庫免受非法使用導致的數據泄露、更改或破壞,是衡量數據庫系統的關鍵指標之一,與計算機系統安全性相互關聯。計算機系統安全性:通過各類安全保護…

【Linux網絡編程】網絡層IP協議

目錄 IP協議的協議頭格式 網段劃分 特殊的IP地址 IP地址的數量限制 私有IP地址和公網IP地址 路由 IP協議的協議頭格式 4位版本號 :指定IP協議的版本,對于IPv4,版本號就是4。 4位首部長度:表名IP協議報頭的長度,單…

“候選對話鏈”(Candidate Dialogue Chain)概念

目錄 一、定義與形式 二、生成過程詳解 1. 語言模型生成(LLM-Based Generation) 2. 知識圖譜支持(KG-Augmented Generation) 3. 策略調控(Policy-Driven Planning) 三、候選對話鏈的屬性 四、候選對…

Unity中的JsonManager

1.具體代碼 先貼代碼 using LitJson; using System.IO; using UnityEngine;/// <summary> /// 序列化和反序列化Json時 使用的是哪種方案 有兩種 JsonUtility 不能直接序列化字典 ligJson可以序列化字典 /// </summary> public enum JsonType {JsonUtilit…

50天50個小項目 (Vue3 + Tailwindcss V4) ? | Split Landing Page(拆分展示頁)

&#x1f4c5; 我們繼續 50 個小項目挑戰&#xff01;—— SplitLandingPage 組件 倉庫地址&#xff1a;https://github.com/SunACong/50-vue-projects 項目預覽地址&#xff1a;https://50-vue-projects.vercel.app/ 在這篇文章中&#xff0c;我們將實現一個交互式的左右面板…

機器學習-ROC曲線?? 和 ??AUC指標

1. 什么是ROC曲線&#xff1f;?? ROC&#xff08;Receiver Operating Characteristic&#xff0c;受試者工作特征曲線&#xff09;是用來評估??分類模型性能??的一種方法&#xff0c;特別是針對??二分類問題??&#xff08;比如“患病”或“健康”&#xff09;。 ?…

Docker容器創建Redis主從集群

利用虛擬機中的三個Docker容器創建主從集群&#xff0c;容器信息&#xff1a; 容器名角色IP映射端口r1master192.168.150.1017001r2slave192.168.150.1017002r3slave192.168.150.1017003 啟動多個redis實例 新建一個docker-compose文件來構建主從集群&#xff1a; 文件內容&…

手寫ArrayList和LinkedList

項目倉庫&#xff1a;https://gitee.com/bossDuy/hand-tear-collection-series 基于b站up生生大佬&#xff1a;https://www.bilibili.com/video/BV1Kp5tzGEc5/?spm_id_from333.788.videopod.sections&vd_source4cda4baec795c32b16ddd661bb9ce865 LinkedList package com…

每日c/c++題 備戰藍橋杯(Cantor 表)

Cantor 表的探究與實現 在數學中&#xff0c;有理數的可枚舉性是一個令人驚嘆的結論。今天&#xff0c;就讓我們一起深入探討這個經典問題&#xff0c;并分享一段精心編寫的代碼&#xff0c;揭開這一數學奧秘的神秘面紗。 問題背景 在 19 世紀末&#xff0c;偉大的數學家康托…

解決idea與springboot版本問題

遇到以下問題&#xff1a; 1、springboot3.2.0與jdk1.8 提示這個包org.springframework.web.bind.annotation不存在&#xff0c;但是pom已經引入了spring-boot-starter-web 2、Error:Cannot determine path to tools.jar library for 17 (D:/jdk17) 3、Error:(3, 28) java: …

Notepad++找回自動暫存的文件

場景&#xff1a; 當你沒有保存就退出Notepad&#xff0c;下次進來Notepad會自動把你上次編輯的內容顯示出來&#xff0c;以便你繼續編輯。除非你手動關掉當前頁面&#xff0c;這樣Notepad就會刪除掉自動保存的內容。 問題&#xff1a; Notepad會將自動保存的文件地址,打開Note…

yolov12畢設前置知識準備 1

1 什么是目標檢測呢&#xff1f; 目標檢測&#xff08;Object Detection&#xff09;主要用于識別圖像或視頻中特定類型物體的位置&#xff0c;并標注其類別。 簡單來說&#xff0c;就是讓計算機像人類一樣 “看懂” 圖像內容&#xff0c;不僅能識別出物體&#xff08;如人、…

unix/linux source 命令,其內部結構機制

要理解 source (或 .) 命令的內部結構機制,我們需要戴上“操作系統”和“解釋器設計”的眼鏡,深入到 Shell 如何管理其狀態以及如何執行命令的層面。 雖然我們無法直接看到 Shell 內部的 C 代碼(除非我們去閱讀 Bash 或 Zsh 的源碼),但我們可以基于其行為和操作系統的原理…