[Android] 關於Window Overscan

來源:互聯網
上載者:User

標籤:android   style   blog   http   io   color   ar   java   for   

Overscan的概念

對於電視機,有一個Overscan的概念,如,所謂Overscan地區,就是電視機螢幕四周某些不可見的地區,這是電視機的特性。並且,Overscan的具體值也沒有一個明確的標準,不同的電視機廠家的Overscan的值也各不相同。

而對於普通的LCD,由於並沒有Overscan的概念,所以設想,將一塊沒有設定Overscan的Framebuffer顯示到有Overscan的電視機上,必定四周有一部分Overscan的地區被切除到無法顯示出來。

所以在Android 4.3以後,Google加入了Overscan的API,並且提供了wm工具,可以讓使用者設定Overscan的值,來滿足不同的電視機。

中,包含了Overscan的整個地區我們稱之為Overscan Screen;

去處Overscan地區後稱之為 Unrestricted Area,由綠色和紫色地區組成,綠色地區用於顯示Status Bar和Navigation Bar;

剩下的紫色地區為 Restricted Area,這裡顯示的為mContentFrame。

 

關於WM Tool

Android 4.3之後,加入了Overscan的概念,並且提供了wm工具來設定Overscan的值。(參考git commit:c652de8141f5b8e3c6bcf8916842b6e106413b1a)

代碼調用流程:

簡單來講就是,當我們設定了Overscan值後,WindowManagerService、PhoneWindowManager等會對當前顯示的View的參數做重新計算,將計算完的數值會傳給View,讓其重新Layout。

關於IME的Bug

一個存在的Bug是,當我們設定完Overscan後,google 的虛擬鍵盤並沒有跟著Overscan的變化而縮放,虛擬鍵盤的一部分會被Overscan的地區遮擋無法顯示。

原因:虛擬鍵盤是通過Canvas繪製到螢幕上,而虛擬鍵盤上每一個組件的大小是根據螢幕的實際像素和深度來計算的,代碼:

packages/inputmethods/LatinIME/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java

final Resources res = mThemeContext.getResources();builder.setScreenGeometry(res.getInteger(R.integer.config_device_form_factor),     res.getConfiguration().orientation, res.getDisplayMetrics().widthPixels);

 

所以,Keyboard會撐滿Overscan Screen,而我們期望的是讓Keyboard撐滿Unrestricted Area,故我們做以下修改:

1. 讓Display.java中的getWidth方法返回除去Overscan長度後的值。

frameworks/base/core/java/android/view/Display.java

     public int getWidth() {    synchronized (this) {      updateCachedAppSizeIfNeededLocked();      updateDisplayInfoLocked();      return mCachedAppWidthCompat - mDisplayInfo.overscanLeft - mDisplayInfo.overscanRight ;         }     }

 

 

2. 在LatinIME中添加mWidth變數,用於存放Keyboard寬度。

packages/inputmethods/LatinIME/java/src/com/android/inputmethod/latin/SettingsValues.java

  public static int mWidth;    public SettingsValues(final SharedPreferences prefs, final InputAttributes inputAttributes, final Context context) {    if(mWidth == 0){      mWidth = res.getDisplayMetrics().widthPixels;    }  }

3. 每次虛擬鍵盤彈出前,比較當前的Width和設定Width是否相同,不同和替代,並重新初始化Keyboard。注,此處InputManagerService的getMaxWidth方法最終會調用Step1的getWidth方法。

packages/inputmethods/LatinIME/java/src/com/android/inputmethod/latin/LatinIME.java

    private void onStartInputViewInternal(final EditorInfo editorInfo, final boolean restarting) {        super.onStartInputView(editorInfo, restarting);// Deal with overscan area        if(mCurrentSettings.mWidth != getMaxWidth()){            mCurrentSettings.mWidth = getMaxWidth();            loadKeyboard();        } }       

 

4.將初始化鍵盤寬度的值從res.getDisplayMetrics().widthPixels改成settingsValues.mWidth。

packages/inputmethods/LatinIME/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java

    public void loadKeyboard(EditorInfo editorInfo, SettingsValues settingsValues) {        final KeyboardLayoutSet.Builder builder = new KeyboardLayoutSet.Builder(                mThemeContext, editorInfo);        final Resources res = mThemeContext.getResources();//      builder.setScreenGeometry(res.getInteger(R.integer.config_device_form_factor),//              res.getConfiguration().orientation, res.getDisplayMetrics().widthPixels);        builder.setScreenGeometry(res.getInteger(R.integer.config_device_form_factor),                res.getConfiguration().orientation, settingsValues.mWidth);    }
 參考

http://blog.csdn.net/cjj7905150/article/details/17888377

 

[Android] 關於Window Overscan

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.