کلاس های اندازه پنجره

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

کلاس‌های اندازه پنجره، ناحیه نمایش در دسترس برنامه شما را به‌عنوان فشرده ، متوسط ​​یا گسترده دسته‌بندی می‌کنند. عرض و ارتفاع موجود به طور جداگانه طبقه‌بندی می‌شوند، بنابراین در هر نقطه از زمان، برنامه شما دارای دو کلاس اندازه پنجره است-یکی برای عرض، یکی برای ارتفاع. عرض در دسترس معمولاً به دلیل فراگیر بودن پیمایش عمودی مهمتر از ارتفاع موجود است، بنابراین کلاس اندازه پنجره عرض احتمالاً بیشتر به رابط کاربری برنامه شما مرتبط است.

شکل 1. نمایش کلاس های اندازه پنجره مبتنی بر عرض.
شکل 2. نمایش کلاس های اندازه پنجره مبتنی بر ارتفاع.

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

کلاس اندازه نقطه شکست نمایندگی دستگاه
عرض جمع و جور عرض < 600dp 99.96 درصد از تلفن ها در حالت پرتره
عرض متوسط 600dp ≤ عرض < 840dp 93.73 درصد از تبلت ها به صورت پرتره،

بیشتر نمایشگرهای داخلی تا شده بزرگ به صورت پرتره

عرض گسترش یافته است عرض ≥ 840dp 97.22٪ از تبلت ها در چشم انداز،

بیشتر نمایشگرهای داخلی باز شده بزرگ در چشم انداز

ارتفاع جمع و جور ارتفاع < 480dp 99.78٪ از تلفن ها در چشم انداز
ارتفاع متوسط 480dp ≤ ارتفاع < 900dp 96.56٪ از تبلت ها در چشم انداز،

97.59 درصد از تلفن ها در حالت پرتره

ارتفاع منبسط شده ارتفاع ≥ 900dp 94.25 درصد تبلت ها به صورت پرتره

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

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

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

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

شما می توانید WindowSizeClass فعلی را با استفاده از تابع WindowSizeClass#compute() که توسط کتابخانه Jetpack WindowManager ارائه شده است محاسبه کنید. مثال زیر نحوه محاسبه کلاس اندازه پنجره و دریافت به روز رسانی هر زمان که کلاس اندازه پنجره تغییر می کند نشان می دهد:

کاتلین

class MainActivity : Activity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // ...

        // Replace with a known container that you can safely add a
        // view to where the view won't affect the layout and the view
        // won't be replaced.
        val container: ViewGroup = binding.container

        // Add a utility view to the container to hook into
        // View.onConfigurationChanged(). This is required for all
        // activities, even those that don't handle configuration
        // changes. You can't use Activity.onConfigurationChanged(),
        // since there are situations where that won't be called when
        // the configuration changes. View.onConfigurationChanged() is
        // called in those scenarios.
        container.addView(object : View(this) {
            override fun onConfigurationChanged(newConfig: Configuration?) {
                super.onConfigurationChanged(newConfig)
                computeWindowSizeClasses()
            }
        })

        computeWindowSizeClasses()
    }

    private fun computeWindowSizeClasses() {
        val metrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(this)
        val width = metrics.bounds.width()
        val height = metrics.bounds.height()
        val density = resources.displayMetrics.density
        val windowSizeClass = WindowSizeClass.compute(width/density, height/density)
        // COMPACT, MEDIUM, or EXPANDED
        val widthWindowSizeClass = windowSizeClass.windowWidthSizeClass
        // COMPACT, MEDIUM, or EXPANDED
        val heightWindowSizeClass = windowSizeClass.windowHeightSizeClass

        // Use widthWindowSizeClass and heightWindowSizeClass.
    }
}

جاوا

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // ...

        // Replace with a known container that you can safely add a
        // view to where the view won't affect the layout and the view
        // won't be replaced.
        ViewGroup container = binding.container;

        // Add a utility view to the container to hook into
        // View.onConfigurationChanged(). This is required for all
        // activities, even those that don't handle configuration
        // changes. You can't use Activity.onConfigurationChanged(),
        // since there are situations where that won't be called when
        // the configuration changes. View.onConfigurationChanged() is
        // called in those scenarios.
        container.addView(new View(this) {
            @Override
            protected void onConfigurationChanged(Configuration newConfig) {
                super.onConfigurationChanged(newConfig);
                computeWindowSizeClasses();
            }
        });

        computeWindowSizeClasses();
    }

    private void computeWindowSizeClasses() {
        WindowMetrics metrics = WindowMetricsCalculator.getOrCreate()
                .computeCurrentWindowMetrics(this);

        int width = metrics.getBounds().width
        int height = metrics.getBounds().height()
        float density = getResources().getDisplayMetrics().density;
        WindowSizeClass windowSizeClass = WindowSizeClass.compute(width/density, height/density)
        // COMPACT, MEDIUM, or EXPANDED
        WindowWidthSizeClass widthWindowSizeClass = windowSizeClass.getWindowWidthSizeClass()
        // COMPACT, MEDIUM, or EXPANDED
        WindowHeightSizeClass heightWindowSizeClass = windowSizeClass.getWindowHeightSizeClass()

        // Use widthWindowSizeClass and heightWindowSizeClass.
    }
}

کلاس های اندازه پنجره را آزمایش کنید

همانطور که در طرح‌بندی تغییراتی ایجاد می‌کنید، رفتار طرح‌بندی را در تمام اندازه‌های پنجره، به‌ویژه در پهنای نقطه شکست فشرده، متوسط ​​و گسترش یافته آزمایش کنید.

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

