फ़ोल्ड किए जा सकने वाले बड़े डिसप्ले और फ़ोल्ड किए गए खास स्टेटस की वजह से, नए उपयोगकर्ताओं को फ़ोल्ड किए जा सकने वाले डिवाइसों का इस्तेमाल करना आसान हो जाता है. अपने ऐप्लिकेशन को फ़ोल्ड करने की जानकारी देने के लिए, Jetpack WindowManager लाइब्रेरी का इस्तेमाल करें. यह लाइब्रेरी, फ़ोल्ड और हिंज जैसी फ़ोल्ड किए जा सकने वाले डिवाइस की विंडो सुविधाओं के लिए, एपीआई सरफ़ेस उपलब्ध कराती है. अगर आपका ऐप्लिकेशन फ़ोल्ड किए जा सकने वाले डिवाइस पर मौजूद है, तो यह लेआउट में बदलाव कर सकता है, ताकि ज़रूरी कॉन्टेंट को फ़ोल्ड या हिंज वाली जगह पर न रखा जाए. साथ ही, फ़ोल्ड और हिंज का इस्तेमाल नैचुरल सेपरेटर के तौर पर किया जा सके.
विंडो की जानकारी
Jetpack WindowManager का WindowInfoTracker
इंटरफ़ेस, विंडो के लेआउट की जानकारी दिखाता है. इंटरफ़ेस का windowLayoutInfo()
तरीका, WindowLayoutInfo
डेटा दिखाता है. इससे आपके ऐप्लिकेशन को फ़ोल्ड किए जा सकने वाले डिवाइस के फ़ोल्ड होने की स्थिति के बारे में जानकारी मिलती है. WindowInfoTracker
getOrCreate()
वाला तरीका, WindowInfoTracker
का एक इंस्टेंस बनाता है.
WindowManager, Kotlin फ़्लो और Java कॉलबैक का इस्तेमाल करके, WindowLayoutInfo
का डेटा इकट्ठा करने में मदद करता है.
Kotlin फ़्लो
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.
}
}
}
}
}
Java कॉलबैक
androidx.window:window-java
डिपेंडेंसी में शामिल कॉलबैक के साथ काम करने की सुविधा लेयर की मदद से, आपको Kotlin फ़्लो का इस्तेमाल किए बिना, WindowLayoutInfo
के अपडेट इकट्ठा करने की सुविधा मिलती है. आर्टफ़ैक्ट में WindowInfoTrackerCallbackAdapter
क्लास शामिल है. यह WindowLayoutInfo
अपडेट पाने के लिए, WindowInfoTracker
को कोड के फ़ॉर्मैट में बदलता है, ताकि रजिस्टर करने (और रजिस्ट्रेशन रद्द करने) की सुविधा काम कर सके. उदाहरण के लिए:
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
) का इस्तेमाल किया जा रहा है, तो उन आर्टफ़ैक्ट का फ़ायदा लिया जा सकता है जिनसे आपको Kotlin फ़्लो का इस्तेमाल किए बिना, WindowLayoutInfo
अपडेट इकट्ठा करने के लिए Observable
या Flowable
की सुविधा मिलती है.
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()
}
}
फ़ोल्ड किए जा सकने वाले डिसप्ले की सुविधाएं
Jetpack WindowManager की WindowLayoutInfo
क्लास, डिसप्ले विंडो की सुविधाओं को DisplayFeature
एलिमेंट के तौर पर उपलब्ध कराती है.
FoldingFeature
एक तरह का DisplayFeature
है, जो फ़ोल्ड किए जा सकने वाले डिसप्ले के बारे में जानकारी देता है. इसमें, यह भी शामिल है:
state
: डिवाइस को फ़ोल्ड किया गया होने की स्थिति,FLAT
याHALF_OPENED
orientation
: फ़ोल्ड या हिंज का ओरिएंटेशन,HORIZONTAL
याVERTICAL
occlusionType
: क्या फ़ोल्ड या हिंज, डिसप्ले का कोई हिस्सा छिपाता है,NONE
याFULL
isSeparating
: फ़ोल्ड या हिंज में दो लॉजिकल डिसप्ले एरिया होते हैं, चाहे वह सही हो या गलत
फ़ोल्ड किया जा सकने वाला डिवाइस, जो HALF_OPENED
है वह हमेशा isSeparating
को 'सही' के तौर पर दिखाता है. ऐसा इसलिए होता है, क्योंकि स्क्रीन को दो डिसप्ले एरिया में बांटा जाता है. साथ ही, जब ऐप्लिकेशन दोनों स्क्रीन पर मौजूद हो, तो दो स्क्रीन वाले डिवाइस पर isSeparating
हमेशा सही होता है.
FoldingFeature
bounds
प्रॉपर्टी (DisplayFeature
से इनहेरिट की गई) फ़ोल्ड या हिंज जैसी फ़ोल्डिंग सुविधा का बाउंडिंग रेक्टैंगल दिखाती है. सीमाओं का इस्तेमाल, सुविधा के हिसाब से स्क्रीन पर एलिमेंट को पोज़िशन करने के लिए किया जा सकता है.
Kotlin
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 } } } }
Java
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
यह पता करने के लिए कि डिवाइस टेबलटॉप मोड में है या नहीं:
Kotlin
fun isTableTopPosture(foldFeature : FoldingFeature?) : Boolean { contract { returns(true) implies (foldFeature != null) } return foldFeature?.state == FoldingFeature.State.HALF_OPENED && foldFeature.orientation == FoldingFeature.Orientation.HORIZONTAL }
Java
boolean isTableTopPosture(FoldingFeature foldFeature) { return (foldFeature != null) && (foldFeature.getState() == FoldingFeature.State.HALF_OPENED) && (foldFeature.getOrientation() == FoldingFeature.Orientation.HORIZONTAL); }
जब आपको पता चल जाए कि डिवाइस टेबलटॉप मोड में है, तब ऐप्लिकेशन का लेआउट उसी हिसाब से अपडेट करें. मीडिया ऐप्लिकेशन के लिए, आम तौर पर इसका मतलब वीडियो को पेज के ऊपरी हिस्से में रखना होता है और फ़ोन को छुए बिना वीडियो देखने या सुनने का अनुभव देने के लिए, पोज़िशनिंग कंट्रोल और सप्लीमेंटल कॉन्टेंट नीचे दिए गए हैं.
उदाहरण
MediaPlayerActivity
ऐप्लिकेशन: जानें कि Media3 Exoplayer और WindowManager. इससे, फ़ोल्ड के हिसाब से वीडियो प्लेयर बनाया जा सकता है.कैमरे के अनुभव को बेहतर बनाएं कोडलैब: फ़ोटोग्राफ़ी ऐप्लिकेशन के लिए टेबलटॉप मोड को लागू करने का तरीका जानें. व्यूफ़ाइंडर को स्क्रीन के ऊपरी आधे हिस्से में, पेज के ऊपरी हिस्से में, और निचले आधे हिस्से में, कंट्रोल को फ़ोल्ड के नीचे दिखाएं.
बुक मोड
फ़ोल्ड किया जा सकने वाला एक और यूनीक पॉस्चर, बुक मोड है. इसमें डिवाइस आधा खुला रहता है और हिंज वर्टिकल होता है. ई-बुक पढ़ने के लिए, बुक मोड सबसे अच्छा विकल्प है. दो पेज वाले फ़ोल्ड किए जा सकने वाले डिवाइस का लेआउट, जो बाउंड बुक की तरह है. बुक मोड में आपको बेहतरीन अनुभव मिलता है एक असली किताब पढ़ी जा सकती है.
अगर आपको बोलकर फ़ोटो लेते समय कोई दूसरा आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) कैप्चर करना है, तो फ़ोटोग्राफ़ी के लिए भी इसका इस्तेमाल किया जा सकता है.
बुक मोड को, टेबलटॉप मोड के लिए इस्तेमाल की जाने वाली तकनीकों के साथ लागू करें. अंतर सिर्फ़ यह है कि कोड में यह जांच करनी चाहिए कि फ़ोल्डिंग सुविधा का ओरिएंटेशन, हॉरिज़ॉन्टल के बजाय वर्टिकल है:
Kotlin
fun isBookPosture(foldFeature : FoldingFeature?) : Boolean { contract { returns(true) implies (foldFeature != null) } return foldFeature?.state == FoldingFeature.State.HALF_OPENED && foldFeature.orientation == FoldingFeature.Orientation.VERTICAL }
Java
boolean isBookPosture(FoldingFeature foldFeature) { return (foldFeature != null) && (foldFeature.getState() == FoldingFeature.State.HALF_OPENED) && (foldFeature.getOrientation() == FoldingFeature.Orientation.VERTICAL); }
विंडो के साइज़ में बदलाव
डिवाइस कॉन्फ़िगरेशन में बदलाव होने पर, ऐप्लिकेशन का डिसप्ले एरिया बदल सकता है. उदाहरण के लिए, डिवाइस को फ़ोल्ड या अनफ़ोल्ड करने, घुमाने पर या मल्टी-विंडो मोड में किसी विंडो का साइज़ बदलने पर.
Jetpack WindowManager WindowMetricsCalculator
क्लास की मदद से, विंडो की मौजूदा और ज़्यादा से ज़्यादा मेट्रिक फिर से हासिल की जा सकती हैं. एपीआई लेवल 30 में पेश किए गए प्लैटफ़ॉर्म WindowMetrics
की तरह ही, WindowManager WindowMetrics
भी विंडो की सीमाएं उपलब्ध कराता है. हालांकि, एपीआई लेवल 14 तक, पुराने सिस्टम के साथ काम करता है.
विंडो साइज़ की क्लास देखें.
अन्य संसाधन
सैंपल
- Jetpack WindowManager: Jetpack WindowManager लाइब्रेरी को इस्तेमाल करने का उदाहरण
- Jetcaster: Compose की मदद से टेबलटॉप पॉस्चर को लागू करना
कोड लैब
- Jetpack WindowManager की मदद से, फ़ोल्ड किए जा सकने वाले और ड्यूअल-स्क्रीन डिवाइस इस्तेमाल किए जा सकते हैं
- कैमरे के साथ मिलने वाली सुविधाओं को बेहतर बनाएं