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

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

আপনার অ্যাপের থিম মাইগ্রেট করা হচ্ছে

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

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

  • AppCompat লাইব্রেরি (যেমন Theme.AppCompat.*) ব্যবহার করে মেটেরিয়াল ডিজাইন ১
  • MDC-Android লাইব্রেরি (যেমন Theme.MaterialComponents.*) ব্যবহার করে মেটেরিয়াল ডিজাইন ২
  • MDC-Android লাইব্রেরি (যেমন Theme.Material3.*) ব্যবহার করে Material Design 3

Compose অ্যাপের জন্য, Material-এর দুটি ভার্সন উপলভ্য:

  • Compose Material লাইব্রেরি (যেমন androidx.compose.material.MaterialTheme) ব্যবহার করে Material Design 2
  • Compose Material 3 লাইব্রেরি (যেমন, androidx.compose.material3.MaterialTheme) ব্যবহার করে Material Design 3

আপনার অ্যাপের ডিজাইন সিস্টেম যদি লেটেস্ট ভার্সন (Material 3) ব্যবহার করার মতো অবস্থায় থাকে, তাহলে আমরা সেটি ব্যবহার করার সাজেশন দিই। Views এবং Compose, দুটির জন্যই মাইগ্রেশন গাইড উপলভ্য আছে:

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

সব Jetpack Compose স্যাম্পেল MaterialTheme-এর উপরে তৈরি করা কাস্টম Compose থিম ব্যবহার করে।

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

আপনার অ্যাপে নেভিগেশন কম্পোনেন্ট ব্যবহার করলে, আরও তথ্যের জন্য ফ্র্যাগমেন্ট-ভিত্তিক অ্যাপে Compose থেকে নেভিগেট করুন এবং Jetpack Navigation-কে Navigation 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()
    }
}

টেস্টিং সম্পর্কে আরও জানতে আপনার Compose লেআউট টেস্ট করা দেখুন। UI টেস্টিং ফ্রেমওয়ার্কের সাথে ইন্টারঅপারেবিলিটির জন্য, Espresso-র সাথে ইন্টারঅপারেবিলিটি এবং UiAutomator-এর সাথে ইন্টারঅপারেবিলিটি দেখুন।

আপনার আগে থেকে থাকা অ্যাপ আর্কিটেকচারের সাথে Compose ইন্টিগ্রেট করা

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

Compose-এ ViewModel ব্যবহার করা

আপনি আর্কিটেকচার কম্পোনেন্ট 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") ?: "")
        }
    }
}

স্টেট সোর্স অফ ট্রুথ

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

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

Compose as the source of truth

নন-কম্পোজ কোডে কম্পোজ স্টেট প্রকাশ করতে 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-এ সাইড-এফেক্ট দেখুন।

সোর্স অফ ট্রুথ হিসেবে সিস্টেম দেখুন

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

নিচের উদাহরণে, একটি 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 এবং ভিউ-ভিত্তিক স্ক্রিন, দুটিতেই ব্যবহার করতে হতে পারে।

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

ভিউ-ভিত্তিক স্ক্রিনে কম্পোজেবল ব্যবহার করতে, কাস্টম ভিউ র‍্যাপার তৈরি করুন যা 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-কে 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 যেসব টেকনিক অফার করে সেগুলি সম্পর্কে জানতে, বিভিন্ন ডিসপ্লে সাইজ সাপোর্ট করা লিঙ্কটি দেখুন।

ভিউয়ের সাথে নেস্টেড স্ক্রলিং

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

RecyclerView-এ কম্পোজ করুন

RecyclerView-এ কম্পোজেবল RecyclerView ভার্সন 1.3.0-alpha02 থেকে পারফর্ম্যান্ট। এইসব সুবিধা দেখতে, আপনি RecyclerView-এর অন্তত 1.3.0-alpha02 ভার্সন ব্যবহার করছেন কিনা তা নিশ্চিত করুন।

WindowInsets Views-এর সাথে ইন্টারঅপারেট করে

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

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

ডিফল্ট হিসেবে, প্রতিটি ComposeView, WindowInsetsCompat লেভেলে সব ইনসেট ব্যবহার করে। এই ডিফল্ট অ্যাকশন পরিবর্তন করতে, ComposeView.consumeWindowInsets false-এ সেট করুন।

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