חלון מטשטש

באנדרואיד 12, ממשקי API ציבוריים זמינים להטמעת אפקטים של טשטוש חלונות, כגון טשטוש רקע וטשטוש מאחור.

טשטוש חלונות, או טשטוש חלונות צולבים, משמשים לטשטוש המסך מאחורי החלון הנתון. ישנם שני סוגים של טשטוש חלונות, שניתן להשתמש בהם כדי להשיג אפקטים חזותיים שונים:

  • טשטוש רקע מאפשר לך ליצור חלונות עם רקע מטושטש, וליצור אפקט זכוכית חלבית.

  • טשטוש מאחורי מאפשר לך לטשטש את כל המסך מאחורי חלון (דיאלוג), יצירת אפקט עומק שדה.

ניתן להשתמש בשני האפקטים בנפרד או בשילוב, כפי שמוצג באיור הבא:

טשטוש רקע בלבד

א

טשטוש מאחור בלבד

ב

טשטוש מאחור וטשטוש רקע

ג

איור 1. טשטוש רקע בלבד (א), טשטוש מאחור בלבד (ב), טשטוש רקע וטשטוש מאחור (ג)

תכונת טשטוש החלונות פועלת על פני חלונות, מה שאומר שהיא פועלת גם כשיש אפליקציה אחרת מאחורי החלון שלך. אפקט זה אינו זהה לאפקט עיבוד הטשטוש , המטשטש את התוכן בתוך אותו חלון. טשטוש חלונות שימושי עבור דיאלוגים, גיליונות תחתונים וחלונות צפים אחרים.

יישום

מפתחי אפליקציות

מפתחי אפליקציות חייבים לספק רדיוס טשטוש כדי ליצור אפקט טשטוש. רדיוס הטשטוש שולט עד כמה הטשטוש צפוף, כלומר, ככל שהרדיוס גבוה יותר, הטשטוש צפוף יותר. טשטוש של 0 פיקסלים פירושו שאין טשטוש. עבור טשטוש מאחור, רדיוס של 20 פיקסלים יוצר אפקט טוב של עומק שדה, בעוד שרדיוס טשטוש רקע של 80 פיקסלים יוצר אפקט טוב של זכוכית חלבית. הימנע מרדיוסי טשטוש גבוהים מ-150 פיקסלים, מכיוון שהדבר ישפיע באופן משמעותי על הביצועים.

כדי להשיג את אפקט הטשטוש הרצוי ולהגביר את הקריאה, בחר ערך רדיוס טשטוש משלים עם שכבת צבע שקופה.

טשטוש רקע

השתמש בטשטוש רקע בחלונות צפים כדי ליצור אפקט רקע של חלון שהוא תמונה מטושטשת של התוכן הבסיסי. כדי להוסיף רקע מטושטש לחלון שלך, בצע את הפעולות הבאות:

  1. התקשר ל- Window#setBackgroundBlurRadius(int) כדי להגדיר רדיוס טשטוש רקע. לחלופין, בעיצוב החלון, הגדר את R.attr.windowBackgroundBlurRadius .

  2. הגדר את R.attr.windowIsTranslucent ל-true כדי להפוך את החלון לשקוף. הטשטוש מצויר מתחת למשטח החלון, כך שהחלון צריך להיות שקוף כדי שהטשטוש יהיה גלוי.

  3. לחלופין, התקשר ל- Window#setBackgroundDrawableResource(int) כדי להוסיף רקע חלון מלבני שניתן לצייר עם צבע שקוף. לחלופין, בעיצוב החלון, הגדר את R.attr.windowBackground .

  4. עבור חלון עם פינות מעוגלות, קבע את הפינות המעוגלות עבור האזור המטושטש על ידי הגדרת ShapeDrawable עם פינות מעוגלות כרקע החלון שניתן לציור.

  5. טפל במצבי טשטוש מופעלים ומושבתים. עיין בסעיף הנחיות לשימוש בטשטוש חלונות באפליקציות למידע נוסף.

טשטוש מאחור

הטשטוש מאחור מטשטש את כל המסך מאחורי החלון. אפקט זה משמש כדי להפנות את תשומת הלב של המשתמש לתוכן החלון על ידי טשטוש כל דבר על המסך מאחורי החלון.

כדי לטשטש את התוכן מאחורי החלון שלך, בצע את השלבים הבאים:

  1. הוסף את FLAG_BLUR_BEHIND לדגלי החלון כדי לאפשר טשטוש מאחור. לחלופין, בעיצוב החלון, הגדר את R.attr.windowBlurBehindEnabled .

  2. התקשר ל- WindowManager.LayoutParams#setBlurBehindRadius כדי להגדיר טשטוש מאחורי רדיוס. לחלופין, בעיצוב החלון, הגדר את R.attr.windowBlurBehindRadius .

  3. לחלופין, בחר כמות עמומה משלימה .

  4. טפל במצבי טשטוש מופעלים ומושבתים. עיין בסעיף הנחיות לשימוש בטשטוש חלונות באפליקציות למידע נוסף.

הנחיות לשימוש בטשטוש חלונות באפליקציות

התמיכה בטשטוש חלונות תלויה בדברים הבאים:

  • גרסת אנדרואיד: ממשקי ה-API של Windows Blut זמינים רק ב-Android 12 ומעלה. בדוק את ה-SDK של המכשיר עבור גרסת אנדרואיד.

  • ביצועים גרפיים: מכשירים עם GPUs פחות ביצועים עשויים לבחור שלא לתמוך בטשטוש חלונות.

  • מצב מערכת: שרת המערכת עשוי להשבית זמנית את טשטוש החלונות בזמן ריצה, לדוגמה, במהלך מצב חיסכון בסוללה, בזמן הפעלת סוגים מסוימים של תוכן וידאו או עקב עקיפה של מפתח.

