柚子快報激活碼778899分享:Android 窗口模糊處理
柚子快報激活碼778899分享:Android 窗口模糊處理
在 Android 12 中,我們提供了一些用于實現(xiàn)窗口模糊處理效果(例如背景模糊處理和模糊處理后方屏幕)的公共 API。
窗口模糊處理或跨窗口模糊處理用于模糊處理給定窗口后方的屏幕。有兩種窗口模糊處理方式,可用于實現(xiàn)不同的視覺效果:
背景模糊處理:可用于創(chuàng)建具有模糊背景的窗口,創(chuàng)造出磨砂玻璃效果。 模糊處理后方屏幕:可用于模糊處理(對話框)窗口后方的整個屏幕,創(chuàng)造出景深效果。
這兩種效果可以單獨使用,也可以組合使用,如下圖所示:
a b c
圖 1.?僅背景模糊處理 (a)、僅模糊處理后方屏幕 (b)、背景模糊處理和模糊處理后方屏幕 (c)
窗口模糊處理功能可以跨窗口使用,這意味著當窗口背后有其他應用時,該功能同樣可以發(fā)揮作用。此效果與模糊處理渲染效果不同,后者會對同一窗口內部的內容進行模糊處理。窗口模糊處理對于對話框、底部動作條和其他浮動窗口非常有用。
注意:跨窗口模糊處理是一項非常耗費資源的操作,僅在部分設備上受支持。如需了解詳情,請參閱在應用中使用窗口模糊處理的準則部分。
實現(xiàn)
應用開發(fā)者
為了創(chuàng)建模糊處理效果,應用開發(fā)者必須提供一個模糊處理半徑。模糊處理半徑用于控制模糊處理的密度,即半徑越高,模糊處理的密度越大。0 像素的模糊處理表示不進行模糊處理。對于模糊處理后方屏幕,半徑達到 20 像素,即可實現(xiàn)良好的景深效果;對于背景模糊處理,半徑達到 80 像素,即可實現(xiàn)良好的磨砂玻璃效果。應避免使用超過 150 像素的模糊處理半徑,因為這會嚴重影響性能。
注意:模糊處理半徑越高,GPU 進行顏色采樣的區(qū)域就越大,從而使操作的性能消耗越大。
為了達到理想的模糊處理效果并提高可辨別性,請選擇與半透明顏色層互補的模糊處理半徑值。
背景模糊處理
對浮動窗口使用背景模糊處理可實現(xiàn)窗口背景效果,這是底層內容的模糊處理圖像。如需為窗口添加模糊處理的背景,請執(zhí)行以下操作:
調用?Window#setBackgroundBlurRadius(int)?設置背景模糊處理半徑。或者,在窗口主題中設置?R.attr.windowBackgroundBlurRadius。 將?R.attr.windowIsTranslucent?設為 true,使窗口變?yōu)榘胪该?。模糊處理是在窗?Surface 下面繪制的,因此窗口必須是半透明的,才能顯示出模糊處理效果。 (可選)調用?Window#setBackgroundDrawableResource(int)?添加具有半透明顏色的矩形窗口背景可繪制對象。或者,在窗口主題中設置?R.attr.windowBackground。 對于具有圓角的窗口,可通過將具有圓角的?ShapeDrawable?設為窗口背景可繪制對象來確定模糊處理區(qū)域的圓角。 處理啟用和停用模糊處理的狀態(tài)。如需了解詳情,請參閱在應用中使用窗口模糊處理的準則部分。
模糊處理后方屏幕
“模糊處理后方屏幕”會對窗口后方的整個屏幕進行模糊處理。這種效果通過對窗口后方屏幕上的所有內容進行模糊處理,將用戶的注意力引導到窗口內容上。
如需對窗口后方的內容進行模糊處理,請按以下步驟操作:
將?FLAG_BLUR_BEHIND?添加至窗口標志,以啟用“模糊處理后方屏幕”?;蛘?,在窗口主題中設置?R.attr.windowBlurBehindEnabled。 調用?WindowManager.LayoutParams#setBlurBehindRadius?設置“模糊處理后方屏幕”的半徑?;蛘?,在窗口主題中設置?R.attr.windowBlurBehindRadius。 (可選)選擇一個互補的暗度。 處理啟用和停用模糊處理的狀態(tài)。如需了解詳情,請參閱在應用中使用窗口模糊處理的準則部分。
在應用中使用窗口模糊處理的準則
是否支持窗口模糊處理取決于以下因素:
Android 版本:窗口模糊處理 API 僅在 Android 12 及更高版本上可用。請檢查設備 SDK 確定 Android 版本。 顯卡性能:GPU 性能較低的設備可能會選擇不支持窗口模糊處理。 系統(tǒng)狀態(tài):系統(tǒng)服務器可能會在運行時暫時停用窗口模糊處理,例如在省電模式下、在播放特定類型的視頻內容時,或開發(fā)者覆蓋了相關設置時。
為了使應用與不同的 Android 版本、設備和系統(tǒng)狀態(tài)兼容,請遵循以下準則:
通過?WindowManager#addCrossWindowBlurEnabledListener?添加監(jiān)聽器,以便在啟用或停用窗口模糊處理時收到通知。此外,還可以使用?WindowManager#isCrossWindowBlurEnabled?查詢當前是否啟用了窗口模糊處理。 實現(xiàn)兩個版本的窗口背景,以適應啟用或停用窗口模糊處理的狀態(tài)。 啟用模糊處理后,窗口背景應該是半透明的,以顯示出模糊處理效果。如果在此狀態(tài)下停用模糊處理,窗口內容將與底層窗口的內容直接重疊,重疊后的窗口將不易辨認。為避免出現(xiàn)這種效果,在停用窗口模糊處理時,請按如下方式調整應用的界面:
對于背景模糊處理,請?zhí)岣叽翱诒尘翱衫L制對象的 Alpha 值,以降低其透明度。 對于模糊處理后方屏幕,請?zhí)砑右粋€暗度更高的暗層。
模糊處理后方屏幕和背景模糊處理的示例
本部分提供了一個同時使用“模糊處理后方屏幕”和“背景模糊處理”的 activity 的實際示例。
以下?MainActivity.java?示例是一個對話框,其“模糊處理后方屏幕”半徑為 20 像素,“背景模糊處理”半徑為 80 像素。該對話框具有圓角(在窗口背景可繪制對象的 xml 中定義),可以正確適應不同的 Android 版本、不同的設備(可能不支持窗口模糊處理)以及運行時啟用或停用模糊處理的變化。此外,該對話框還通過調整窗口背景可繪制對象 Alpha 值和窗口暗度,確保在上述任何條件下對話框內容都能清晰辨認。
public class MainActivity extends Activity {
? ? private final int mBackgroundBlurRadius = 80;
? ? private final int mBlurBehindRadius = 20;
? ? // We set a different dim amount depending on whether window blur is enabled or disabled
? ? private final float mDimAmountWithBlur = 0.1f;
? ? private final float mDimAmountNoBlur = 0.4f;
? ? // We set a different alpha depending on whether window blur is enabled or disabled
? ? private final int mWindowBackgroundAlphaWithBlur = 170;
? ? private final int mWindowBackgroundAlphaNoBlur = 255;
? ? // Use a rectangular shape drawable for the window background. The outline of this drawable
? ? // dictates the shape and rounded corners for the window background blur area.
? ? private Drawable mWindowBackgroundDrawable;
? ? @Override
? ? protected void onCreate(Bundle savedInstanceState) {
? ? ? ? super.onCreate(savedInstanceState);
? ? ? ? setContentView(R.layout.activity_main);
? ? ? ? mWindowBackgroundDrawable = getDrawable(R.drawable.window_background);
? ? ? ? getWindow().setBackgroundDrawable(mWindowBackgroundDrawable);
? ? ? ? if (buildIsAtLeastS()) {
? ? ? ? ? ? // Enable blur behind. This can also be done in xml with R.attr#windowBlurBehindEnabled
? ? ? ? ? ? getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
? ? ? ? ? ? // Register a listener to adjust window UI whenever window blurs are enabled/disabled
? ? ? ? ? ? setupWindowBlurListener();
? ? ? ? } else {
? ? ? ? ? ? // Window blurs are not available prior to Android S
? ? ? ? ? ? updateWindowForBlurs(false /* blursEnabled */);
? ? ? ? }
? ? ? ? // Enable dim. This can also be done in xml, see R.attr#backgroundDimEnabled
? ? ? ? getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
? ? }
? ? /**
? ? ?* Set up a window blur listener.
? ? ?*
? ? ?* Window blurs might be disabled at runtime in response to user preferences or system states
? ? ?* (e.g. battery saving mode). WindowManager#addCrossWindowBlurEnabledListener allows to
? ? ?* listen for when that happens. In that callback we adjust the UI to account for the
? ? ?* added/missing window blurs.
? ? ?*
? ? ?* For the window background blur we adjust the window background drawable alpha:
? ? ?* ? ? - lower when window blurs are enabled to make the blur visible through the window
? ? ?* ? ? ? background drawable
? ? ?* ? ? - higher when window blurs are disabled to ensure that the window contents are readable
? ? ?*
? ? ?* For window blur behind we adjust the dim amount:
? ? ?* ? ? - higher when window blurs are disabled - the dim creates a depth of field effect,
? ? ?* ? ? ? bringing the user's attention to the dialog window
? ? ?* ? ? - lower when window blurs are enabled - no need for a high alpha, the blur behind is
? ? ?* ? ? ? enough to create a depth of field effect
? ? ?*/
? ? @RequiresApi(api = Build.VERSION_CODES.S)
? ? private void setupWindowBlurListener() {
? ? ? ? Consumer
? ? ? ? getWindow().getDecorView().addOnAttachStateChangeListener(
? ? ? ? ? ? ? ? new View.OnAttachStateChangeListener() {
? ? ? ? ? ? ? ? ? ? @Override
? ? ? ? ? ? ? ? ? ? public void onViewAttachedToWindow(View v) {
? ? ? ? ? ? ? ? ? ? ? ? getWindowManager().addCrossWindowBlurEnabledListener(
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? windowBlurEnabledListener);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? @Override
? ? ? ? ? ? ? ? ? ? public void onViewDetachedFromWindow(View v) {
? ? ? ? ? ? ? ? ? ? ? ? getWindowManager().removeCrossWindowBlurEnabledListener(
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? windowBlurEnabledListener);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? });
? ? }
? ? private void updateWindowForBlurs(boolean blursEnabled) {
? ? ? ? mWindowBackgroundDrawable.setAlpha(blursEnabled && mBackgroundBlurRadius > 0 ?
? ? ? ? ? ? ? ? mWindowBackgroundAlphaWithBlur : mWindowBackgroundAlphaNoBlur);
? ? ? ? getWindow().setDimAmount(blursEnabled && mBlurBehindRadius > 0 ?
? ? ? ? ? ? ? ? mDimAmountWithBlur : mDimAmountNoBlur);
? ? ? ? if (buildIsAtLeastS()) {
? ? ? ? ? ? // Set the window background blur and blur behind radii
? ? ? ? ? ? getWindow().setBackgroundBlurRadius(mBackgroundBlurRadius);
? ? ? ? ? ? getWindow().getAttributes().setBlurBehindRadius(mBlurBehindRadius);
? ? ? ? ? ? getWindow().setAttributes(getWindow().getAttributes());
? ? ? ? }
? ? }
? ? private static boolean buildIsAtLeastS() {
? ? ? ? return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S;
? ? }
}
為了為窗口創(chuàng)建圓角,我們在?res/drawable/window_background.xml?中將窗口背景定義為具有半徑為 20 dp 的圓角的?ShapeDrawable,如下所示:
? ?
? ?
窗口模糊處理會對 activity 下方的窗口內容進行模糊處理。模糊處理后的圖像會顯示在此 activity 窗口“下方”,因此該 activity 窗口必須為半透明狀態(tài),才能顯示出模糊處理效果。為了將窗口設為半透明,我們在 activity 主題中設置?R.attr.windowIsTranslucent,如下所示:
原始設備制造商 (OEM) 與合作伙伴
如需在設備上啟用窗口模糊處理,OEM 需要聲明設備支持窗口模糊處理。
如需檢查設備是否支持窗口模糊處理,請執(zhí)行以下操作:
確保設備可以處理額外的 GPU 負載。低端設備可能無法處理額外的負載,這可能會導致幀丟失。請僅在 GPU 性能足夠強大的測試設備上啟用窗口模糊處理。 如果您有自定義渲染引擎,請確保您的渲染引擎實現(xiàn)了模糊處理邏輯。默認的 Android 12?渲染引擎會在?BlurFilter.cpp?中實現(xiàn)模糊處理邏輯。
確保設備可以支持窗口模糊處理后,請設置以下 Surface Flinger?sysprop:
PRODUCT_VENDOR_PROPERTIES += \
? ? ? ?ro.surface_flinger.supports_background_blur=1
驗證
如需驗證應用窗口在啟用模糊處理和停用模糊處理的狀態(tài)之間切換時能否正確處理,請按以下步驟操作:
打開支持模糊處理的界面。 通過開啟和關閉窗口模糊處理來啟用或停用窗口模糊處理。 驗證窗口界面是否按預期在模糊處理和非模糊處理狀態(tài)之間轉換。
開啟和關閉窗口模糊處理
如需測試窗口界面的窗口模糊處理呈現(xiàn)效果,請使用以下方法之一啟用或停用模糊處理:
通過“開發(fā)者選項”操作: 設置 -> 系統(tǒng) -> 開發(fā)者選項 -> 硬件加速渲染 -> 允許窗口級模糊處理 注意:如果您在“設置”下找不到該選項,則表示您的設備不支持窗口模糊處理。 通過已取得 root 權限的設備上的終端操作: adb shell wm disable-blur 1 # 1 disables window blurs, 0 allows them
注意:只有在支持窗口模糊處理的設備上才能夠啟用。
如需檢查您的 Android 12 及更高版本設備是否支持窗口模糊處理,以及當前是否啟用了窗口模糊處理,請在已取得 root 權限的設備上運行?adb shell wm disable-blur。
問題排查
在驗證期間,您可以參考以下內容進行問題排查。
未呈現(xiàn)模糊處理效果
確認目前是否啟用了模糊處理功能,以及硬件是否支持此功能。請參閱開啟和關閉窗口模糊處理。 請確保設置半透明的窗口背景顏色;不透明的窗口背景顏色會遮蓋模糊處理的區(qū)域。
測試設備不支持窗口模糊處理
在 Android 12 模擬器上測試您的應用。如需設置 Android 模擬器,請參閱設置 Android 模擬器。使用模擬器創(chuàng)建的任何 Android 虛擬設備都支持窗口模糊處理。
無圓角
設置窗口背景可繪制對象以定義圓角。此可繪制對象決定了模糊處理區(qū)域的輪廓。
更新開發(fā)者選項并不會啟用模糊處理功能
請檢查設備是否處于省電模式或是否正在使用多媒體隧道技術。在某些 TV 設備上,播放視頻時也可能會停用窗口模糊處理。
以全屏形式(而不是在窗口邊界內)繪制的背景模糊處理
請檢查?android:windowIsFloating,以確保窗口已標記為懸浮式。 請確保已設置窗口背景可繪制對象。此設置決定了模糊處理區(qū)域的輪廓。
來自監(jiān)聽器的更新內容不會應用到屏幕上
監(jiān)聽器更新內容可能會應用于舊窗口實例。請檢查窗口是否會被銷毀,并使用正確的監(jiān)聽器更新內容重新創(chuàng)建。
柚子快報激活碼778899分享:Android 窗口模糊處理
精彩文章
本文內容根據(jù)網絡資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。
轉載請注明,如有侵權,聯(lián)系刪除。