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.
![](https://developer.android.com/static/develop/ui/compose/images/layouts/adaptive/window-size-classes/window_size_classes_width.png?authuser=9&hl=vi)
![](https://developer.android.com/static/develop/ui/compose/images/layouts/adaptive/window-size-classes/window_size_classes_height.png?authuser=9&hl=vi)
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:
Đối với bố cục dựa trên Compose: Hỗ trợ nhiều kích thước màn hình
Đối với bố cục dựa trên khung hiển thị: Thiết kế đáp ứng/thích ứng với khung hiển thị
Để 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: