ב-Android 12, ממשקי API ציבוריים זמינים להטמעה של אפקטים של טשטוש חלונות, כמו טשטוש רקע וטשטוש מאחור.
טשטוש חלונות, או טשטוש בין חלונות, משמש לטשטוש המסך שמאחורי החלון הנתון. יש שני סוגים של טשטוש חלונות, שמאפשרים להשיג אפקטים חזותיים שונים:
טשטוש הרקע מאפשר ליצור חלונות עם רקע מטושטש, וליצור אפקט של זכוכית חלבית.
ההגדרה טשטוש מאחור מאפשרת לטשטש את כל המסך שמאחורי חלון (תיבת דו-שיח), וכך ליצור אפקט של עומק שדה.
אפשר להשתמש בשני האפקטים בנפרד או לשלב ביניהם, כמו שמוצג בתמונה הבאה:
|
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.
ביצועי גרפיקה: מכשירים עם מעבדים גרפיים פחות חזקים עשויים לא לתמוך בטשטוש חלונות.
מצב המערכת: שרת המערכת עשוי להשבית באופן זמני את טשטוש החלונות בזמן הריצה, למשל, במצב חיסכון בסוללה, בזמן הפעלה של סוגים מסוימים של קטע וידאו או בגלל שינוי מברירת המחדל של מפתח.
כדי שהאפליקציה תהיה תואמת לגרסאות Android, למכשירים ולמצבי מערכת שונים, צריך לפעול לפי ההנחיות הבאות:
מוסיפים מאזין באמצעות WindowManager#addCrossWindowBlurEnabledListener, כדי לקבל התראה כשהטשטוש של החלונות מופעל או מושבת. בנוסף, אפשר להשתמש ב-
WindowManager#isCrossWindowBlurEnabledכדי לשלוח שאילתה ולבדוק אם טשטוש החלונות מופעל כרגע.הטמיעו שתי גרסאות לרקע של החלון, כדי להתאים למצב שבו טשטוש החלונות מופעל או מושבת.
כשהטשטוש מופעל, הרקע של החלון צריך להיות שקוף למחצה כדי שהטשטוש יהיה גלוי. במצב הזה, כשמשביתים את הטשטוש, תוכן החלון חופף ישירות לתוכן של החלון שמתחתיו, והחלון החופף פחות קריא. כדי להימנע מהאפקט הזה, כשהטשטוש של החלונות מושבת, צריך להתאים את ממשק המשתמש של האפליקציה באופן הבא:
כדי לטשטש את הרקע, מגדילים את ערך האלפא של הרקע של החלון שניתן לשרטוט, כך שהוא יהיה אטום יותר.
כדי לטשטש את הרקע, מוסיפים שכבת עמעום עם ערך עמעום גבוה יותר.
דוגמה לטשטוש מאחור ולטשטוש הרקע
בקטע הזה מוצגת דוגמה לפעילות שמשתמשת גם בטשטוש מאחור וגם בטשטוש רקע.
הדוגמה הבאה של MainActivity.java היא תיבת דו-שיח עם רדיוס טשטוש מאחור של 20 פיקסלים ורדיוס טשטוש ברקע של 80 פיקסלים. יש לו פינות מעוגלות, שמוגדרות ב-XML ב-drawable של רקע החלון. הוא מטפל בצורה נכונה בגרסאות שונות של 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) ושותפים
כדי לטשטש חלונות במכשיר, ה-OEM צריך להצהיר שהמכשיר תומך בטשטוש חלונות.
כדי לבדוק אם המכשיר תומך בטשטוש חלונות:
מוודאים שהמכשיר יכול להתמודד עם העומס הנוסף על המעבד הגרפי (GPU). יכול להיות שמכשירים פשוטים יותר לא יוכלו להתמודד עם העומס הנוסף, מה שעלול לגרום לדילוג על פריימים. צריך להפעיל טשטוש חלונות רק במכשירים שנבדקו ויש להם מספיק כוח GPU.
אם יש לכם מנוע רינדור מותאם אישית, ודאו שהוא מיישם את לוגיקת הטשטוש. מנוע הרינדור שמוגדר כברירת מחדל ב-Android 12 מטמיע את הלוגיקה של הטשטוש ב-
BlurFilter.cpp.
אחרי שמוודאים שהמכשיר תומך בטשטוש חלונות, מגדירים את המאפיין הבא של
surface flinger sysprop:
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 שיוצרים באמצעות האמולטור תומך בטשטוש החלונות.
ללא פינות מעוגלות
- הגדירו רכיב גרפי לרקע של החלון כדי להגדיר פינות מעוגלות. האובייקט הזה קובע את קווי המתאר של האזור המטושטש.
עדכון האפשרות למפתחים לא מפעיל את הטשטוש
- בודקים אם המכשיר נמצא במצב חיסכון בסוללה או אם הוא משתמש במנהור מולטימדיה. במכשירי טלוויזיה מסוימים, יכול להיות שגם טשטוש החלונות יושבת במהלך הפעלת הסרטון.
טשטוש הרקע מוצג במסך מלא, ולא בתוך גבולות החלון
בודקים את android:windowIsFloating כדי לוודא שהחלון מסומן כצף.
מוודאים שמוגדר רכיב גרפי לרקע של החלון. ההגדרה הזו קובעת את קווי המתאר של אזור הטשטוש.
העדכונים מהמאזין לא מופיעים במסך
- יכול להיות שהעדכונים של המאזין מוחלים על מופע חלון ישן. בודקים אם החלון נסגר ונפתח מחדש עם עדכון המאזין הנכון.
