پنجره تار می شود

در اندروید ۱۲، APIهای عمومی برای پیاده‌سازی جلوه‌های تاری پنجره، مانند تاری پس‌زمینه و تاری پشت، در دسترس هستند.

تار کردن پنجره‌ها یا تار کردن پنجره‌های متقاطع، برای تار کردن صفحه نمایش پشت پنجره مورد نظر استفاده می‌شود. دو نوع تار کردن پنجره وجود دارد که می‌توانند برای دستیابی به جلوه‌های بصری مختلف مورد استفاده قرار گیرند:

  • تار کردن پس‌زمینه به شما امکان می‌دهد پنجره‌هایی با پس‌زمینه تار ایجاد کنید و جلوه‌ای از شیشه مات ایجاد کنید.

  • قابلیت محو کردن پشت صحنه به شما این امکان را می‌دهد که کل صفحه نمایش پشت یک پنجره (گفتگو) را محو کنید و جلوه عمق میدان ایجاد کنید.

این دو اثر می‌توانند به صورت جداگانه یا ترکیبی استفاده شوند، همانطور که در شکل زیر نشان داده شده است:

فقط تاری پس‌زمینه

الف

فقط پشت را تار کنید

ب

تاری پشت و تاری پس‌زمینه

ج

شکل ۱. فقط محو کردن پس‌زمینه (الف)، فقط محو کردن پشت (ب)، محو کردن پس‌زمینه و محو کردن پشت (ج)

ویژگی تار کردن پنجره در بین پنجره‌ها کار می‌کند، به این معنی که وقتی برنامه دیگری پشت پنجره شما وجود دارد نیز کار می‌کند. این جلوه با جلوه رندر تار که محتوای داخل همان پنجره را تار می‌کند، یکسان نیست. تار کردن پنجره برای دیالوگ‌ها، صفحات پایینی و سایر پنجره‌های شناور مفید است.

پیاده‌سازی

توسعه‌دهندگان اپلیکیشن

توسعه‌دهندگان برنامه باید برای ایجاد جلوه تاری، شعاع تاری را ارائه دهند. شعاع تاری، میزان تراکم تاری را کنترل می‌کند، یعنی هرچه شعاع بیشتر باشد، تاری متراکم‌تر است. تاری ۰ پیکسل به معنای عدم تاری است. برای تاری پشت، شعاع ۲۰ پیکسل عمق میدان خوبی ایجاد می‌کند، در حالی که شعاع تاری پس‌زمینه ۸۰ پیکسل جلوه شیشه مات خوبی ایجاد می‌کند. از شعاع تاری بالاتر از ۱۵۰ پیکسل خودداری کنید، زیرا این امر به طور قابل توجهی بر عملکرد تأثیر می‌گذارد.

برای رسیدن به جلوه تاری دلخواه و افزایش خوانایی، مقدار شعاع تاری را با یک لایه رنگ شفاف تکمیل کنید.

محو شدن پس‌زمینه

از قابلیت تار کردن پس‌زمینه روی پنجره‌های شناور استفاده کنید تا جلوه‌ای از پس‌زمینه پنجره ایجاد شود که تصویری تار از محتوای زیرین است. برای افزودن پس‌زمینه تار به پنجره خود، مراحل زیر را انجام دهید:

  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های ویندوز بلور فقط در اندروید ۱۲ و بالاتر در دسترس هستند. برای اطلاع از نسخه اندروید، SDK دستگاه را بررسی کنید.

  • عملکرد گرافیکی: دستگاه‌هایی که پردازنده‌های گرافیکی ضعیف‌تری دارند، ممکن است از قابلیت تار کردن پنجره‌ها پشتیبانی نکنند.

  • وضعیت سیستم: سرور سیستم ممکن است در زمان اجرا، مثلاً در حالت صرفه‌جویی در باتری، هنگام پخش انواع خاصی از محتوای ویدیویی یا به دلیل لغو تنظیمات توسط توسعه‌دهنده، موقتاً قابلیت تار شدن پنجره‌ها را غیرفعال کند.

برای اینکه برنامه شما با نسخه‌های مختلف اندروید، دستگاه‌ها و وضعیت‌های مختلف سیستم سازگار باشد، این دستورالعمل‌ها را دنبال کنید:

  • از طریق WindowManager#addCrossWindowBlurEnabledListener یک شنونده اضافه کنید تا وقتی تار شدن پنجره فعال یا غیرفعال شد، به شما اطلاع دهد. علاوه بر این، از WindowManager#isCrossWindowBlurEnabled برای پرس و جو در مورد فعال بودن تار شدن پنجره‌ها استفاده کنید.

  • دو نسخه برای پس‌زمینه پنجره پیاده‌سازی کنید تا حالت فعال یا غیرفعال تاری پنجره را در خود جای دهد.

    وقتی قابلیت محوشدگی فعال است، پس‌زمینه پنجره باید شفاف باشد تا محوشدگی قابل مشاهده باشد. در این حالت، وقتی قابلیت محوشدگی غیرفعال می‌شود، محتوای پنجره مستقیماً با محتوای پنجره زیرین همپوشانی دارد و باعث می‌شود پنجره روی هم افتاده خوانایی کمتری داشته باشد. برای جلوگیری از چنین تأثیری، وقتی قابلیت محوشدگی پنجره غیرفعال است، رابط کاربری برنامه را به صورت زیر تنظیم کنید:

    • برای تار کردن پس‌زمینه، آلفای پس‌زمینه‌ی پنجره‌ی قابل ترسیم را افزایش دهید و آن را مات‌تر کنید.

    • برای تاری پشت، یک لایه کم‌نور با مقدار کم‌نوری بالاتر اضافه کنید.

