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

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

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

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

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

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

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

آ

فقط پشت تاری

ب

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

ج

شکل 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 blur فقط در اندروید 12 و بالاتر در دسترس هستند. SDK دستگاه را برای نسخه اندروید بررسی کنید.

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

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

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

  • یک شنونده از طریق 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 با گوشه های گرد با شعاع dp 20 به صورت زیر تعریف می کنیم:

<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 تست کنید. برای راه اندازی شبیه ساز اندروید، به راه اندازی شبیه ساز اندروید مراجعه کنید. هر دستگاه مجازی اندرویدی که با شبیه ساز ایجاد می کنید از تاری پنجره پشتیبانی می کند.

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

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

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

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

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

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