Sử dụng các lớp kích thước cửa sổ

Thử cách dùng Compose
Jetpack Compose là bộ công cụ giao diện người dùng được đề xuất cho Android. Tìm hiểu cách sử dụng các lớp kích thước cửa sổ trong Compose.

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ó ý kiến giúp bạn thiết kế, phát triển và thử nghiệm các bố cục thích ứng/đáp ứng. Các điểm ngắt tạo sự cân bằng giữa tính đơn giản và linh hoạt của bố cục nhằm 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ổ phân loại khu vực hiển thị có sẵn cho ứng dụng của bạn là 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 cũng có hai lớp kích thước cửa sổ — một cho chiều rộng và một cho chiều cao. Chiều rộng có sẵn thường quan trọng hơn chiều cao do sự cuộn ngang đang hiển thị; do đó, loại kích thước cửa sổ chiều rộng có thể sẽ 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ư hình minh hoạ trong các hình, các điểm ngắt cho phép bạn tiếp tục cân nhắc về bố cục theo các 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

hầu hết màn hình lớn bên trong ở chế độ dọc khi chưa gập

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

hầu hết màn hình lớn bên trong ở chế độ ngang khi chưa gập

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 các lớp kích thước cửa sổ không được xác định rõ ràng theo kích thước của màn hình thiết bị. Các lớp kích thước cửa sổ không dành cho logic loại isTablet. Thay vào đó, các lớp kích thước cửa sổ được xác định theo kích thước cửa sổ có sẵn cho ứng dụng của bạn, bất kể loại thiết bị mà ứng dụng đang chạy trên đó. Điều này gây ra hai hậu quả quan trọ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ể. 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ổ loại máy tính 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. Trong khi ứng dụng đang chạy, sự thay đổi hướng thiết bị, làm nhiều việc cùng lúc hoặc gập/mở có thể thay đổi lượng không gian màn hình có sẵn. Do đó, 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 thích ứng tương ứng.

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

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 thử nghiệm hành vi của bố cục trên tất cả các kích thước cửa sổ, đặc biệt là ở chiều rộng điểm ngắt nhỏ, trung bình và mở rộng.

Nếu có một bố cục cho các màn hình nhỏ hơn, hãy tối ưu hoá bố cục cho lớp kích thước chiều rộng mở rộng đầu tiên vì lớp kích thước này cung cấp nhiều không gian nhất để hiển thị thêm nội dung hoặc thực hiện những thay đổi Giao diện người dùng khác. Sau đó, hãy quyết định bố cục phù hợp với lớp kích thước chiều rộng trung bình; 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 bố cục thích ứng/thích ứng, hãy xem những nội dung sau:

Để tìm hiểu thêm về những yếu tố giúp ứng dụng đạt hiệu quả cao trên tất cả các thiết bị và kích thước màn hình, hãy xem: