Views থেকে Compose-এ মাইগ্রেট করা সম্পূর্ণ UI-সম্পর্কিত হলেও, নিরাপদ ও ইনক্রিমেন্টাল মাইগ্রেশন করার জন্য অনেক কিছু বিবেচনা করতে হয়। এই পৃষ্ঠায় আপনার ভিউ-ভিত্তিক অ্যাপকে Compose-এ মাইগ্রেট করার সময় কিছু বিষয় বিবেচনা করতে হবে।
আপনার অ্যাপের থিম মাইগ্রেট করা
Android অ্যাপের থিমিংয়ের জন্য মেটেরিয়াল ডিজাইন হল সাজেস্ট করা ডিজাইন সিস্টেম।
ভিউ-ভিত্তিক অ্যাপের জন্য, Material-এর তিনটি ভার্সন উপলভ্য:
- Material Design 1 যা
AppCompat লাইব্রেরি ব্যবহার করে (যেমন,
Theme.AppCompat.*) -
MDC-Android
লাইব্রেরি (যেমন,
Theme.MaterialComponents.*) ব্যবহার করে Material Design 2 -
MDC-Android
লাইব্রেরি (যেমন,
Theme.Material3.*) ব্যবহার করে Material Design 3
Compose অ্যাপের জন্য, Material-এর দুটি ভার্সন উপলভ্য:
-
Compose Material লাইব্রেরি ব্যবহার করে Material Design 2
(যেমন,
androidx.compose.material.MaterialTheme) -
Compose Material 3 লাইব্রেরি ব্যবহার করে Material Design 3
(যেমন,
androidx.compose.material3.MaterialTheme)
আপনার অ্যাপের ডিজাইন সিস্টেম লেটেস্ট ভার্সন (Material 3) ব্যবহার করার মতো অবস্থায় থাকলে, আমরা সেটি ব্যবহার করার সাজেশন দিই। Views ও Compose, দু'টির জন্যই মাইগ্রেশন গাইড উপলভ্য:
- ভিউতে মেটেরিয়াল ১ থেকে মেটেরিয়াল ২
- ভিউতে Material 2 থেকে Material 3
- Compose-এ Material 2 থেকে Material 3
Compose-এ নতুন স্ক্রিন তৈরি করার সময়, আপনি Material
Design-এর যে ভার্সনই ব্যবহার করুন না কেন, নিশ্চিত করুন যে Compose Material লাইব্রেরি থেকে UI এমিট করে এমন যেকোনও
কম্পোজ করার মতো আইটেমের আগে আপনি একটি MaterialTheme প্রয়োগ করেছেন। MaterialTheme না থাকলে মেটেরিয়াল
কম্পোনেন্ট (Button, Text, ইত্যাদি) কাজ করে না
এবং এর আচরণ কেমন হবে তা বলা যায় না।
সব
Jetpack Compose স্যাম্পেল
MaterialTheme-এর উপরে তৈরি কাস্টম Compose থিম ব্যবহার করে।
আরও জানতে Compose-এ ডিজাইন সিস্টেম ও XML থিমকে Compose-এ মাইগ্রেট করা দেখুন।
নেভিগেশন
আপনার অ্যাপে নেভিগেশন কম্পোনেন্ট ব্যবহার করলে, আরও তথ্যের জন্য ফ্র্যাগমেন্ট-ভিত্তিক অ্যাপে Compose থেকে নেভিগেট করা এবং Jetpack নেভিগেশনকে নেভিগেশন Compose-এ মাইগ্রেট করা দেখুন।
আপনার মিক্সড Compose/Views UI পরীক্ষা করুন
আপনার অ্যাপের কিছু অংশ Compose-এ মাইগ্রেট করার পরে, আপনি কিছু ভেঙে দেননি তা নিশ্চিত করতে পরীক্ষা করা অত্যন্ত গুরুত্বপূর্ণ।
কোনও অ্যাক্টিভিটি বা ফ্র্যাগমেন্ট Compose ব্যবহার করলে, আপনাকে ActivityScenarioRule ব্যবহার করার পরিবর্তে
createAndroidComposeRule
ব্যবহার করতে হবে। createAndroidComposeRule ইন্টিগ্রেট করে
ActivityScenarioRule ComposeTestRuleযার মাধ্যমে আপনি Compose এবং
View কোড একই সাথে টেস্ট করতে পারেন।
class MyActivityTest { @Rule @JvmField val composeTestRule = createAndroidComposeRule<MyActivity>() @Test fun testGreeting() { val greeting = InstrumentationRegistry.getInstrumentation() .targetContext.resources.getString(R.string.greeting) composeTestRule.onNodeWithText(greeting).assertIsDisplayed() } }
পরীক্ষা সম্পর্কে আরও জানতে আপনার কম্পোজ লেআউট পরীক্ষা করা দেখুন। UI টেস্টিং ফ্রেমওয়ার্কের সাথে ইন্টারঅপারেবিলিটি সম্পর্কে জানতে, Espresso-এর সাথে ইন্টারঅপারেবিলিটি এবং UiAutomator-এর সাথে ইন্টারঅপারেবিলিটি দেখুন।
আপনার আগে থেকে থাকা অ্যাপ আর্কিটেকচারের সাথে Compose ইন্টিগ্রেট করা
একমুখী ডেটা ফ্লো (UDF) আর্কিটেকচার প্যাটার্ন Compose-এর সাথে নির্বিঘ্নে কাজ করে। অ্যাপটি যদি মডেল ভিউ প্রেজেন্টার (MVP)-এর মতো অন্য ধরনের আর্কিটেকচার প্যাটার্ন ব্যবহার করে, তাহলে আমরা সাজেস্ট করি যে, Compose গ্রহণ করার আগে বা সেই সময় UI-এর সেই অংশটি UDF-এ মাইগ্রেট করুন।
কম্পোজে ViewModel ব্যবহার করা
আপনি Architecture Components
ViewModel লাইব্রেরি ব্যবহার করলে, viewModel()
ফাংশন কল করে যেকোনও কম্পোজ করার উপযুক্ত আইটেম থেকে
ViewModel অ্যাক্সেস করতে পারবেন, যেমন Compose ও অন্যান্য লাইব্রেরি নিবন্ধে ব্যাখ্যা করা হয়েছে।
Compose গ্রহণ করার সময়, বিভিন্ন কম্পোজেবলে একই ViewModel ধরন ব্যবহার করা
সম্পর্কে সতর্ক থাকুন, কারণ ViewModel এলিমেন্ট View-লাইফসাইকেল স্কোপ অনুসরণ করে। নেভিগেশন লাইব্রেরি ব্যবহার করা হলে, স্কোপ হবে হোস্ট অ্যাক্টিভিটি, ফ্র্যাগমেন্ট বা নেভিগেশন গ্রাফ।
যেমন, কম্পোজ করার উপযুক্ত আইটেম কোনও অ্যাক্টিভিটিতে হোস্ট করা হলে, viewModel()সবসময়
একই ইনস্ট্যান্স রিটার্ন করে যা অ্যাক্টিভিটি শেষ হলেই শুধু মুছে যায়।
নিচের উদাহরণে, একই ব্যবহারকারী ("user1") দু'বার স্বাগত পেয়েছেন কারণ
হোস্ট অ্যাক্টিভিটির অধীনে থাকা সব কম্পোজেবল আইটেমে একই GreetingViewModel
ইনস্ট্যান্স আবার ব্যবহার করা হয়েছে। তৈরি করা প্রথম ViewModel ইনস্ট্যান্স অন্যান্য
কম্পোজ করার উপযুক্ত আইটেমে আবার ব্যবহার করা হয়।
class GreetingActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { MaterialTheme { Column { GreetingScreen("user1") GreetingScreen("user2") } } } } } @Composable fun GreetingScreen( userId: String, viewModel: GreetingViewModel = viewModel( factory = GreetingViewModelFactory(userId) ) ) { val messageUser by viewModel.message.observeAsState("") Text(messageUser) } class GreetingViewModel(private val userId: String) : ViewModel() { private val _message = MutableLiveData("Hi $userId") val message: LiveData<String> = _message } class GreetingViewModelFactory(private val userId: String) : ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") override fun <T : ViewModel> create(modelClass: Class<T>): T { return GreetingViewModel(userId) as T } }
নেভিগেশন গ্রাফেও ViewModel এলিমেন্ট থাকে, তাই নেভিগেশন গ্রাফে কোনও
ডেস্টিনেশন হিসেবে কম্পোজ করা যায় এমন আইটেমের ViewModel-এর আলাদা আলাদা ইনস্ট্যান্স থাকে।
এই ক্ষেত্রে, ViewModel-এর স্কোপ হল গন্তব্যের লাইফসাইকেল এবং
ব্যাকস্ট্যাক থেকে গন্তব্য সরিয়ে দিলে এটি মুছে যায়। নিচের
উদাহরণে, ব্যবহারকারী প্রোফাইল স্ক্রিনে নেভিগেট করলে, GreetingViewModel-এর একটি নতুন
ইনস্ট্যান্স তৈরি হয়।
@Composable fun MyApp() { NavHost(rememberNavController(), startDestination = "profile/{userId}") { /* ... */ composable("profile/{userId}") { backStackEntry -> GreetingScreen(backStackEntry.arguments?.getString("userId") ?: "") } } }
State source of truth
আপনি UI-এর কোনও অংশে Compose ব্যবহার করলে, Compose ও
View সিস্টেম কোডকে ডেটা শেয়ার করতে হতে পারে। সম্ভব হলে, আমরা আপনাকে
অন্য একটি ক্লাসে সেই শেয়ার করা স্টেট এনক্যাপসুলেট করার জন্য সাজেস্ট করি যা UDF বেস্ট প্র্যাক্টিস
ফলো করে এবং দুটি প্ল্যাটফর্মেই ব্যবহার করা হয়; যেমন, ViewModel-এ যা ডেটা আপডেট এমিট করার জন্য
শেয়ার করা ডেটার স্ট্রিম এক্সপোজ করে।
তবে, শেয়ার করা ডেটা পরিবর্তনযোগ্য হলে অথবা কোনও UI এলিমেন্টের সাথে কঠোরভাবে আবদ্ধ থাকলে, এটি সবসময় সম্ভব হয় না। সেই ক্ষেত্রে, একটি সিস্টেমকে অবশ্যই সত্যের সোর্স হতে হবে এবং সেই সিস্টেমকে অন্য সিস্টেমে যেকোনও ডেটা আপডেট শেয়ার করতে হবে। সাধারণভাবে UI হায়ারার্কির রুট এলিমেন্টের কাছাকাছি থাকা এলিমেন্টকে সোর্স অফ ট্রুথ হিসেবে গণ্য করা হয়।
সঠিক তথ্য হিসেবে কম্পোজ করা
Compose স্টেট নন-Compose কোডে প্রকাশ করতে
SideEffect
কম্পোজ করার উপযুক্ত ব্যবহার করুন। এই ক্ষেত্রে, সোর্স অফ ট্রুথকে
কম্পোজ করা যায় এমন একটি জায়গায় রাখা হয়, যা স্টেট আপডেট পাঠায়।
যেমন, আপনার অ্যানালিটিক্স লাইব্রেরি আপনাকে কাস্টম মেটাডেটা (এই উদাহরণে ব্যবহারকারীর প্রপার্টি)
অ্যাট্যাচ করে আপনার ব্যবহারকারী
জনসংখ্যাকে সেগমেন্ট করতে দিতে পারে। আপনার অ্যানালিটিক্স লাইব্রেরিতে বর্তমান ব্যবহারকারীর
ব্যবহারকারীর ধরন কমিউনিকেট করতে, এর ভ্যালু আপডেট করতে SideEffect ব্যবহার করুন।
@Composable fun rememberFirebaseAnalytics(user: User): FirebaseAnalytics { val analytics: FirebaseAnalytics = remember { FirebaseAnalytics() } // On every successful composition, update FirebaseAnalytics with // the userType from the current User, ensuring that future analytics // events have this metadata attached SideEffect { analytics.setUserProperty("userType", user.userType) } return analytics }
আরও তথ্যের জন্য, Compose-এ পার্শ্বপ্রতিক্রিয়া দেখুন।
সোর্স অফ ট্রুথ হিসেবে সিস্টেমকে দেখা
ভিউ সিস্টেম যদি স্টেটটি নিজের কাছে রাখে এবং তা Compose-এর সাথে শেয়ার করে, তাহলে আমরা সাজেস্ট করি যে
Compose-এর জন্য থ্রেড-সেফ করতে আপনি স্টেটটিকে mutableStateOf অবজেক্টে
র্যাপ করুন। আপনি এই পদ্ধতি ব্যবহার করলে, কম্পোজ করার উপযুক্ত ফাংশনগুলি আরও সহজ হয়ে যায় কারণ
সেগুলির আর সোর্স অফ ট্রুথ থাকে না, তবে ভিউ সিস্টেমকে পরিবর্তনযোগ্য স্টেট
এবং সেই স্টেট ব্যবহার করা ভিউ আপডেট করতে হয়।
নিচের উদাহরণে, CustomViewGroup-এর মধ্যে TextView ও ComposeView আছে এবং TextField কম্পোজ করা যায়।
TextView-এ
ব্যবহারকারী TextField-এ যা টাইপ করেন তার কন্টেন্ট দেখাতে হবে।
class CustomViewGroup @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyle: Int = 0 ) : LinearLayout(context, attrs, defStyle) { // Source of truth in the View system as mutableStateOf // to make it thread-safe for Compose private var text by mutableStateOf("") private val textView: TextView init { orientation = VERTICAL textView = TextView(context) val composeView = ComposeView(context).apply { setContent { MaterialTheme { TextField(value = text, onValueChange = { updateState(it) }) } } } addView(textView) addView(composeView) } // Update both the source of truth and the TextView private fun updateState(newValue: String) { text = newValue textView.text = newValue } }
শেয়ার করা UI মাইগ্রেট করা
আপনি যদি ধীরে ধীরে Compose-এ মাইগ্রেট করেন, তাহলে আপনাকে Compose এবং ভিউ সিস্টেম, দু'টিতেই শেয়ার করা UI
এলিমেন্ট ব্যবহার করতে হতে পারে। যেমন, আপনার অ্যাপে
কাস্টম CallToActionButton কম্পোনেন্ট থাকলে, আপনাকে সেটি Compose
ও ভিউ-ভিত্তিক স্ক্রিন, দু'টিতেই ব্যবহার করতে হতে পারে।
Compose-এ, শেয়ার করা UI এলিমেন্টগুলি কম্পোজ করার উপযুক্ত হয়ে যায় এবং XML ব্যবহার করে স্টাইল করা বা কাস্টম ভিউ হওয়া সত্ত্বেও, সেগুলি অ্যাপ জুড়ে
পুনর্ব্যবহার করা যেতে পারে। যেমন, আপনি CallToActionButtonআপনার কাস্টম কল টু অ্যাকশন
Button কম্পোনেন্টের জন্য একটি কম্পোজ করার মতো আইটেম তৈরি করবেন।
ভিউ-ভিত্তিক স্ক্রিনে কম্পোজ করার উপযুক্ত আইটেম ব্যবহার করতে, একটি কাস্টম ভিউ র্যাপার তৈরি করুন যা AbstractComposeView থেকে
এক্সটেন্ড করে। এর ওভাররাইড করা Content কম্পোজ করার উপযুক্ত আইটেমে,
আপনার Compose থিমে র্যাপ করা কম্পোজ করার উপযুক্ত আইটেমটি রাখুন, নিচে দেওয়া
উদাহরণে যেমন দেখানো হয়েছে:
@Composable fun CallToActionButton( text: String, onClick: () -> Unit, modifier: Modifier = Modifier, ) { Button( colors = ButtonDefaults.buttonColors( containerColor = MaterialTheme.colorScheme.secondary ), onClick = onClick, modifier = modifier, ) { Text(text) } } class CallToActionViewButton @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyle: Int = 0 ) : AbstractComposeView(context, attrs, defStyle) { var text by mutableStateOf("") var onClick by mutableStateOf({}) @Composable override fun Content() { YourAppTheme { CallToActionButton(text, onClick) } } }
লক্ষ্য করুন, কম্পোজ করার উপযুক্ত প্যারামিটারগুলি কাস্টম
ভিউয়ের মধ্যে পরিবর্তনযোগ্য ভেরিয়েবল হয়ে যায়। এর ফলে কাস্টম CallToActionViewButton ভিউটি ইনফ্লেটেবল ও ব্যবহারযোগ্য হয়ে ওঠে,
যেমন ঐতিহ্যবাহী ভিউ। ভিউ বাইন্ডিং
সহ এর একটি উদাহরণ নিচে দেখুন:
class ViewBindingActivity : ComponentActivity() { private lateinit var binding: ActivityExampleBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityExampleBinding.inflate(layoutInflater) setContentView(binding.root) binding.callToAction.apply { text = getString(R.string.greeting) onClick = { /* Do something */ } } } }
কাস্টম কম্পোনেন্টে পরিবর্তনযোগ্য স্টেট থাকলে, সত্যের স্টেট সোর্স দেখুন।
প্রেজেন্টেশন থেকে স্প্লিট করার স্ট্যাটাসকে অগ্রাধিকার দিন
ঐতিহ্যগতভাবে, View হল স্টেটফুল। View এমন ফিল্ড ম্যানেজ করে যা
কীভাবে দেখাতে হবে তার পাশাপাশি কী দেখাতে হবে তাও বর্ণনা করে। আপনি View থেকে Compose-এ কনভার্ট করলে, একমুখী ডেটা ফ্লো
অর্জন করতে রেন্ডার করা ডেটা আলাদা করার দিকে নজর দিন, যা স্টেট হোয়েস্টিং-এ আরও বিস্তারিতভাবে ব্যাখ্যা করা হয়েছে।
যেমন, একটি View-এর একটি visibility প্রপার্টি আছে যা এটি
দৃশ্যমান, অদৃশ্য বা চলে গেছে কিনা তা বর্ণনা করে। এটি View-এর একটি অন্তর্নিহিত প্রপার্টি। অন্যান্য কোড
View-এর দৃশ্যমানতা পরিবর্তন করতে পারলেও, View
নিজে শুধুমাত্র নিজের বর্তমান দৃশ্যমানতা সম্পর্কে জানে। View-এর দৃশ্যমানতা
নিশ্চিত করার লজিক ভুল হতে পারে এবং এটি প্রায়ই View
নিজেই করে।
অন্যদিকে, Compose-এ Kotlin-এ কন্ডিশনাল লজিক ব্যবহার করে সম্পূর্ণ আলাদা কম্পোজ করার উপযুক্ত আইটেম দেখানো সহজ:
@Composable fun MyComposable(showCautionIcon: Boolean) { if (showCautionIcon) { CautionIcon(/* ... */) } }
ডিজাইন অনুযায়ী, CautionIcon-এর জানার বা বোঝার প্রয়োজন নেই যে এটি কেন দেখানো হচ্ছে,
এবং visibility-এর কোনও ধারণা নেই: এটি কম্পোজিশনে আছে অথবা
নেই।
স্টেট ম্যানেজমেন্ট ও প্রেজেন্টেশন লজিককে পরিষ্কারভাবে আলাদা করার মাধ্যমে, আপনি আরও স্বাধীনভাবে পরিবর্তন করতে পারবেন যে কীভাবে UI-তে স্টেট কনভার্সন হিসেবে কন্টেন্ট দেখানো হবে। প্রয়োজন হলে স্টেট হোইস্ট করতে পারার সুবিধা কম্পোজ করার মতো আইটেমকে আরও বেশি করে আবার ব্যবহারযোগ্য করে তোলে, কারণ স্টেটের মালিকানা আরও বেশি নমনীয়।
এনক্যাপসুলেট করা ও আবার ব্যবহারযোগ্য কম্পোনেন্ট প্রোমোট করা
View এলিমেন্টগুলি প্রায়শই কোথায় থাকে সেই সম্পর্কে কিছু ধারণা থাকে: Activity-এর মধ্যে, একটি
Dialog, একটি Fragment অথবা অন্য কোনও View হায়ারার্কির মধ্যে। কারণ,
স্ট্যাটিক লেআউট ফাইল থেকে এগুলি প্রায়ই বড় হয়ে যায়, তাই কোনও
View-এর সামগ্রিক স্ট্রাকচার খুব রিজিড হয়। এর ফলে আরও বেশি টাইট কাপলিং হয় এবং View পরিবর্তন বা আবার ব্যবহার করা
কঠিন হয়ে যায়।
যেমন, কাস্টম View ধরে নিতে পারে যে এটির কাছে নির্দিষ্ট আইডি সহ নির্দিষ্ট
ধরনের চাইল্ড ভিউ আছে এবং কোনও
অ্যাকশনের উত্তরে সরাসরি এর প্রপার্টি পরিবর্তন করতে পারে। এটি সেইসব View এলিমেন্টকে একসাথে শক্ত করে জোড়া দেয়: কাস্টম View
চাইল্ড খুঁজে না পেলে ক্র্যাশ করতে বা ভেঙে যেতে পারে এবং কাস্টম View প্যারেন্ট ছাড়া চাইল্ডকে সম্ভবত
পুনর্ব্যবহার করা যাবে না।
পুনর্ব্যবহারযোগ্য কম্পোজ করার মতো কম্পোজের ক্ষেত্রে এটি কম সমস্যাযুক্ত। অভিভাবকরা সহজেই স্টেট ও কলব্যাক নির্দিষ্ট করতে পারেন, তাই আপনি এমন কম্পোজ করার মতো আইটেম লিখতে পারবেন যেগুলি কোথায় ব্যবহার করা হবে তা আপনাকে জানতে হবে না।
@Composable fun AScreen() { var isEnabled by rememberSaveable { mutableStateOf(false) } Column { ImageWithEnabledOverlay(isEnabled) ControlPanelWithToggle( isEnabled = isEnabled, onEnabledChanged = { isEnabled = it } ) } }
উপরের উদাহরণে, তিনটি অংশই আরও বেশি এনক্যাপসুলেটেড এবং কম কাপলড:
ImageWithEnabledOverlay-কে শুধুমাত্র বর্তমানisEnabledস্টেট সম্পর্কে জানতে হবে।ControlPanelWithToggleযে আছে বা এমনকি কীভাবে এটি কন্ট্রোল করা যায়, সেই সম্পর্কে জানার প্রয়োজন নেই।ControlPanelWithToggleজানে না যেImageWithEnabledOverlayআছে।isEnabledদেখানোর শূন্য, একটি বা একাধিক উপায় থাকতে পারে এবংControlPanelWithToggleপরিবর্তন করতে হবে না।অভিভাবকের কাছে,
ImageWithEnabledOverlayবাControlPanelWithToggleকতখানি নেস্ট করা আছে তা গুরুত্বপূর্ণ নয়। সেইসব বাচ্চারা অ্যানিমেট করা পরিবর্তন, কন্টেন্ট অদল-বদল করা বা অন্য বাচ্চাদের কন্টেন্ট পাস করার মতো কাজ করতে পারে।
এই প্যাটার্নকে ইনভার্সন অফ কন্ট্রোল বলা হয়, যার ব্যাপারে আপনি CompositionLocal ডকুমেন্টেশন
থেকে আরও জানতে পারবেন।
স্ক্রিন সাইজ পরিবর্তন ম্যানেজ করা
বিভিন্ন উইন্ডো সাইজের জন্য আলাদা আলাদা রিসোর্স থাকলে, তা রেসপন্সিভ View লেআউট
তৈরি করার অন্যতম প্রধান উপায়। স্ক্রিন-লেভেল লেআউট সংক্রান্ত সিদ্ধান্তের জন্য উপযুক্ত রিসোর্স এখনও একটি বিকল্প হলেও, Compose সাধারণ কন্ডিশনাল লজিক সহ কোডে সম্পূর্ণভাবে লেআউট পরিবর্তন করাকে
অনেক সহজ করে তোলে। আরও জানতে উইন্ডো সাইজ
ক্লাস ব্যবহার করুন দেখুন।
এছাড়াও, অ্যাডাপ্টিভ UI তৈরি করার জন্য Compose-এর অফার করা টেকনিক সম্পর্কে জানতে বিভিন্ন ডিসপ্লে সাইজ সাপোর্ট করে লিঙ্কে দেখুন।
Views-এর সাথে নেস্টেড স্ক্রলিং
স্ক্রল করা যায় এমন View এলিমেন্ট এবং স্ক্রল করা যায় এমন কম্পোজ করার উপযুক্ত আইটেমের মধ্যে নেস্টেড স্ক্রলিং ইন্টার-অপারেশন কীভাবে চালু করতে হয় সেই সম্পর্কে আরও জানতে, দুদিকেই নেস্ট করা, নেস্টেড স্ক্রলিং ইন্টার-অপারেশন লিঙ্কটি পড়ুন।
RecyclerView-এ কম্পোজ করো
RecyclerView-এর কম্পোজেবল RecyclerView ভার্সন
1.3.0-alpha02 থেকে পারফর্ম্যান্স ভালো দেয়। এইসব সুবিধা পেতে, আপনি অন্তত
RecyclerView ভার্সন 1.3.0-alpha02 ব্যবহার করছেন কিনা তা নিশ্চিত করুন।
WindowInsets Views-এর সাথে ইন্টারঅপারেশন
আপনার স্ক্রিনে একই হায়ারার্কিতে View ও Compose কোড থাকলে, আপনাকে ডিফল্ট ইনসেট ওভাররাইড করতে হতে পারে। এই ক্ষেত্রে, কোন ইনসেটটি ব্যবহার করতে হবে এবং কোনটি উপেক্ষা করতে হবে তা আপনাকে স্পষ্টভাবে উল্লেখ করতে হবে।
যেমন, আপনার সবচেয়ে বাইরের লেআউট Android View লেআউট হলে, আপনাকে View সিস্টেমে ইনসেট
ব্যবহার করতে হবে এবং Compose-এর জন্য সেগুলি উপেক্ষা করতে হবে।
অথবা, আপনার সবচেয়ে বাইরের লেআউট কম্পোজ করার উপযুক্ত হলে, আপনাকে Compose-এ
ইনসেট ব্যবহার করতে হবে এবং সেই অনুযায়ী AndroidView কম্পোজ করার উপযুক্ত আইটেম প্যাড করতে হবে।
ডিফল্ট হিসেবে, প্রতিটি ComposeView, WindowInsetsCompat লেভেলের কনজাম্পশনে
সব ইনসেট কনজিউম করে। এই ডিফল্ট আচরণ পরিবর্তন করতে, ComposeView.consumeWindowInsets
false হিসেবে সেট করুন।
আরও তথ্যের জন্য, Compose-এ WindowInsets সম্পর্কে ডকুমেন্টেশন পড়ুন।
আপনার জন্য সাজেস্ট করা হয়েছে
- মনে রাখবেন: জাভাস্ক্রিপ্ট বন্ধ থাকলে লিঙ্ক টেক্সট দেখানো হয়
- ইমোজি দেখানো
- Compose-এ Material Design 2
- Compose-এ উইন্ডো ইনসেট