ב-Android 12, יש ממשקי API ציבוריים שמאפשרים להטמיע אפקטים של טשטוש חלונות, כמו טשטוש הרקע וטשטוש מאחורי החלון.
טשטוש חלונות, או טשטוש בין חלונות, משמש לטשטוש המסך מאחורי החלון הנתון. יש שני סוגים של טשטוש חלונות, שאפשר להשתמש בהם כדי ליצור אפקטים ויזואליים שונים:
טשטוש הרקע מאפשר ליצור חלונות עם רקע מטושטש, כך נוצר אפקט של זכוכית חלבית.
ההגדרה טשטוש מאחור מאפשרת לטשטש את כל המסך מאחורי חלון (דו-שיח), כדי ליצור אפקט של עומק שדה.
אפשר להשתמש בשני האפקטים בנפרד או לשלב ביניהם, כמו שרואים באיור הבא:
![]() a |
![]() b |
![]() c |
איור 1. טשטוש הרקע בלבד (א), טשטוש רק מאחוריכם (ב), טשטוש הרקע וטשטוש מאחוריכם (ג)
התכונה 'טשטוש החלון' פועלת בכל החלונות, כלומר היא פועלת גם אם יש אפליקציה אחרת מאחורי החלון. ההשפעה הזו שונה מאפקט הטשטוש של הרינדור, שמטשטש את התוכן בתוך אותו חלון. טשטוש החלון שימושי לתיבות דו-שיח, לגיליונות תחתונים ולחלונות צפים אחרים.
הטמעה
מפתחי אפליקציות
מפתחי אפליקציות צריכים לספק רדיוס טשטוש כדי ליצור אפקט טשטוש. רדיוס הטשטוש קובע את צפיפות הטשטוש. ככל שהרדיוס גדול יותר, הטשטוש צפוף יותר. טשטוש של 0 פיקסלים אומר שאין טשטוש. כדי ליצור טשטוש מאחורי האובייקט, רדיוס של 20 פיקסלים יוצר אפקט טוב של עומק שדה, ורדיוס של 80 פיקסלים יוצר אפקט טוב של זכוכית חלבית. מומלץ להימנע משימוש ברדיוסים של טשטוש שגדולים מ-150 פיקסלים, כי זה ישפיע באופן משמעותי על הביצועים.
כדי להשיג את אפקט הטשטוש הרצוי ולשפר את הקריאות, בוחרים ערך של רדיוס הטשטוש שמשלים שכבת צבע שקופה למחצה.
טשטוש הרקע
אתם יכולים להשתמש בטשטוש הרקע בחלונות צפים כדי ליצור אפקט של רקע חלון, שהוא תמונה מטושטשת של התוכן שמתחת. כדי להוסיף רקע מטושטש לחלון:
מתקשרים אל Window#setBackgroundBlurRadius(int) כדי להגדיר את רדיוס טשטוש הרקע. לחלופין, מגדירים את R.attr.windowBackgroundBlurRadius בעיצוב החלון.
מגדירים את R.attr.windowIsTranslucent לערך true כדי שהחלון יהיה שקוף. הטשטוש מצויר מתחת לפני השטח של החלון, ולכן החלון צריך להיות שקוף כדי שהטשטוש יהיה גלוי.
אופציונלי, אפשר לקרוא ל-Window#setBackgroundDrawableResource(int) כדי להוסיף רקע מלבני לחלון עם צבע שקוף למחצה. אפשרות נוספת היא להגדיר את R.attr.windowBackground בעיצוב החלון.
כדי להגדיר חלון עם פינות מעוגלות, צריך להגדיר ShapeDrawable עם פינות מעוגלות כ-drawable של רקע החלון.
טיפול במצבי טשטוש מופעל ומושבת. מידע נוסף זמין בקטע הנחיות לשימוש בטשטוש חלונות באפליקציות.
טשטוש הרקע
הטשטוש מאחורי החלון מטשטש את כל המסך מאחורי החלון. האפקט הזה משמש להפניית תשומת הלב של המשתמש לתוכן החלון על ידי טשטוש כל מה שמוצג במסך מאחורי החלון.
כדי לטשטש את התוכן שמאחורי החלון, פועלים לפי השלבים הבאים:
מוסיפים את
FLAG_BLUR_BEHIND
לדגלי החלון כדי להפעיל את הטשטוש מאחור. לחלופין, מגדירים את R.attr.windowBlurBehindEnabled בעיצוב החלון.מתקשרים אל
WindowManager.LayoutParams#setBlurBehindRadius
כדי להגדיר את רדיוס הטשטוש מאחוריכם. אפשר גם להגדיר את R.attr.windowBlurBehindRadius בעיצוב החלון.אפשר גם לבחור סכום עמעום משלים.
טיפול במצבי טשטוש מופעל ומושבת. מידע נוסף זמין בקטע הנחיות לשימוש בטשטוש חלונות באפליקציות.
הנחיות לשימוש בטשטוש חלונות באפליקציות
התמיכה בטשטוש החלונות תלויה בדברים הבאים:
גרסת Android: ממשקי ה-API של טשטוש החלונות זמינים רק ב-Android מגרסה 12 ומעלה. בודקים את ה-SDK של המכשיר כדי לראות איזו גרסת Android מותקנת בו.
ביצועים גרפיים: יכול להיות שבמכשירים עם GPU עם ביצועים נמוכים יותר לא תהיה תמיכה בטשטוש חלונות.
מצב המערכת: יכול להיות ששרת המערכת ישבית באופן זמני את טשטוש החלונות בזמן הריצה, למשל במהלך מצב חיסכון בסוללה, בזמן הפעלה של סוגים מסוימים של תוכן וידאו או בגלל ביטול ברירת מחדל של מפתח.
כדי שהאפליקציה תהיה תואמת לגרסאות, למכשירים ולמצבי מערכת שונים של Android, צריך לפעול לפי ההנחיות הבאות:
מוסיפים מאזין באמצעות WindowManager#addCrossWindowBlurEnabledListener, כדי לקבל התראה כשהטשטוש של החלון מופעל או מושבת. בנוסף, אפשר להשתמש ב-
WindowManager#isCrossWindowBlurEnabled
כדי לבדוק אם האפשרות 'טשטוש החלון' מופעלת כרגע.צריך להטמיע שתי גרסאות לרקע של החלון, כדי להתאים למצב המופעל או המושבת של טשטוש החלון.
כשטשטוש הרקע מופעל, הרקע של החלון צריך להיות שקוף כדי שהטשטוש יהיה גלוי. במצב הזה, כשהטשטוש מושבת, התוכן של החלון חופף ישירות לתוכן של החלון שמתחתיו, ולכן קשה יותר לקרוא את התוכן של החלון החופף. כדי למנוע את האפקט הזה, כשמשביתים את טשטוש החלון, צריך לשנות את ממשק המשתמש של האפליקציה באופן הבא:
כדי לטשטש את הרקע, מגדילים את ערך האלפא של הרקע של חלון הציור, כדי שיהיה אטום יותר.
כדי להוסיף טשטוש מאחורי האובייקט, מוסיפים שכבה עמומה עם ערך עמעום גבוה יותר.
דוגמה לטשטוש מאחורי האובייקט ולטשטוש הרקע
בקטע הזה מופיעה דוגמה לפעילות שבה נעשה שימוש גם בטשטוש מאחורי וגם בטשטוש הרקע.
בדוגמה הבאה של MainActivity.java
מוצג דו-שיח עם טשטוש ברקע ברדיוס של 20 פיקסלים וטשטוש ברקע ברדיוס של 80 פיקסלים. יש לו פינות מעוגלות, שמוגדרות ב-XML בפריט הגרפי של רקע החלון. הוא מטפל בצורה נכונה בגרסאות שונות של Android, במכשירים שונים (שלא תומכים בטשטוש חלונות) ובשינויים בהפעלה או בהשבתה של טשטוש בזמן ריצה. הוא מוודא שתוכן הדיאלוג קריא בכל אחד מהתנאים האלה על ידי התאמת השקיפות של הרקע של החלון והעמעום של החלון.
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<Boolean> windowBlurEnabledListener = this::updateWindowForBlurs;
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;
}
}
כדי ליצור פינות מעוגלות לחלון, מגדירים את הרקע של החלון ב-res/drawable/window_background.xml
כ-ShapeDrawable עם פינות מעוגלות ברדיוס של 20 dp באופן הבא:
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<corners android:radius="20dp"/>
<solid android:color="#AAAAAA"/>
</shape>
טשטוש חלון מטשטש את התוכן של החלון שמתחת לפעילות. התמונה המטושטשת מצוירת מתחת לחלון הפעילות הזה, ולכן חלון הפעילות צריך להיות שקוף כדי שהטשטוש יהיה גלוי. כדי להפוך את החלון לשקוף למחצה, מגדירים את R.attr.windowIsTranslucent בעיצוב של הפעילות באופן הבא:
<style name="Theme.BlurryDialog" parent="Theme.MaterialComponents.Dialog">
<item name="android:windowIsTranslucent">true</item>
</style>
יצרני ציוד מקורי (OEM) ושותפים
כדי להשתמש בהטשטוש של החלון במכשיר, יצרן הציוד המקורי צריך להצהיר שהמכשיר תומך בטשטוש של חלונות.
כדי לבדוק אם המכשיר תומך בטשטוש חלונות:
מוודאים שהמכשיר יכול להתמודד עם העומס הנוסף על ה-GPU. יכול להיות שמכשירים פשוטים יותר לא יוכלו להתמודד עם העומס הנוסף, מה שעלול לגרום להשמטת פריימים. הפעלת טשטוש החלונות רק במכשירים שנבדקו עם מספיק כוח GPU.
אם יש לכם מנוע עיבוד בהתאמה אישית, צריך לוודא שמנוע העיבוד מיישם את הלוגיקה של הטשטוש. מנוע העיבוד של Android 12 כברירת מחדל מטמיע את לוגיקת הטשטוש ב-
BlurFilter.cpp
.
אחרי שמוודאים שהמכשיר יכול לתמוך בטשטוש חלונות, מגדירים את sysprop
Surface Flinger באופן הבא:
PRODUCT_VENDOR_PROPERTIES += \
ro.surface_flinger.supports_background_blur=1
אימות
כדי לוודא שחלון האפליקציה מטפל בצורה נכונה במעבר בין מצב שבו הטשטוש מופעל לבין מצב שבו הטשטוש מושבת, פועלים לפי השלבים הבאים:
פותחים את ממשק המשתמש שבו רוצים להשתמש בטשטוש.
כדי להפעיל או להשבית את טשטוש החלונות, מפעילים או משביתים את האפשרות 'טשטוש חלונות'.
מוודאים שממשק המשתמש של החלון משתנה למצב מטושטש וממצב מטושטש כמו שצריך.
הפעלה והשבתה של טשטוש החלון
כדי לבדוק איך ממשק המשתמש של החלון מוצג עם אפקט הטשטוש של החלון, מפעילים או משביתים את הטשטוש באחת מהשיטות הבאות:
באפשרויות למפתחים:
הגדרות -> מערכת -> אפשרויות למפתחים -> עיבוד בהאצת חומרה -> אפשרות לטשטוש ברמת החלון
מהטרמינל במכשיר עם הרשאות בסיס:
adb shell wm disable-blur 1 # 1 disables window blurs, 0 allows them
כדי לבדוק אם המכשיר עם Android מגרסה 12 ואילך תומך בהטשטוש של חלונות, ואם הטשטוש של חלונות מופעל כרגע, מריצים את הפקודה adb shell wm disable-blur
במכשיר שעבר רוט.
פתרון בעיות
ההנחיות הבאות יעזרו לכם לפתור בעיות במהלך האימות.
לא נמשך טשטוש
מוודאים שהטשטוש מופעל כרגע ושהחומרה תומכת בו. אפשר לעיין במאמר הפעלה והשבתה של טשטוש החלון.
חשוב להגדיר צבע רקע שקוף לחלון. צבע הרקע של חלון אטום מסתיר את האזור המטושטש.
מכשיר הבדיקה לא תומך בטשטוש חלונות
- בודקים את האפליקציה באמולטור של Android 12. הוראות להגדרת אמולטור Android מופיעות במאמר הגדרת אמולטור Android. כל מכשיר וירטואלי של Android שיוצרים באמצעות האמולטור תומך בטשטוש החלון.
ללא פינות מעוגלות
- מגדירים drawable לרקע של החלון כדי להגדיר פינות מעוגלות. ה-drawable הזה קובע את המתאר של האזור המטושטש.
עדכון האפשרות למפתחים לא מפעיל את הטשטוש
- בודקים אם המכשיר במצב חיסכון בסוללה או אם הוא משתמש במנהור מולטימדיה. במכשירי טלוויזיה מסוימים, יכול להיות שגם הטשטוש של החלון יושבת במהלך הפעלת הסרטון.
טשטוש הרקע מוצג במסך מלא, ולא בתוך גבולות החלון
בודקים את android:windowIsFloating כדי לוודא שהחלון מסומן כחלון צף.
מוודאים שמוגדר window background drawable. ההגדרה הזו קובעת את קו המתאר של האזור המטושטש.
העדכונים מה-listener לא מוחלים על המסך
- יכול להיות שהעדכונים של מאזין מוחלים על מופע ישן של חלון. בודקים אם החלון נהרס ונוצר מחדש עם העדכון הנכון של listener.