כדי להפוך את האפליקציה שלך לתואמת לגרסאות אנדרואיד, מכשירים ומצבי מערכת, פעל לפי ההנחיות הבאות:

  • הוסף מאזין דרך WindowManager#addCrossWindowBlurEnabledListener , כדי להודיע ​​לך כאשר טשטוש החלונות מופעלים או מושבתים. בנוסף, השתמש WindowManager#isCrossWindowBlurEnabled כדי לשאול אם טשטוש החלונות מופעלים כעת.

  • הטמע שתי גרסאות עבור רקע החלון, כדי להתאים למצב מופעל או מושבת של טשטוש חלונות.

    כאשר הטשטושים מופעלים, רקע החלון צריך להיות שקוף כדי שהטשטוש יהיה גלוי. במצב זה, כאשר הטשטושים מושבתים, תוכן החלון חופף ישירות לתוכן של החלון הבסיסי, מה שהופך את החלון החופף לפחות קריא. כדי למנוע אפקט כזה, כאשר טשטוש החלונות מושבת, התאם את ממשק המשתמש של האפליקציה באופן הבא:

    • לטשטוש רקע, הגדל את האלפא של רקע החלון הניתן לציור, מה שהופך אותו אטום יותר.

    • לטשטוש מאחור, הוסף שכבה עמומה עם כמות עמומה גבוהה יותר.

דוגמה לטשטוש מאחורי וטשטוש רקע

חלק זה מספק דוגמה פועלת לפעילות המשתמשת גם בטשטוש מאחור וגם בטשטוש רקע.

הדוגמה הבאה של MainActivity.java היא דו-שיח עם טשטוש מאחורי רדיוס של 20 פיקסלים ורדיוס טשטוש רקע של 80 פיקסלים. יש לו פינות מעוגלות, המוגדרות ב-xml ברקע החלון שניתן לצייר. הוא מטפל נכון בגרסאות אנדרואיד שונות, מכשירים שונים (שעשויים לא תומכים בטשטוש חלונות) ושינויים מופעלים או מושבתים של טשטוש זמן ריצה. זה מבטיח שתוכן הדו-שיח יהיה קריא בכל אחד מהתנאים הללו על-ידי התאמת ה-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<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 מספיק.

  • אם יש לך מנוע רינדור מותאם אישית, ודא שמנוע הרינדור שלך מיישם את היגיון הטשטוש. מנוע הרינדור של אנדרואיד 12 המוגדר כברירת מחדל מיישם את היגיון הטשטוש ב- BlurFilter.cpp .

לאחר שתוודא שהמכשיר שלך יכול לתמוך בטשטוש חלונות, הגדר את sysprop של השטח הבא:

PRODUCT_VENDOR_PROPERTIES += \
       ro.surface_flinger.supports_background_blur=1

מַתַן תוֹקֵף

כדי לוודא שלחלון האפליקציה שלך יש טיפול תקין בעת ​​מעבר בין מצב טשטוש מופעל למצב טשטוש מושבת, בצע את השלבים הבאים:

  1. פתח את ממשק המשתמש שיש בו טשטוש.

  2. הפעל או השבת את טשטוש החלונות על ידי הפעלה וכיבוי של טשטוש החלונות .

  3. ודא שממשק המשתמש של החלון משתנה למצב מטושטש וממנו כצפוי.

הפעלה וכיבוי של טשטוש החלונות

כדי לבדוק כיצד ממשק המשתמש של החלון מוצג עם אפקט טשטוש החלונות, הפעל או השבת את הטשטושים באחת מהשיטות הבאות:

  • מתוך אפשרויות מפתחים:

    הגדרות -> מערכת -> אפשרויות מפתח -> עיבוד מואץ חומרה -> אפשר טשטוש ברמת החלון

  • מהמסוף במכשיר שורשי:

    adb shell wm disable-blur 1 # 1 disables window blurs, 0 allows them
    

כדי לבדוק אם מכשיר ה-Android 12+ שלך תומך בטשטוש חלונות והאם טשטוש חלונות מופעלים כעת, הפעל את adb shell wm disable-blur במכשיר שורשי.

פתרון תקלות

השתמש בדברים הבאים כמדריך לפתרון בעיות במהלך האימות.

לא צויר טשטוש

  • ודא שהטשטושים מופעלים כעת והחומרה שלך תומכת בהם. עיין בהפעלה וכיבוי של טשטוש חלון .

  • ודא שאתה מגדיר צבע רקע שקוף לחלון. צבע רקע של חלון אטום מסתיר את האזור המטושטש.

מכשיר הבדיקה אינו תומך בטשטוש חלונות

  • בדוק את האפליקציה שלך באמולטור אנדרואיד 12. להגדרת אמולטור אנדרואיד, עיין בהגדרת אמולטור אנדרואיד . כל מכשיר וירטואלי של אנדרואיד שתיצור עם האמולטור תומך בטשטוש החלונות.

ללא פינות מעוגלות

עדכון אפשרות המפתח אינו מאפשר טשטושים

  • בדוק אם המכשיר נמצא במצב חיסכון בסוללה או שהוא משתמש במנהור מולטימדיה . במכשירי טלוויזיה מסוימים ייתכן שטשטוש החלונות יהיה מושבת גם במהלך הפעלת וידאו.

טשטוש רקע מצויר במסך מלא, לא בגבולות החלון

עדכונים מהמאזין אינם מוחלים על המסך

  • ייתכן שעדכוני המאזין יוחלו על מופע חלון ישן. בדוק אם החלון נהרס ויוצר מחדש עם עדכון המאזין הנכון.