Ứng dụng của bạn hoạt động tốt trên điện thoại ở hướng dọc, vậy nên bạn hạn chế ứng dụng chỉ ở chế độ dọc. Tuy nhiên, bạn có thể làm được nhiều việc hơn trên màn hình lớn theo hướng ngang.
Làm thế nào để bạn có thể sử dụng theo cả hai cách – nghĩa là hạn chế ứng dụng ở hướng dọc trên màn hình nhỏ, nhưng vẫn bật được hướng ngang trên màn hình lớn?
Hướng dẫn này là biện pháp tạm thời cho đến khi bạn có thể cải thiện ứng dụng của mình để cung cấp hỗ trợ đầy đủ cho tất cả các cấu hình thiết bị.
Quản lý hướng ứng dụng
Để bật hướng ngang trên màn hình lớn, hãy đặt tệp kê khai ứng dụng của bạn để xử lý các thay đổi về hướng theo mặc định. Trong thời gian chạy, hãy xác định kích thước cửa sổ ứng dụng. Nếu cửa sổ ứng dụng nhỏ, hãy hạn chế hướng ứng dụng bằng cách ghi đè chế độ cài đặt hướng của tệp kê khai.
1. Chỉ định tuỳ chọn cài đặt hướng trong tệp kê khai ứng dụng
Bạn có thể tránh khai báo phần tử screenOrientation
của tệp kê khai ứng dụng (trong trường hợp này, hướng được đặt mặc định thành unspecified
) hoặc đặt hướng màn hình thành fullUser
. Nếu người dùng chưa khoá chế độ xoay dựa trên cảm biến, ứng dụng của bạn sẽ hỗ trợ tất cả các hướng của thiết bị.
<activity
android:name=".MyActivity"
android:screenOrientation="fullUser">
Sự khác biệt giữa unspecified
và fullUser
là khó thấy nhưng quan trọng. Nếu bạn không khai báo một giá trị screenOrientation
, thì hệ thống sẽ chọn hướng và chính sách mà hệ thống sử dụng để xác định hướng có thể khác nhau giữa các thiết bị. Mặt khác, việc chỉ định fullUser
sẽ khớp chặt chẽ hơn với hành vi mà người dùng đã xác định cho thiết bị: nếu người dùng đã khoá tính năng xoay dựa trên cảm biến, thì ứng dụng sẽ tuân theo lựa chọn ưu tiên của người dùng; nếu không, hệ thống sẽ cho phép bất kỳ hướng màn hình nào trong số 4 hướng có thể có (dọc, ngang, dọc đảo ngược hoặc ngang đảo ngược). Hãy xem screenOrientation
.
2. Xác định kích thước màn hình
Với tệp kê khai được đặt để hỗ trợ tất cả các hướng được người dùng cho phép, bạn có thể chỉ định hướng ứng dụng theo phương thức lập trình dựa trên kích thước màn hình.
Thêm thư viện Jetpack WindowManager vào tệp build.gradle
hoặc build.gradle.kts
của mô-đun:
Kotlin
implementation("androidx.window:window:version
") implementation("androidx.window:window-core:version
")
Groovy
implementation 'androidx.window:window:version
' implementation 'androidx.window:window-core:version
'
Sử dụng phương thức WindowMetricsCalculator#computeMaximumWindowMetrics()
của Jetpack WindowManager để lấy kích thước màn hình thiết bị dưới dạng đối tượng WindowMetrics
. Bạn có thể so sánh các chỉ số của cửa sổ với lớp kích thước cửa sổ để quyết định thời điểm giới hạn hướng.
Lớp kích thước của Windows cung cấp các điểm ngắt giữa màn hình nhỏ và màn hình lớn.
Sử dụng các điểm ngắt WindowWidthSizeClass#COMPACT
và WindowHeightSizeClass#COMPACT
để xác định kích thước màn hình:
Kotlin
/** Determines whether the device has a compact screen. **/ fun compactScreen() : Boolean { val metrics = WindowMetricsCalculator.getOrCreate().computeMaximumWindowMetrics(this) val width = metrics.bounds.width() val height = metrics.bounds.height() val density = resources.displayMetrics.density val windowSizeClass = WindowSizeClass.compute(width/density, height/density) return windowSizeClass.windowWidthSizeClass == WindowWidthSizeClass.COMPACT || windowSizeClass.windowHeightSizeClass == WindowHeightSizeClass.COMPACT }
Java
/** Determines whether the device has a compact screen. **/ private boolean compactScreen() { WindowMetrics metrics = WindowMetricsCalculator.getOrCreate().computeMaximumWindowMetrics(this); int width = metrics.getBounds().width(); int height = metrics.getBounds().height(); float density = getResources().getDisplayMetrics().density; WindowSizeClass windowSizeClass = WindowSizeClass.compute(width/density, height/density); return windowSizeClass.getWindowWidthSizeClass() == WindowWidthSizeClass.COMPACT || windowSizeClass.getWindowHeightSizeClass() == WindowHeightSizeClass.COMPACT; }
- Lưu ý:
- Các ví dụ được triển khai dưới dạng phương thức của một hoạt động; và do đó, hoạt động được tham chiếu như
this
trong đối số củacomputeMaximumWindowMetrics()
. - Phương thức
computeMaximumWindowMetrics()
được dùng thay chocomputeCurrentWindowMetrics()
, vì bạn có thể chạy ứng dụng ở chế độ nhiều cửa sổ, nghĩa là bỏ qua chế độ cài đặt hướng màn hình. Chẳng có lý do gì phải xác định kích thước cửa sổ ứng dụng và ghi đè tuỳ chọn cài đặt hướng, trừ phi cửa sổ ứng dụng chiếm toàn bộ màn hình thiết bị.
Vui lòng xem WindowManager để biết hướng dẫn về cách khai báo các phần phụ thuộc nhằm cung cấp phương thức computeMaximumWindowMetrics()
cho ứng dụng của bạn.
3. Ghi đè chế độ cài đặt trong tệp kê khai ứng dụng
Khi đã xác định thiết bị có kích thước màn hình thu gọn, bạn có thể gọi Activity#setRequestedOrientation()
để ghi đè chế độ cài đặt screenOrientation
của tệp kê khai:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) requestedOrientation = if (compactScreen()) ActivityInfo.SCREEN_ORIENTATION_PORTRAIT else ActivityInfo.SCREEN_ORIENTATION_FULL_USER ... // 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) requestedOrientation = if (compactScreen()) ActivityInfo.SCREEN_ORIENTATION_PORTRAIT else ActivityInfo.SCREEN_ORIENTATION_FULL_USER } }) }
Java
@Override protected void onCreate(Bundle savedInstance) { super.onCreate(savedInstanceState); if (compactScreen()) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } else { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_USER); } ... // 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); if (compactScreen()) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } else { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_USER); } } }); }
Bằng cách thêm logic vào phương thức onCreate()
và View.onConfigurationChanged()
, bạn có thể thu được các chỉ số cửa sổ tối đa và ghi đè chế độ cài đặt hướng bất cứ khi nào hoạt động được đổi kích thước hoặc di chuyển giữa các màn hình hiển thị, chẳng hạn như sau khi xoay thiết bị hoặc khi một thiết bị có thể gập lại được gập hoặc mở ra.
Để biết thêm thông tin về thời điểm diễn ra các thay đổi về cấu hình và thời điểm các thay đổi đó dẫn đến việc tạo lại hoạt động, hãy tham khảo bài viết Xử lý các thay đổi về cấu hình.
Điểm chính
screenOrientation
: Tuỳ chọn cài đặt tệp kê khai ứng dụng cho phép bạn chỉ định cách ứng dụng của bạn phản hồi các thay đổi về hướng trên thiết bị- Jetpack WindowManager: Tập hợp các thư viện cho phép bạn xác định kích thước và tỷ lệ khung hình của cửa sổ ứng dụng; tương thích ngược với API cấp 14
Activity#setRequestedOrientation()
: Phương thức mà bạn có thể thay đổi hướng ứng dụng trong thời gian chạy
Kết quả
Ứng dụng của bạn vẫn nằm ở hướng dọc trên màn hình nhỏ bất kể thiết bị có xoay hướng nào. Trên màn hình lớn, ứng dụng sẽ hỗ trợ cả hướng ngang lẫn hướng dọc.
Các bộ sưu tập chứa hướng dẫn này
Hướng dẫn này là một phần của các bộ sưu tập Hướng dẫn nhanh được tuyển chọn này, bao gồm các mục tiêu phát triển Android rộng hơn:
![](https://developer.android.com/static/images/quick-guides/collection-illustration.png?hl=vi)