مثالی از تاری پشت و تاری پس‌زمینه

این بخش یک مثال کاربردی از فعالیتی ارائه می‌دهد که از هر دو قابلیت تار کردن پشت و تار کردن پس‌زمینه استفاده می‌کند.

مثال زیر از MainActivity.java یک دیالوگ با شعاع محوشدگی پشت 20 پیکسل و شعاع محوشدگی پس‌زمینه 80 پیکسل است. این دیالوگ دارای گوشه‌های گرد است که در xml در پنجره پس‌زمینه قابل ترسیم تعریف شده‌اند. این دیالوگ به درستی نسخه‌های مختلف اندروید، دستگاه‌های مختلف (که به طور بالقوه از محوشدگی پنجره پشتیبانی نمی‌کنند) و تغییرات فعال یا غیرفعال محوشدگی در زمان اجرا را مدیریت می‌کند. این دیالوگ با تنظیم آلفای قابل ترسیم پس‌زمینه پنجره و میزان کم‌نور شدن پنجره، خوانایی محتوای دیالوگ را در هر یک از این شرایط تضمین می‌کند.

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) را تحمل کند. دستگاه‌های رده پایین ممکن است نتوانند بار اضافی را تحمل کنند که می‌تواند باعث افت فریم شود. فقط در دستگاه‌های آزمایش‌شده با قدرت پردازنده گرافیکی کافی، قابلیت تار شدن پنجره‌ها را فعال کنید.

  • اگر موتور رندر سفارشی دارید، مطمئن شوید که موتور رندر شما منطق محوشدگی را پیاده‌سازی می‌کند. موتور رندر پیش‌فرض اندروید ۱۲، منطق محوشدگی را در BlurFilter.cpp پیاده‌سازی می‌کند.

وقتی مطمئن شدید که دستگاه شما از قابلیت تار کردن پنجره‌ها پشتیبانی می‌کند، sysprop مربوط به surface flinger را به صورت زیر تنظیم کنید:

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

برای بررسی اینکه آیا دستگاه اندروید ۱۲+ شما از قابلیت تار کردن پنجره‌ها پشتیبانی می‌کند و آیا این قابلیت در حال حاضر فعال است، adb shell wm disable-blur روی دستگاه روت شده اجرا کنید.

عیب‌یابی

از موارد زیر به عنوان راهنما برای عیب‌یابی در طول اعتبارسنجی استفاده کنید.

بدون تاری ترسیم شده

  • مطمئن شوید که تاری‌ها در حال حاضر فعال هستند و سخت‌افزار شما از آنها پشتیبانی می‌کند. به روشن و خاموش کردن تاری پنجره مراجعه کنید.

  • مطمئن شوید که رنگ پس‌زمینه پنجره را شفاف تنظیم کرده‌اید. رنگ پس‌زمینه پنجره مات، ناحیه تار شده را پنهان می‌کند.

دستگاه تست از تار کردن پنجره‌ها پشتیبانی نمی‌کند

  • برنامه خود را روی شبیه‌ساز اندروید ۱۲ تست کنید. برای راه‌اندازی شبیه‌ساز اندروید، به بخش «راه‌اندازی شبیه‌ساز اندروید» مراجعه کنید. هر دستگاه مجازی اندرویدی که با شبیه‌ساز ایجاد می‌کنید، از قابلیت تار شدن پنجره‌ها پشتیبانی می‌کند.

بدون گوشه‌های گرد

به‌روزرسانی گزینه توسعه‌دهنده، تار شدن تصویر را فعال نمی‌کند

  • بررسی کنید که آیا دستگاه در حالت صرفه‌جویی در مصرف باتری است یا از تونل‌سازی چندرسانه‌ای استفاده می‌کند. در برخی از دستگاه‌های تلویزیون، ممکن است تار شدن پنجره‌ها هنگام پخش ویدیو غیرفعال باشد.

پس‌زمینه تار در تمام صفحه ترسیم شده است، نه در محدوده پنجره

به‌روزرسانی‌های شنونده روی صفحه اعمال نمی‌شوند

  • ممکن است به‌روزرسانی‌های شنونده روی یک نمونه پنجره قدیمی اعمال شوند. بررسی کنید که آیا پنجره با به‌روزرسانی شنونده صحیح از بین می‌رود و دوباره ایجاد می‌شود یا خیر.