অন্যান্য বিবেচ্য বিষয়

ভিউ থেকে কম্পোজে মাইগ্রেট করা সম্পূর্ণরূপে UI-সম্পর্কিত হলেও, নিরাপদ এবং ক্রমবর্ধমান মাইগ্রেশন সম্পাদনের জন্য অনেক কিছু বিবেচনা করতে হবে। আপনার ভিউ-ভিত্তিক অ্যাপটি কম্পোজে মাইগ্রেট করার সময় এই পৃষ্ঠায় কিছু বিবেচ্য বিষয় রয়েছে।

আপনার অ্যাপের থিম স্থানান্তর করা হচ্ছে

অ্যান্ড্রয়েড অ্যাপের থিমিংয়ের জন্য মেটেরিয়াল ডিজাইন হল প্রস্তাবিত ডিজাইন সিস্টেম।

ভিউ-ভিত্তিক অ্যাপের জন্য, ম্যাটেরিয়ালের তিনটি সংস্করণ উপলব্ধ:

  • অ্যাপকম্প্যাট লাইব্রেরি ব্যবহার করে মেটেরিয়াল ডিজাইন ১ (অর্থাৎ Theme.AppCompat.* )
  • MDC-Android লাইব্রেরি ব্যবহার করে মেটেরিয়াল ডিজাইন 2 (অর্থাৎ Theme.MaterialComponents.* )
  • MDC-Android লাইব্রেরি ব্যবহার করে মেটেরিয়াল ডিজাইন 3 (অর্থাৎ Theme.Material3.* )

কম্পোজ অ্যাপের জন্য, ম্যাটেরিয়ালের দুটি সংস্করণ পাওয়া যায়:

আপনার অ্যাপের ডিজাইন সিস্টেম যদি তা করার মতো অবস্থানে থাকে, তাহলে আমরা আপনাকে সর্বশেষ সংস্করণ (ম্যাটেরিয়াল ৩) ব্যবহার করার পরামর্শ দিচ্ছি। ভিউ এবং কম্পোজ উভয়ের জন্যই মাইগ্রেশন গাইড উপলব্ধ রয়েছে:

Compose-এ নতুন স্ক্রিন তৈরি করার সময়, আপনি Material Design-এর যে সংস্করণই ব্যবহার করুন না কেন, Compose Material লাইব্রেরি থেকে UI নির্গত করে এমন যেকোনো composable-এর আগে MaterialTheme প্রয়োগ করুন। Material উপাদানগুলি ( Button , Text , ইত্যাদি) একটি MaterialTheme স্থানে থাকার উপর নির্ভর করে এবং এটি ছাড়া তাদের আচরণ অনির্দিষ্ট।

সমস্ত জেটপ্যাক কম্পোজ নমুনা MaterialTheme এর উপরে তৈরি একটি কাস্টম কম্পোজ থিম ব্যবহার করে।

আরও জানতে "Compose-এ ডিজাইন সিস্টেম" এবং "XML থিমগুলিকে কম্পোজে মাইগ্রেট করা" দেখুন।

আপনি যদি আপনার অ্যাপে নেভিগেশন উপাদান ব্যবহার করেন, তাহলে আরও তথ্যের জন্য কম্পোজের সাথে নেভিগেট করা - ইন্টারঅপারেবিলিটি এবং জেটপ্যাক নেভিগেশনকে নেভিগেশন কম্পোজে মাইগ্রেট করুন দেখুন।

আপনার মিশ্র রচনা/দর্শন UI পরীক্ষা করুন

আপনার অ্যাপের কিছু অংশ কম্পোজে স্থানান্তরিত করার পরে, আপনি কোনও কিছু ভেঙে ফেলেছেন কিনা তা নিশ্চিত করার জন্য পরীক্ষা করা অত্যন্ত গুরুত্বপূর্ণ।

যখন কোন অ্যাক্টিভিটি বা ফ্র্যাগমেন্ট 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 এর সাথে আন্তঃকার্যকারিতা দেখুন।

আপনার বিদ্যমান অ্যাপ আর্কিটেকচারের সাথে কম্পোজ ইন্টিগ্রেট করা

ইউনিডাইরেকশনাল ডেটা ফ্লো (UDF) আর্কিটেকচার প্যাটার্ন কম্পোজের সাথে নির্বিঘ্নে কাজ করে। যদি অ্যাপটি মডেল ভিউ প্রেজেন্টার (MVP) এর মতো অন্যান্য ধরণের আর্কিটেকচার প্যাটার্ন ব্যবহার করে, তাহলে আমরা আপনাকে কম্পোজ গ্রহণের আগে বা গ্রহণ করার সময় UI এর সেই অংশটি UDF-এ স্থানান্তর করার পরামর্শ দিচ্ছি।

কম্পোজে একটি ViewModel ব্যবহার করা

