نمایشگرهای تاشو بزرگ و حالتهای تا شده منحصر به فرد، تجربه کاربری جدیدی را در دستگاههای تاشو امکانپذیر میسازد. برای آگاه کردن برنامه خود، از کتابخانه Jetpack WindowManager استفاده کنید، که یک سطح API برای ویژگیهای پنجره دستگاه تاشو مانند تا و لولا ارائه میدهد. وقتی برنامه شما از تا کردن آگاه باشد، میتواند طرحبندی خود را برای جلوگیری از قرار دادن محتوای مهم در ناحیه چینها یا لولاها تنظیم کند و از چینها و لولاها به عنوان جداکننده طبیعی استفاده کند.
اطلاعات پنجره
رابط WindowInfoTracker
در Jetpack WindowManager اطلاعات طرح بندی پنجره را در معرض دید قرار می دهد. متد windowLayoutInfo()
واسط جریانی از دادههای WindowLayoutInfo
را برمیگرداند که برنامه شما را در مورد وضعیت فولد دستگاه تاشو مطلع میکند. متد WindowInfoTracker
getOrCreate()
نمونه ای از WindowInfoTracker
را ایجاد می کند.
WindowManager برای جمع آوری داده های WindowLayoutInfo
با استفاده از Kotlin Flow و callbacks جاوا پشتیبانی می کند.
کاتلین فلوس
برای شروع و توقف جمعآوری دادههای WindowLayoutInfo
، میتوانید از یک برنامه راهاندازی مجدد با آگاهی از چرخه حیات استفاده کنید که در آن بلوک کد repeatOnLifecycle
زمانی اجرا میشود که چرخه حیات حداقل STARTED
است و STOPPED
چرخه حیات متوقف میشود. اجرای بلوک کد به طور خودکار با STARTED
چرخه حیات مجدداً شروع می شود. در مثال زیر، بلوک کد داده های WindowLayoutInfo
را جمع آوری و استفاده می کند:
class DisplayFeaturesActivity : AppCompatActivity() {
private lateinit var binding: ActivityDisplayFeaturesBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityDisplayFeaturesBinding.inflate(layoutInflater)
setContentView(binding.root)
lifecycleScope.launch(Dispatchers.Main) {
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
WindowInfoTracker.getOrCreate(this@DisplayFeaturesActivity)
.windowLayoutInfo(this@DisplayFeaturesActivity)
.collect { newLayoutInfo ->
// Use newLayoutInfo to update the layout.
}
}
}
}
}
تماس های جاوا
لایه سازگاری پاسخ به تماس موجود در وابستگی androidx.window:window-java
به شما امکان میدهد بهروزرسانیهای WindowLayoutInfo
را بدون استفاده از Kotlin Flow جمعآوری کنید. این آرتیفکت شامل کلاس WindowInfoTrackerCallbackAdapter
است که یک WindowInfoTracker
را برای پشتیبانی از ثبت (و لغو ثبت) تماسها برای دریافت بهروزرسانیهای WindowLayoutInfo
تطبیق میدهد، به عنوان مثال:
public class SplitLayoutActivity extends AppCompatActivity {
private WindowInfoTrackerCallbackAdapter windowInfoTracker;
private ActivitySplitLayoutBinding binding;
private final LayoutStateChangeCallback layoutStateChangeCallback =
new LayoutStateChangeCallback();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivitySplitLayoutBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
windowInfoTracker =
new WindowInfoTrackerCallbackAdapter(WindowInfoTracker.getOrCreate(this));
}
@Override
protected void onStart() {
super.onStart();
windowInfoTracker.addWindowLayoutInfoListener(
this, Runnable::run, layoutStateChangeCallback);
}
@Override
protected void onStop() {
super.onStop();
windowInfoTracker
.removeWindowLayoutInfoListener(layoutStateChangeCallback);
}
class LayoutStateChangeCallback implements Consumer<WindowLayoutInfo> {
@Override
public void accept(WindowLayoutInfo newLayoutInfo) {
SplitLayoutActivity.this.runOnUiThread( () -> {
// Use newLayoutInfo to update the layout.
});
}
}
}
پشتیبانی از RxJava
اگر از RxJava
(نسخه 2
یا 3
) استفاده می کنید، می توانید از مصنوعاتی استفاده کنید که به شما امکان می دهد از Observable
یا Flowable
برای جمع آوری به روز رسانی های WindowLayoutInfo
بدون استفاده از Kotlin Flow استفاده کنید.
لایه سازگاری ارائه شده توسط وابستگیهای androidx.window:window-rxjava2
و androidx.window:window-rxjava3
شامل متدهای WindowInfoTracker#windowLayoutInfoFlowable()
و WindowInfoTracker#windowLayoutInfoObservable()
میشود که به روز رسانی، برنامه را برای WindowLayoutInfo
میتواند دریافت کند.
class RxActivity: AppCompatActivity {
private lateinit var binding: ActivityRxBinding
private var disposable: Disposable? = null
private lateinit var observable: Observable<WindowLayoutInfo>
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivitySplitLayoutBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
// Create a new observable
observable = WindowInfoTracker.getOrCreate(this@RxActivity)
.windowLayoutInfoObservable(this@RxActivity)
}
@Override
protected void onStart() {
super.onStart();
// Subscribe to receive WindowLayoutInfo updates
disposable?.dispose()
disposable = observable
.observeOn(AndroidSchedulers.mainThread())
.subscribe { newLayoutInfo ->
// Use newLayoutInfo to update the layout
}
}
@Override
protected void onStop() {
super.onStop();
// Dispose the WindowLayoutInfo observable
disposable?.dispose()
}
}
ویژگی های نمایشگرهای تاشو
کلاس WindowLayoutInfo
از Jetpack WindowManager ویژگی های یک پنجره نمایش را به عنوان لیستی از عناصر DisplayFeature
در دسترس قرار می دهد.
FoldingFeature
نوعی از DisplayFeature
است که اطلاعاتی در مورد نمایشگرهای تاشو ارائه می دهد، از جمله موارد زیر:
-
state
: حالت تا شده دستگاه،FLAT
یاHALF_OPENED
-
orientation
: جهت چین یا لولا،HORIZONTAL
یاVERTICAL
-
occlusionType
: چه تاشو یا لولا قسمتی از نمایشگر را پنهان کند،NONE
یاFULL
-
isSeparating
: این که آیا تاشو یا لولا دو ناحیه نمایش منطقی ایجاد می کند، درست یا نادرست
یک دستگاه تاشو که HALF_OPENED
است همیشه isSeparating
به عنوان درست گزارش می دهد زیرا صفحه نمایش به دو ناحیه نمایشگر جدا شده است. همچنین، isSeparating
همیشه در دستگاههای دو صفحهنمایش درست است، زمانی که برنامه در هر دو صفحه باشد.
ویژگی FoldingFeature
bounds
(که از DisplayFeature
به ارث رسیده است) مستطیل محدود کننده یک ویژگی تاشو مانند یک تا یا لولا را نشان می دهد. از کران ها می توان برای قرار دادن عناصر روی صفحه نسبت به ویژگی استفاده کرد.
کاتلین
override fun onCreate(savedInstanceState: Bundle?) { ... lifecycleScope.launch(Dispatchers.Main) { lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { // Safely collects from windowInfoRepo when the lifecycle is STARTED // and stops collection when the lifecycle is STOPPED WindowInfoTracker.getOrCreate(this@MainActivity) .windowLayoutInfo(this@MainActivity) .collect { layoutInfo -> // New posture information val foldingFeature = layoutInfo.displayFeatures .filterIsInstance() .firstOrNull() // Use information from the foldingFeature object } } } }
جاوا
private WindowInfoTrackerCallbackAdapter windowInfoTracker; private final LayoutStateChangeCallback layoutStateChangeCallback = new LayoutStateChangeCallback(); @Override protected void onCreate(@Nullable Bundle savedInstanceState) { ... windowInfoTracker = new WindowInfoTrackerCallbackAdapter(WindowInfoTracker.getOrCreate(this)); } @Override protected void onStart() { super.onStart(); windowInfoTracker.addWindowLayoutInfoListener( this, Runnable::run, layoutStateChangeCallback); } @Override protected void onStop() { super.onStop(); windowInfoTracker.removeWindowLayoutInfoListener(layoutStateChangeCallback); } class LayoutStateChangeCallback implements Consumer<WindowLayoutInfo> { @Override public void accept(WindowLayoutInfo newLayoutInfo) { // Use newLayoutInfo to update the Layout List<DisplayFeature> displayFeatures = newLayoutInfo.getDisplayFeatures(); for (DisplayFeature feature : displayFeatures) { if (feature instanceof FoldingFeature) { // Use information from the feature object } } } }
حالت رومیزی
با استفاده از اطلاعات موجود در شی FoldingFeature
، برنامه شما میتواند از حالتهایی مانند حالت رومیزی پشتیبانی کند، جایی که تلفن روی یک سطح قرار میگیرد، لولا در حالت افقی قرار دارد و صفحه نمایش تاشو نیمه باز است.
حالت رومیزی به کاربران این امکان را می دهد که با گوشی خود بدون در دست گرفتن گوشی کار کنند. حالت رومیزی برای تماشای رسانه، گرفتن عکس و برقراری تماس ویدیویی عالی است.
از FoldingFeature.State
و FoldingFeature.Orientation
برای تعیین اینکه آیا دستگاه در حالت رومیزی است یا نه استفاده کنید:
کاتلین
fun isTableTopPosture(foldFeature : FoldingFeature?) : Boolean { contract { returns(true) implies (foldFeature != null) } return foldFeature?.state == FoldingFeature.State.HALF_OPENED && foldFeature.orientation == FoldingFeature.Orientation.HORIZONTAL }
جاوا
boolean isTableTopPosture(FoldingFeature foldFeature) { return (foldFeature != null) && (foldFeature.getState() == FoldingFeature.State.HALF_OPENED) && (foldFeature.getOrientation() == FoldingFeature.Orientation.HORIZONTAL); }
هنگامی که متوجه شدید دستگاه در حالت رومیزی است، طرح بندی برنامه خود را مطابق با آن به روز کنید. برای برنامههای رسانه، این معمولاً به معنای قرار دادن پخش در بالای صفحه و کنترلهای موقعیتیابی و محتوای تکمیلی در زیر آن است تا تجربه تماشا یا گوش دادن بدون هندز را داشته باشید.
نمونه ها
برنامه
MediaPlayerActivity
: نحوه استفاده از Media3 Exoplayer و WindowManager برای ایجاد یک پخش کننده ویدیویی تاشو را ببینید.کد لبه تجربه دوربین خود را باز کنید : نحوه پیاده سازی حالت رومیزی برای برنامه های عکاسی را بیاموزید. منظره یاب را در نیمه بالایی صفحه، بالای تاشو، و کنترلها را در نیمه پایین، زیر تاشو نشان دهید.
حالت کتاب
حالت تاشوی منحصر به فرد دیگر حالت کتاب است که در آن دستگاه نیمه باز است و لولا عمودی است. حالت کتاب برای خواندن کتاب های الکترونیکی عالی است. با طرحبندی دو صفحهای روی صفحهنمایش بزرگ که مانند کتاب صحافی شده قابل تاشو است، حالت کتاب تجربه خواندن یک کتاب واقعی را به تصویر میکشد.
اگر میخواهید هنگام عکسبرداری بدون هندز، نسبت ابعاد متفاوتی را ثبت کنید، میتواند برای عکاسی نیز استفاده شود.
با همان تکنیک هایی که برای حالت رومیزی استفاده می شود، حالت کتاب را پیاده سازی کنید. تنها تفاوت این است که کد باید بررسی کند که جهت ویژگی تاشو به جای افقی عمودی باشد:
کاتلین
fun isBookPosture(foldFeature : FoldingFeature?) : Boolean { contract { returns(true) implies (foldFeature != null) } return foldFeature?.state == FoldingFeature.State.HALF_OPENED && foldFeature.orientation == FoldingFeature.Orientation.VERTICAL }
جاوا
boolean isBookPosture(FoldingFeature foldFeature) { return (foldFeature != null) && (foldFeature.getState() == FoldingFeature.State.HALF_OPENED) && (foldFeature.getOrientation() == FoldingFeature.Orientation.VERTICAL); }
اندازه پنجره تغییر می کند
ناحیه نمایش یک برنامه میتواند در نتیجه تغییر پیکربندی دستگاه تغییر کند—مثلاً وقتی دستگاه تا شده یا باز میشود، میچرخد یا اندازه یک پنجره در حالت چند پنجرهای تغییر میکند.
کلاس Jetpack WindowManager WindowMetricsCalculator
شما را قادر می سازد تا معیارهای فعلی و حداکثر پنجره را بازیابی کنید. مانند پلتفرم WindowMetrics
که در سطح API 30 معرفی شده است، WindowManager WindowMetrics
محدودیت های پنجره را ارائه می دهد، اما API تا سطح API 14 سازگار است.
کلاس های اندازه پنجره را ببینید.
منابع اضافی
نمونه ها
- Jetpack WindowManager : مثالی از نحوه استفاده از کتابخانه Jetpack WindowManager
- Jetcaster : اجرای وضعیت قرارگیری روی میز با Compose
Codelabs
{% کلمه به کلمه %}برای شما توصیه می شود
- توجه: وقتی جاوا اسکریپت خاموش است، متن پیوند نمایش داده می شود
- با Jetpack WindowManager از دستگاه های تاشو و دو صفحه پشتیبانی کنید
- برنامه دوربین خود را در دستگاه های تاشو با Jetpack WindowManager بهینه کنید
- حالت سازگاری دستگاه