مراحل بعدی

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

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

،

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

کلاس‌های اندازه پنجره، ناحیه نمایش در دسترس برنامه شما را به‌عنوان فشرده ، متوسط ​​یا گسترده دسته‌بندی می‌کنند. عرض و ارتفاع موجود به طور جداگانه طبقه‌بندی می‌شوند، بنابراین در هر نقطه از زمان، برنامه شما دارای دو کلاس اندازه پنجره است-یکی برای عرض، یکی برای ارتفاع. عرض در دسترس معمولاً به دلیل فراگیر بودن پیمایش عمودی مهمتر از ارتفاع موجود است، بنابراین کلاس اندازه پنجره عرض احتمالاً بیشتر به رابط کاربری برنامه شما مرتبط است.

شکل 1. نمایش کلاس های اندازه پنجره مبتنی بر عرض.
شکل 2. نمایش کلاس های اندازه پنجره مبتنی بر ارتفاع.

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

کلاس اندازه نقطه شکست نمایندگی دستگاه
عرض جمع و جور عرض < 600dp 99.96 درصد از تلفن ها در حالت پرتره
عرض متوسط 600dp ≤ عرض < 840dp 93.73 درصد از تبلت ها به صورت پرتره،

بیشتر نمایشگرهای داخلی تا شده بزرگ به صورت پرتره

عرض گسترش یافته است عرض ≥ 840dp 97.22٪ از تبلت ها در چشم انداز،

بیشتر نمایشگرهای داخلی باز شده بزرگ در چشم انداز

ارتفاع جمع و جور ارتفاع < 480dp 99.78٪ از تلفن ها در چشم انداز
ارتفاع متوسط 480dp ≤ ارتفاع < 900dp 96.56٪ از تبلت ها در چشم انداز،

97.59 درصد از تلفن ها در حالت پرتره

ارتفاع منبسط شده ارتفاع ≥ 900dp 94.25 درصد تبلت ها به صورت پرتره

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

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

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

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

شما می توانید WindowSizeClass فعلی را با استفاده از تابع WindowSizeClass#compute() که توسط کتابخانه Jetpack WindowManager ارائه شده است محاسبه کنید. مثال زیر نحوه محاسبه کلاس اندازه پنجره و دریافت به روز رسانی هر زمان که کلاس اندازه پنجره تغییر می کند نشان می دهد:

کاتلین

class MainActivity : Activity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // ...

        // Replace with a known container that you can safely add a
        // view to where the view won't affect the layout and the view
        // won't be replaced.
        val container: ViewGroup = binding.container

        // Add a utility view to the container to hook into
        // View.onConfigurationChanged(). This is required for all
        // activities, even those that don't handle configuration
        // changes. You can't use Activity.onConfigurationChanged(),
        // since there are situations where that won't be called when
        // the configuration changes. View.onConfigurationChanged() is
        // called in those scenarios.
        container.addView(object : View(this) {
            override fun onConfigurationChanged(newConfig: Configuration?) {
                super.onConfigurationChanged(newConfig)
                computeWindowSizeClasses()
            }
        })

        computeWindowSizeClasses()
    }

    private fun computeWindowSizeClasses() {
        val metrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(this)
        val width = metrics.bounds.width()
        val height = metrics.bounds.height()
        val density = resources.displayMetrics.density
        val windowSizeClass = WindowSizeClass.compute(width/density, height/density)
        // COMPACT, MEDIUM, or EXPANDED
        val widthWindowSizeClass = windowSizeClass.windowWidthSizeClass
        // COMPACT, MEDIUM, or EXPANDED
        val heightWindowSizeClass = windowSizeClass.windowHeightSizeClass

        // Use widthWindowSizeClass and heightWindowSizeClass.
    }
}

جاوا

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // ...

        // Replace with a known container that you can safely add a
        // view to where the view won't affect the layout and the view
        // won't be replaced.
        ViewGroup container = binding.container;

        // Add a utility view to the container to hook into
        // View.onConfigurationChanged(). This is required for all
        // activities, even those that don't handle configuration
        // changes. You can't use Activity.onConfigurationChanged(),
        // since there are situations where that won't be called when
        // the configuration changes. View.onConfigurationChanged() is
        // called in those scenarios.
        container.addView(new View(this) {
            @Override
            protected void onConfigurationChanged(Configuration newConfig) {
                super.onConfigurationChanged(newConfig);
                computeWindowSizeClasses();
            }
        });

        computeWindowSizeClasses();
    }

    private void computeWindowSizeClasses() {
        WindowMetrics metrics = WindowMetricsCalculator.getOrCreate()
                .computeCurrentWindowMetrics(this);

        int width = metrics.getBounds().width
        int height = metrics.getBounds().height()
        float density = getResources().getDisplayMetrics().density;
        WindowSizeClass windowSizeClass = WindowSizeClass.compute(width/density, height/density)
        // COMPACT, MEDIUM, or EXPANDED
        WindowWidthSizeClass widthWindowSizeClass = windowSizeClass.getWindowWidthSizeClass()
        // COMPACT, MEDIUM, or EXPANDED
        WindowHeightSizeClass heightWindowSizeClass = windowSizeClass.getWindowHeightSizeClass()

        // Use widthWindowSizeClass and heightWindowSizeClass.
    }
}

کلاس های اندازه پنجره را آزمایش کنید

همانطور که در طرح‌بندی تغییراتی ایجاد می‌کنید، رفتار طرح‌بندی را در تمام اندازه‌های پنجره، به‌ویژه در پهنای نقطه شکست فشرده، متوسط ​​و گسترش یافته آزمایش کنید.

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

مراحل بعدی

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

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