যদি আপনি Architecture Components ViewModel লাইব্রেরি ব্যবহার করেন, viewModel() ফাংশনটি কল করে যেকোনো কম্পোজেবল থেকে ViewModel অ্যাক্সেস করতে পারবেন, যেমনটি Compose এবং অন্যান্য লাইব্রেরিতে ব্যাখ্যা করা হয়েছে।

কম্পোজ গ্রহণ করার সময়, ViewModel উপাদানগুলি View-lifecycle স্কোপ অনুসরণ করে, একই ধরণের ViewModel টাইপ বিভিন্ন কম্পোজেবলে ব্যবহার করার বিষয়ে সতর্ক থাকুন। যদি নেভিগেশন লাইব্রেরি ব্যবহার করা হয়, তাহলে স্কোপটি হয় হোস্ট অ্যাক্টিভিটি, ফ্র্যাগমেন্ট, অথবা নেভিগেশন গ্রাফ হবে।

উদাহরণস্বরূপ, যদি কম্পোজেবলগুলি কোনও অ্যাক্টিভিটিতে হোস্ট করা থাকে, 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") ?: "")
        }
    }
}

সত্যের রাষ্ট্রীয় উৎস

যখন আপনি UI এর একটি অংশে Compose গ্রহণ করেন, তখন Compose এবং View সিস্টেম কোডের ডেটা শেয়ার করার প্রয়োজন হতে পারে। যখন সম্ভব হয়, আমরা আপনাকে সেই শেয়ার্ড স্টেটটিকে অন্য একটি ক্লাসে ক্যাপসুলেট করার পরামর্শ দিই যা উভয় প্ল্যাটফর্ম দ্বারা ব্যবহৃত UDF সেরা অনুশীলনগুলি অনুসরণ করে; উদাহরণস্বরূপ, একটি ViewModel যা ডেটা আপডেট নির্গত করার জন্য শেয়ার্ড ডেটার একটি স্ট্রিম প্রকাশ করে।

তবে, যদি ভাগ করা ডেটা পরিবর্তনযোগ্য হয় বা কোনও UI উপাদানের সাথে শক্তভাবে আবদ্ধ থাকে তবে এটি সর্বদা সম্ভব হয় না। সেক্ষেত্রে, একটি সিস্টেমকে সত্যের উৎস হতে হবে এবং সেই সিস্টেমকে অন্য সিস্টেমের সাথে যেকোনো ডেটা আপডেট শেয়ার করতে হবে। একটি সাধারণ নিয়ম হিসাবে, সত্যের উৎসটি UI অনুক্রমের মূলের কাছাকাছি যে উপাদানটি রয়েছে তার মালিকানাধীন হওয়া উচিত।

সত্যের উৎস হিসেবে রচনা করুন

কম্পোজ অবস্থাকে নন-কম্পোজ কোডে প্রকাশ করতে 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
}

আরও তথ্যের জন্য, কম্পোজে পার্শ্ব প্রতিক্রিয়া দেখুন।

সিস্টেমকে সত্যের উৎস হিসেবে দেখুন

যদি ভিউ সিস্টেমটি স্টেটের মালিক হয় এবং এটি কম্পোজের সাথে শেয়ার করে, তাহলে আমরা সুপারিশ করব যে আপনি স্টেটটিকে mutableStateOf অবজেক্টে মুড়ে নিন যাতে এটি Compose-এর জন্য থ্রেড-নিরাপদ হয়। আপনি যদি এই পদ্ধতিটি ব্যবহার করেন, তাহলে কম্পোজেবল ফাংশনগুলি সরলীকৃত হয় কারণ তাদের আর সত্যের উৎস থাকে না, তবে ভিউ সিস্টেমকে mutable state এবং সেই স্টেট ব্যবহার করে এমন Views আপডেট করতে হবে।

নিম্নলিখিত উদাহরণে, একটি 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 এবং View সিস্টেম উভয় ক্ষেত্রেই শেয়ার্ড UI উপাদান ব্যবহার করতে হতে পারে। উদাহরণস্বরূপ, যদি আপনার অ্যাপে একটি কাস্টম CallToActionButton উপাদান থাকে, তাহলে আপনাকে Compose এবং View-ভিত্তিক উভয় স্ক্রিনেই এটি ব্যবহার করতে হতে পারে।

কম্পোজে, শেয়ার করা UI উপাদানগুলি কম্পোজেবল হয়ে যায় যা অ্যাপ জুড়ে পুনঃব্যবহার করা যেতে পারে, XML ব্যবহার করে স্টাইল করা উপাদানটি হোক বা কাস্টম ভিউ হোক না কেন। উদাহরণস্বরূপ, আপনি আপনার কাস্টম কল টু অ্যাকশন Button উপাদানের জন্য একটি CallToActionButton কম্পোজেবল তৈরি করবেন।

ভিউ-ভিত্তিক স্ক্রিনে কম্পোজেবল ব্যবহার করতে, AbstractComposeView থেকে প্রসারিত একটি কাস্টম ভিউ র‍্যাপার তৈরি করুন। এর ওভাররাইড করা Content কম্পোজেবলে, আপনার তৈরি কম্পোজেবলটি আপনার কম্পোজ থিমে মোড়ানো অবস্থায় রাখুন, যেমনটি নীচের উদাহরণে দেখানো হয়েছে:

