Các lớp kích thước cửa sổ

Lớp kích thước cửa sổ là một tập hợp các điểm ngắt khung nhìn cố định giúp bạn thiết kế, phát triển và thử nghiệm bố cục thích ứng. Sự cân bằng của các điểm ngắt tính đơn giản về bố cục cùng tính linh hoạt trong việc tối ưu hoá ứng dụng trong các trường hợp riêng biệt.

Các lớp kích thước cửa sổ sẽ phân loại khu vực hiển thị có sẵn cho ứng dụng thành nhỏ gọn, trung bình hoặc mở rộng. Chiều rộng và chiều cao có sẵn được phân loại riêng biệt, vì vậy, tại bất kỳ thời điểm nào, ứng dụng của bạn đều có kích thước cửa sổ lớp – một cho chiều rộng, một cho chiều cao. Chiều rộng có sẵn thường lớn hơn quan trọng hơn chiều cao hiện có do sự phổ biến của cuộn dọc, vì vậy lớp kích thước cửa sổ chiều rộng có thể phù hợp hơn với giao diện người dùng của ứng dụng.

Hình 1. Ví dụ minh hoạ các lớp kích thước cửa sổ chiều rộng.
Hình 2. Ví dụ minh hoạ các lớp kích thước cửa sổ chiều cao.

Như minh hoạ trong các hình, các điểm ngắt giúp bạn tiếp tục suy nghĩ về bố cục liên quan đến thiết bị và cấu hình. Mỗi điểm chuyển đổi đại diện cho một bố cục điển hình của thiết bị. Đây có thể là khung tham chiếu hữu ích trong quá trình thiết kế bố cục dựa trên điểm chuyển đổi.

Lớp kích thước Điểm chuyển đổi Trình bày trên thiết bị
Chiều rộng thu gọn chiều rộng < 600dp 99,96% điện thoại ở chế độ dọc
Chiều rộng trung bình 600dp ≤ chiều rộng < 840dp 93,73% máy tính bảng ở chế độ dọc

màn hình bên trong lớn nhất ở chế độ dọc khi chưa mở

Chiều rộng được mở rộng chiều rộng ≥ 840dp 97,22% máy tính bảng ở chế độ ngang

màn hình bên trong lớn nhất khi chưa mở ở chế độ ngang

Chiều cao thu gọn chiều cao < 480dp 99,78% điện thoại ở chế độ ngang
Chiều cao trung bình 480dp ≤ chiều cao < 900dp 96,56% máy tính bảng ở chế độ ngang

97,59% điện thoại ở chế độ dọc

Chiều cao mở rộng chiều cao ≥ 900dp 94,25% máy tính bảng ở chế độ dọc

Mặc dù việc trực quan hoá lớp kích thước dưới dạng thiết bị thực tế có thể hữu ích, nhưng kích thước cửa sổ các lớp rõ ràng không được xác định theo kích thước của màn hình thiết bị. Cửa sổ không dành cho logic isTablet-type. Thay vào đó, cửa sổ lớp kích thước được xác định theo kích thước cửa sổ có sẵn cho ứng dụng bất kể loại thiết bị mà ứng dụng đang chạy trên đó là loại thiết bị nào. Trong đó có hai yếu tố quan trọng tác động:

  • Thiết bị thực tế không đảm bảo tương thích với kích thước cửa sổ cụ thể. Chiến lược phát hành đĩa đơn không gian màn hình có sẵn cho ứng dụng của bạn có thể khác với kích thước màn hình của thiết bị vì nhiều lý do. Trên thiết bị di động, chế độ chia đôi màn hình có thể phân vùng màn hình giữa hai ứng dụng. Trên ChromeOS, các ứng dụng Android có thể được hiển thị dưới dạng cửa sổ dạng tự do có thể thay đổi kích thước tuỳ ý. Bạn có thể gập riêng từng màn hình có kích thước khác nhau bằng cách gập hoặc mở thiết bị.

  • Lớp kích thước cửa sổ có thể thay đổi trong suốt thời gian hoạt động của ứng dụng. Khi ứng dụng của bạn đang chạy, hướng thiết bị, đa nhiệm và việc gập/mở có thể thay đổi lượng không gian màn hình có sẵn. Là một kết quả, lớp kích thước cửa sổ là động và giao diện người dùng của ứng dụng phải điều chỉnh cho phù hợp.

Các lớp kích thước cửa sổ ánh xạ đến các điểm ngắt nhỏ gọn, trung bình và mở rộng trong phần tử Bố cục Material Design hướng dẫn. Sử dụng các lớp kích thước cửa sổ để đưa ra quyết định cấp cao về bố cục ứng dụng, chẳng hạn như quyết định xem có nên sử dụng một bố cục chuẩn cụ thể để tận dụng không gian màn hình bổ sung.

Bạn có thể tính toán giá trị WindowSizeClass sử dụng WindowSizeClass#compute() hàm do Jetpack cung cấp WindowManager. Ví dụ sau đây cho biết cách tính toán lớp kích thước cửa sổ và nhận thông tin cập nhật bất cứ khi nào các thay đổi về lớp kích thước cửa sổ:

Kotlin

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.
    }
}

Java

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.
    }
}

Kiểm thử các lớp kích thước cửa sổ

Khi bạn thay đổi bố cục, hãy kiểm thử hành vi bố cục trên tất cả các kích thước cửa sổ, đặc biệt là với chiều rộng điểm ngắt nhỏ gọn, trung bình và mở rộng.

Nếu bạn đã có sẵn bố cục cho màn hình thu gọn, trước tiên hãy tối ưu hoá bố cục cho lớp kích thước chiều rộng mở rộng, vì lớp kích thước này cung cấp nhiều không gian nhất cho những thay đổi bổ sung về nội dung và giao diện người dùng. Sau đó quyết định bố cục phù hợp lớp kích thước chiều rộng trung bình; hãy cân nhắc thêm một bố cục chuyên biệt.

Các bước tiếp theo

Để tìm hiểu thêm về cách sử dụng các lớp kích thước cửa sổ để tạo quảng cáo thích ứng bố cục, hãy xem như sau:

Để tìm hiểu thêm về những yếu tố tạo nên sức hút của một ứng dụng trên tất cả thiết bị và kích thước màn hình, xem: