বড় আনফোল্ড ডিসপ্লে এবং অনন্য ভাঁজ করা অবস্থাগুলি ভাঁজযোগ্য ডিভাইসগুলিতে নতুন ব্যবহারকারীর অভিজ্ঞতা সক্ষম করে। আপনার অ্যাপকে ভাঁজ সম্পর্কে সচেতন করতে, Jetpack WindowManager লাইব্রেরি ব্যবহার করুন, যা ভাঁজযোগ্য ডিভাইস উইন্ডো বৈশিষ্ট্য যেমন ভাঁজ এবং কব্জাগুলির জন্য একটি API পৃষ্ঠ প্রদান করে। যখন আপনার অ্যাপটি ভাঁজ সম্পর্কে সচেতন থাকে, তখন এটি ভাঁজ বা কব্জাগুলির এলাকায় গুরুত্বপূর্ণ বিষয়বস্তু স্থাপন এড়াতে এবং ভাঁজ এবং কব্জাগুলিকে প্রাকৃতিক বিভাজক হিসাবে ব্যবহার করতে এটির বিন্যাসকে মানিয়ে নিতে পারে।
একটি ডিভাইস ট্যাবলেটপ বা বইয়ের ভঙ্গি মত কনফিগারেশন সমর্থন করে কিনা তা বোঝা বিভিন্ন লেআউট সমর্থন বা নির্দিষ্ট বৈশিষ্ট্য প্রদানের বিষয়ে সিদ্ধান্তগুলিকে নির্দেশ করতে পারে।
উইন্ডো তথ্য
Jetpack WindowManager-এ WindowInfoTracker
ইন্টারফেস উইন্ডো লেআউট তথ্য প্রকাশ করে। ইন্টারফেসের windowLayoutInfo()
পদ্ধতিটি WindowLayoutInfo
ডেটার একটি স্ট্রীম ফেরত দেয় যা একটি ভাঁজযোগ্য ডিভাইসের ভাঁজ অবস্থা সম্পর্কে আপনার অ্যাপকে জানায়। WindowInfoTracker#getOrCreate()
পদ্ধতি WindowInfoTracker
এর একটি উদাহরণ তৈরি করে।
WindowManager Kotlin ফ্লো এবং জাভা কলব্যাক ব্যবহার করে WindowLayoutInfo
ডেটা সংগ্রহের জন্য সমর্থন প্রদান করে।
কোটলিন বয়ে যাচ্ছে
WindowLayoutInfo
ডেটা সংগ্রহ শুরু এবং বন্ধ করতে, আপনি একটি পুনঃসূচনাযোগ্য লাইফসাইকেল-সচেতন কোরোটিন ব্যবহার করতে পারেন যেখানে লাইফসাইকেল অন্তত STARTED
হলে repeatOnLifecycle
কোড ব্লক কার্যকর করা হয় এবং লাইফসাইকেল 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
নির্ভরতা-এ অন্তর্ভুক্ত কলব্যাক সামঞ্জস্যপূর্ণ স্তর আপনাকে 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 of 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
থেকে উত্তরাধিকারসূত্রে প্রাপ্ত) একটি ভাঁজ বা কব্জার মতো একটি ভাঁজ বৈশিষ্ট্যের বাউন্ডিং আয়তক্ষেত্রকে প্রতিনিধিত্ব করে। বৈশিষ্ট্যের সাথে সম্পর্কিত স্ক্রিনে উপাদানগুলির অবস্থানের জন্য সীমাগুলি ব্যবহার করা যেতে পারে:
কোটলিন
override fun onCreate(savedInstanceState: Bundle?) { ... lifecycleScope.launch(Dispatchers.Main) { lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { // Safely collects from WindowInfoTracker 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<FoldingFeature>() .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); }
একবার আপনি জানেন যে ডিভাইসটি ট্যাবলেটপ ভঙ্গিতে আছে, সেই অনুযায়ী আপনার অ্যাপ লেআউট আপডেট করুন। মিডিয়া অ্যাপ্লিকেশানগুলির জন্য, এর অর্থ সাধারণত হ্যান্ডস-ফ্রি দেখার বা শোনার অভিজ্ঞতার জন্য ভাঁজের উপরে প্লেব্যাক রাখা এবং অবস্থান নিয়ন্ত্রণ এবং সম্পূরক বিষয়বস্তু।
অ্যান্ড্রয়েড 15 (এপিআই লেভেল 35) এবং উচ্চতর, ডিভাইসের বর্তমান অবস্থা নির্বিশেষে একটি ডিভাইস ট্যাবলেটপ ভঙ্গি সমর্থন করে কিনা তা সনাক্ত করতে আপনি একটি সিঙ্ক্রোনাস API ব্যবহার করতে পারেন।
API ডিভাইস দ্বারা সমর্থিত অঙ্গবিন্যাসগুলির একটি তালিকা প্রদান করে। যদি তালিকায় ট্যাবলেটপ ভঙ্গি থাকে, তাহলে আপনি ভঙ্গি সমর্থন করতে আপনার অ্যাপ লেআউটকে বিভক্ত করতে পারেন এবং ট্যাবলেটপ এবং পূর্ণ-স্ক্রীন লেআউটের জন্য আপনার অ্যাপ UI-তে A/B পরীক্ষা চালাতে পারেন।
কোটলিন
if (WindowSdkExtensions.getInstance().extensionsVersion >= 6) { val postures = WindowInfoTracker.getOrCreate(context).supportedPostures if (postures.contains(TABLE_TOP)) { // Device supports tabletop posture. } }
জাভা
if (WindowSdkExtensions.getInstance().getExtensionVersion() >= 6) { List<SupportedPosture> postures = WindowInfoTracker.getOrCreate(context).getSupportedPostures(); if (postures.contains(SupportedPosture.TABLETOP)) { // Device supports tabletop posture. } }
উদাহরণ
MediaPlayerActivity
অ্যাপ: একটি ভাঁজ-সচেতন ভিডিও প্লেয়ার তৈরি করতে Media3 Exoplayer এবং WindowManager কীভাবে ব্যবহার করবেন তা দেখুন।Jetpack 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
ক্লাস আপনাকে বর্তমান এবং সর্বাধিক উইন্ডো মেট্রিক্স পুনরুদ্ধার করতে সক্ষম করে। এপিআই লেভেল 30 এ প্রবর্তিত প্ল্যাটফর্ম WindowMetrics
মত, WindowManager WindowMetrics
উইন্ডোর সীমানা প্রদান করে, কিন্তু API এপিআই লেভেল 14-এ পিছিয়ে সামঞ্জস্যপূর্ণ।
উইন্ডো সাইজ ক্লাস ব্যবহার করুন দেখুন।
অতিরিক্ত সম্পদ
নমুনা
- জেটপ্যাক উইন্ডো ম্যানেজার : জেটপ্যাক উইন্ডো ম্যানেজার লাইব্রেরি কীভাবে ব্যবহার করবেন তার উদাহরণ
- জেটকাস্টার : কম্পোজ সহ ট্যাবলেটপ ভঙ্গি বাস্তবায়ন
কোডল্যাব
- জেটপ্যাক উইন্ডো ম্যানেজার সহ ভাঁজযোগ্য এবং ডুয়াল-স্ক্রীন ডিভাইসগুলিকে সমর্থন করে
- Jetpack WindowManager দিয়ে ভাঁজ করা যায় এমন ডিভাইসে আপনার ক্যামেরা অ্যাপটি অপ্টিমাইজ করুন