獲取View組件寬度以及ViewTreeObserver

来源:https://www.cnblogs.com/ganchuanpu/archive/2018/02/18/8452698.html
-Advertisement-
Play Games

View寬高測量方法: 測量方法有三種,如下: 1)(直接在onCreate()執行) 2)2和3都是在onCreate()調用完後回調拿到組件的寬高 3) 註意:方法一比其他方法多一次onMeasure計算,方法二的回調函數會被多次調用。 轉自http://blog.csdn.net/johnny ...


View寬高測量方法:

測量方法有三種,如下:

1)(直接在onCreate()執行)

int w = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);  
int h = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);  
imageView.measure(w, h);  
int height =imageView.getMeasuredHeight();  
int width =imageView.getMeasuredWidth();  
textView.append("\n"+height+","+width);

2)2和3都是在onCreate()調用完後回調拿到組件的寬高

ViewTreeObserver vto = imageView.getViewTreeObserver();  
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {  
    public boolean onPreDraw() {  
        int height = imageView.getMeasuredHeight();  
        int width = imageView.getMeasuredWidth();  
        textView.append("\n"+height+","+width);  
        return true;  
    }  
});

3)

ViewTreeObserver vto2 = imageView.getViewTreeObserver();    
vto2.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {  
    @Override    
    public void onGlobalLayout() {  
        imageView.getViewTreeObserver().removeGlobalOnLayoutListener(this);    
        textView.append("\n\n"+imageView.getHeight()+","+imageView.getWidth());  
    }    
});

註意:方法一比其他方法多一次onMeasure計算,方法二的回調函數會被多次調用。

轉自http://blog.csdn.net/johnny901114/article/details/7839512

ViewTreeObserver

一、結構

public final class ViewTreeObserver extends Object
    java.lang.Object
         android.view.ViewTreeObserver

二、概述

    這是一個註冊監聽視圖樹的觀察者(observer),在視圖樹種全局事件改變時得到通知。這個全局事件不僅還包括整個樹的佈局,從繪畫過程開始,觸摸模式的改變等。ViewTreeObserver不能夠被應用程式實例化,因為它是由視圖提供,參照getViewTreeObserver()以查看更多信息。

三、內部類

interface  ViewTreeObserver.OnGlobalFocusChangeListener         
//當在一個視圖樹中的焦點狀態發生改變時,所要調用的回調函數的介面類
 
interface  ViewTreeObserver.OnGlobalLayoutListener
//當在一個視圖樹中全局佈局發生改變或者視圖樹中的某個視圖的可視狀態發生改變時,所要調用的回調函數的介面類
 
interface  ViewTreeObserver.OnPreDrawListener
//當一個視圖樹將要繪製時,所要調用的回調函數的介面類
 
interface  ViewTreeObserver.OnScrollChangedListener
//當一個視圖樹中的一些組件發生滾動時,所要調用的回調函數的介面類
 
interface  ViewTreeObserver.OnTouchModeChangeListener
//當一個視圖樹的觸摸模式發生改變時,所要調用的回調函數的介面類

四、公共方法

/**註冊一個回調函數,當在一個視圖樹中的焦點狀態發生改變時調用這個回調函數。
 * 參數 listener    將要被添加的回調函數
 *異常 IllegalStateException       如果isAlive() 返回false
*/
public void addOnGlobalFocusChangeListener (ViewTreeObserver.OnGlobalFocusChangeListener listener)
     
 
/**註冊一個回調函數,當在一個視圖樹中全局佈局發生改變或者視圖樹中的某個視圖的可視狀態發生改變時調用這個回調函數。
 *參數 listener    將要被添加的回調函數
 *異常 IllegalStateException       如果isAlive() 返回false
*/
public void addOnGlobalLayoutListener (ViewTreeObserver.OnGlobalLayoutListener listener)
  
 
  
/**註冊一個回調函數,當一個視圖樹將要繪製時調用這個回調函數。
 *參數 listener    將要被添加的回調函數
 *異常 IllegalStateException       如果isAlive() 返回false
*/
 public void addOnPreDrawListener (ViewTreeObserver.OnPreDrawListener listener)
 
    
/**註冊一個回調函數,當一個視圖發生滾動時調用這個回調函數。
  *參數 listener    將要被添加的回調函數
 *異常 IllegalStateException       如果isAlive() 返回false
*/
public void addOnScrollChangedListener (ViewTreeObserver.OnScrollChangedListener listener)  
 
 
/**註冊一個回調函數,當一個觸摸模式發生改變時調用這個回調函數。
  *參數 listener    將要被添加的回調函數
  *異常 IllegalStateException       如果isAlive() 返回false
*/
public void addOnTouchModeChangeListener (ViewTreeObserver.OnTouchModeChangeListener listener)
 
  
//當整個佈局發生改變時通知相應的註冊監聽器。如果你強制對視圖佈局或者在一個沒有附加到一個視窗的視圖的層次結構或者在GONE狀態下,它可以被手動的調用
public final void dispatchOnGlobalLayout ()
    