@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 কম্পোজে রূপান্তর করেন, তখন একটি একমুখী ডেটা প্রবাহ অর্জনের জন্য রেন্ডার করা ডেটা আলাদা করার চেষ্টা করুন, যেমনটি state hoisting -এ আরও ব্যাখ্যা করা হয়েছে।

উদাহরণস্বরূপ, একটি View একটি visibility property থাকে যা বর্ণনা করে যে এটি দৃশ্যমান, অদৃশ্য, নাকি চলে গেছে। এটি View এর একটি অন্তর্নিহিত বৈশিষ্ট্য। যদিও অন্যান্য কোডের অংশগুলি View এর visibility পরিবর্তন করতে পারে, শুধুমাত্র View নিজেই জানে যে এর বর্তমান visibility কী। View দৃশ্যমান তা নিশ্চিত করার যুক্তি ত্রুটিপ্রবণ হতে পারে এবং প্রায়শই View এর সাথেই সম্পর্কিত।

বিপরীতে, কম্পোজ কোটলিনে কন্ডিশনাল লজিক ব্যবহার করে সম্পূর্ণ ভিন্ন কম্পোজেবল প্রদর্শন করা সহজ করে তোলে:

@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 লেআউট তৈরির অন্যতম প্রধান উপায়। যদিও স্ক্রিন-লেভেল লেআউট সিদ্ধান্তের জন্য যোগ্য রিসোর্স এখনও একটি বিকল্প, কম্পোজ স্বাভাবিক শর্তাধীন লজিকের সাথে কোডে সম্পূর্ণরূপে লেআউট পরিবর্তন করা অনেক সহজ করে তোলে। আরও জানতে উইন্ডো আকারের ক্লাস ব্যবহার করুন দেখুন।

অতিরিক্তভাবে, অভিযোজিত UI তৈরির জন্য কম্পোজ কী কী কৌশল অফার করে তা জানতে বিভিন্ন ডিসপ্লে আকার সমর্থন করুন দেখুন।

ভিউ সহ নেস্টেড স্ক্রোলিং

স্ক্রোলযোগ্য ভিউ এলিমেন্ট এবং উভয় দিকে নেস্টেড স্ক্রোলযোগ্য কম্পোজেবলের মধ্যে নেস্টেড স্ক্রোলিং ইন্টারঅপ কীভাবে সক্ষম করবেন সে সম্পর্কে আরও তথ্যের জন্য, নেস্টেড স্ক্রোলিং ইন্টারঅপ পড়ুন।

RecyclerView এ রচনা করুন

RecyclerView এর কম্পোজেবলগুলি RecyclerView সংস্করণ 1.3.0-alpha02 থেকে কার্যকর। এই সুবিধাগুলি দেখতে RecyclerView এর কমপক্ষে 1.3.0-alpha02 সংস্করণটি ব্যবহার করছেন কিনা তা নিশ্চিত করুন।

WindowInsets ভিউয়ের সাথে ইন্টারঅ্যাপ করে

যখন আপনার স্ক্রিনে একই শ্রেণিবিন্যাসে ভিউ এবং কম্পোজ কোড উভয়ই থাকে তখন আপনাকে ডিফল্ট ইনসেটগুলিকে ওভাররাইড করতে হতে পারে। এই ক্ষেত্রে, আপনাকে স্পষ্টভাবে বলতে হবে যে কোনটি ইনসেটগুলি ব্যবহার করা উচিত এবং কোনটি সেগুলি উপেক্ষা করা উচিত।

উদাহরণস্বরূপ, যদি আপনার বাইরেরতম লেআউটটি একটি অ্যান্ড্রয়েড ভিউ লেআউট হয়, তাহলে আপনার ভিউ সিস্টেমের ইনসেটগুলি ব্যবহার করা উচিত এবং কম্পোজের জন্য সেগুলি উপেক্ষা করা উচিত। বিকল্পভাবে, যদি আপনার বাইরেরতম লেআউটটি একটি কম্পোজেবল হয়, তাহলে আপনার কম্পোজে ইনসেটগুলি ব্যবহার করা উচিত এবং সেই অনুযায়ী AndroidView কম্পোজেবলগুলি প্যাড করা উচিত।

ডিফল্টরূপে, প্রতিটি ComposeView WindowInsetsCompat ব্যবহারের স্তরে সমস্ত ইনসেট ব্যবহার করে। এই ডিফল্ট আচরণ পরিবর্তন করতে, ComposeView.consumeWindowInsets false এ সেট করুন।

আরও তথ্যের জন্য, WindowInsets in Compose ডকুমেন্টেশনটি পড়ুন।

{% অক্ষরে অক্ষরে %} {% এন্ডভারব্যাটিম %} {% অক্ষরে অক্ষরে %} {% এন্ডভারব্যাটিম %}