/**當一個視圖樹將要繪製時通知相應的註冊監聽器。如果這個監聽器返回true,則這個繪製將被取消並重新計劃。如果你強制對視圖佈局或者在一個沒有附加到一個視窗的視圖的層次結構或者在一個GONE狀態下,它可以被手動的調用
 *返回值  當前繪製能夠取消並重新計劃則返回true,否則返回false。
*/
public final boolean dispatchOnPreDraw ()
 
/**指示當前的ViewTreeObserver是否可用(alive)。當observer不可用時,任何方法的調用(除了這個方法)都將拋出一個異常。如果一個應用程式保持和ViewTreeObserver一個歷時較長的引用,它應該總是需要在調用別的方法之前去檢測這個方法的返回值。
 *返回值 但這個對象可用則返回true,否則返回false   
*/
public boolean isAlive ()
    
     
/**移除之前已經註冊的全局佈局回調函數。
  *參數 victim 將要被移除的回調函數
  *異常 IllegalStateException       如果isAlive() 返回false   
*/
public void removeGlobalOnLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim)
  
/**移除之前已經註冊的焦點改變回調函數。
 *參數 victim 將要被移除的回調函數
 *異常 IllegalStateException       如果isAlive() 返回false 
*/
public void removeOnGlobalFocusChangeListener (ViewTreeObserver.OnGlobalFocusChangeListener victim)
  
/**移除之前已經註冊的預繪製回調函數。
 *參數 victim 將要被移除的回調函數
  *異常 IllegalStateException       如果isAlive() 返回false  
*/
public void removeOnPreDrawListener (ViewTreeObserver.OnPreDrawListener victim)
  
/**移除之前已經註冊的滾動改變回調函數。
 *參數 victim 將要被移除的回調函數
 *異常 IllegalStateException       如果isAlive() 返回false 
*/
public void removeOnScrollChangedListener (ViewTreeObserver.OnScrollChangedListener victim)
 
/**移除之前已經註冊的觸摸模式改變回調函數
 *參數 victim 將要被移除的回調函數
 *異常  IllegalStateException       如果isAlive() 返回false
*/
public void removeOnTouchModeChangeListener (ViewTreeObserver.OnTouchModeChangeListener victim)

五、代碼示例


1、創建監聽器

private final ViewTreeObserver.OnGlobalLayoutListener mGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
      int width = -1;
      int height = -1;
      
      try {
        width = getActivity().getWindow().getDecorView().getWidth();
        height = getActivity().getWindow().getDecorView().getHeight();
      } catch (Exception e) {
        // called too early. so, just skip.
      }
      
      if (width != -1 && mGlobalLayoutWidth != width) {//只有當尺寸真正有了數值,即已經確定了,更新UI才有意義
        mGlobalLayoutWidth = width;
        updateUI();
      } else if (height != -1 && mGlobalLayoutHeight != height) {
        mGlobalLayoutHeight = height;                
    updateUI();
 } } };

2、一般在onCreate或onCreateView中註冊監聽器

mViewTreeObserver = getActivity().getWindow().getDecorView().getViewTreeObserver();
mViewTreeObserver.addOnGlobalLayoutListener(mGlobalLayoutListener);

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 今天是大年初二,都去走親戚了吧,享受一下這難得的能和親友相聚的時光。而我就不一樣了,今天一回到家就又開始瞎折騰了,哈哈哈。 問題背景 最近花了點時間用 ASP.NET Core 2 寫了個個人博客,中間出了好多問題,過程彎彎曲曲的,但好歹最後還是完成部署在阿裡雲上了。這幾天閑的沒事看 .NET Co ...
  • 先說一下dos命令在很多情況下的共有特性 1.大小寫一樣,如dir和DIR 2.盤符後不加目錄時,像”dir E:“和”dir E:\“沒什麼區別 3.使用形如"cd/?"的格式可以查看幫助信息 4.Ctrl+C可以退出 5.按F7查看執行過的命令 6.使用滑鼠上下鍵回看上一次執行的命令 ***** ...
  • 在數據傳輸前,SSH會對需要傳輸的數據進行加密,保證會話安全與會話中傳輸數據的安全,SSH客戶端還包含一個遠程拷貝scp。 1、SSH的結構 SSH服務由服務端軟體(openssh)和客戶端(SSH、SecureCRT、Xshell)組成,SSH預設使用22埠,SSH服務端是一個守護進程,在後臺時 ...
  • RT ...
  • 這個文件描述系統中各種文件系統的信息。一般而言,應用程式僅讀取這個文件,而不對它進行寫操作。對它的維護是系統管理員的工作。 ...
  • 本節介紹: 表結構操作 創建數據表、 查看數據表和查看欄位、 修改數據表結構 刪除數據表 欄位操作 新增欄位、 修改欄位數據類型、位置或屬性、 重命名欄位 刪除欄位 首發時間:2018-02-18 21:31 表結構操作 創建數據表: 語法 : create table [if not exists... ...
  • Android安卓Die With Me不限電量破解版出爐,初二學生就能做到,你為什麼不能? ...
  • 轉載請註明來源。 加入新特性: 對話框,NumberPicker,專項訓練入口界面,新兵、文職人員專欄,自動更新。 總結問題: 1. startActivityForResult(Intent intent,int requestCode)中requestCode要是自然數,否則返回後不會調用onA ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...