Wear OS এর জন্য রচনা সহ তালিকা


Wear OS ডিভাইসে তালিকা ব্যবহারকারীদের বিভিন্ন বিকল্পের মধ্য থেকে কোনো একটি আইটেম বেছে নিতে সাহায্য করে।

Many Wear OS devices use round screens, which makes it more difficult to see list items that appear near the top and bottom of the screen. For this reason, Compose for Wear OS includes a version of the LazyColumn class called TransformingLazyColumn , which supports scaling and morphing animations. When items move to the edges, they get smaller and fade out.

প্রস্তাবিত স্কেলিং এবং স্ক্রোলিং ইফেক্টগুলো প্রয়োগ করতে:

  1. Use Modifier.transformedHeight to allow Compose to calculate the height change as the item scrolls through the screen.
  2. আইটেমের বিষয়বস্তু ছোট করা সহ ভিজ্যুয়াল ইফেক্টগুলো প্রয়োগ করতে transformation = SurfaceTransformation(transformationSpec) ব্যবহার করুন।
  3. যেসব কম্পোনেন্ট প্যারামিটার হিসেবে transformation গ্রহণ করে না, যেমন Text সেগুলোর জন্য একটি কাস্টম TransformationSpec ব্যবহার করুন।

নিম্নলিখিত অ্যানিমেশনটি দেখায় কিভাবে একটি তালিকার উপাদান স্ক্রিনের উপরে এবং নীচে যাওয়ার সময় তার আকার ও আকৃতি পরিবর্তন করে:

নিম্নলিখিত কোড স্নিপেটটি দেখায় কিভাবে TransformingLazyColumn লেআউট ব্যবহার করে একটি তালিকা তৈরি করা যায়, যার বিষয়বস্তু বিভিন্ন Wear OS স্ক্রিনের আকারে চমৎকার দেখায়

এই কোড স্নিপেটটিতে minimumVerticalContentPadding মডিফায়ারটির ব্যবহারও দেখানো হয়েছে, যা লিস্টের উপরে ও নীচে সঠিক প্যাডিং প্রয়োগ করার জন্য লিস্ট আইটেমগুলোতে সেট করতে হয়।

স্ক্রোল ইন্ডিকেটর দেখানোর জন্য, ScreenScaffold এবং TransformingLazyColumn এর মধ্যে columnState শেয়ার করুন:

val columnState = rememberTransformingLazyColumnState()
val transformationSpec = rememberTransformationSpec()
ScreenScaffold(
    scrollState = columnState
) { contentPadding ->
    TransformingLazyColumn(
        state = columnState,
        contentPadding = contentPadding
    ) {
        item {
            ListHeader(
                modifier = Modifier
                    .fillMaxWidth()
                    .transformedHeight(this, transformationSpec)
                    .minimumVerticalContentPadding(ListHeaderDefaults.minimumTopListContentPadding),
                transformation = SurfaceTransformation(transformationSpec)
            ) {
                Text(text = "Header")
            }
        }
        // ... other items
        item {
            Button(
                modifier = Modifier
                    .fillMaxWidth()
                    .transformedHeight(this, transformationSpec)
                    .minimumVerticalContentPadding(ButtonDefaults.minimumVerticalListContentPadding),
                transformation = SurfaceTransformation(transformationSpec),
                onClick = { /* ... */ },
                icon = {
                    Icon(
                        imageVector = Icons.Default.Build,
                        contentDescription = "build",
                    )
                },
            ) {
                Text(
                    text = "Build",
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis,
                )
            }
        }
    }
}

একটি স্ন্যাপ-অ্যান্ড-ফ্লিং এফেক্ট যোগ করুন

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

To add a snap-and-fling behavior, set the flingBehavior parameter to TransformingLazyColumnDefaults.snapFlingBehavior(columnState) . Set the rotaryScrollableBehavior to match, using RotaryScrollableDefaults.snapBehavior(columnState) for a consistent experience when using the physical crown or bezel.

val columnState = rememberTransformingLazyColumnState()
ScreenScaffold(scrollState = columnState) {
    TransformingLazyColumn(
        state = columnState,
        flingBehavior = TransformingLazyColumnDefaults.snapFlingBehavior(columnState),
        rotaryScrollableBehavior = RotaryScrollableDefaults.snapBehavior(columnState)
    ) {
        // ...
        // ...
    }
}

বিপরীত বিন্যাস

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

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

এইসব ব্যবহারের ক্ষেত্রকে সমর্থন করার জন্য, TransformingLazyColumn আপনাকে reverseLayout = true সেট করে লেআউটটি উল্টে দেওয়ার সুযোগ দেয়। এর ফলে তালিকার অ্যাঙ্করটি উপরের প্রান্ত থেকে নিচের প্রান্তে স্থানান্তরিত হয়।

সুবিধার জন্য, reverseLayout = true সেট করলে আইটেমগুলোর দৃশ্যমান ক্রম এবং স্ক্রোলিং জেসচারের দিকও উল্টে যায়:

  • আইটেমগুলো নিচ থেকে উপরের দিকে সাজানো থাকে, অর্থাৎ ইনডেক্স ০ স্ক্রিনের নিচে প্রদর্শিত হয়।
  • উপরে স্ক্রল করলে উচ্চতর সূচকের আইটেমগুলো দেখা যায়।

রিভার্স লেআউটের সাথে স্ন্যাপ-অ্যান্ড-ফ্লিং বিহেভিয়ার যোগ করতে, আপনি নিচের কোড স্নিপেটে দেখানো অনুযায়ী flingBehavior এবং rotaryScrollableBehavior একত্রিত করতে পারেন:

val columnState = rememberTransformingLazyColumnState()
val transformationSpec = rememberTransformationSpec()
ScreenScaffold(scrollState = columnState) { contentPadding ->
    TransformingLazyColumn(
        state = columnState,
        contentPadding = contentPadding,
        reverseLayout = true,
        modifier = Modifier.fillMaxWidth()
    ) {
        items(10) { index ->
            Button(
                label = {
                    Text(
                        text = "Item ${index + 1}"
                    )
                },
                onClick = {},
                modifier = Modifier
                    .fillMaxWidth()
                    .transformedHeight(this, transformationSpec)
                    .minimumVerticalContentPadding(ButtonDefaults.minimumVerticalListContentPadding),
                transformation = SurfaceTransformation(transformationSpec)
            )
        }
        item {
            // With reverseLayout = true, the last item declared appears at the top.
            ListHeader(
                modifier = Modifier
                    .fillMaxWidth()
                    .transformedHeight(this, transformationSpec)
                    .minimumVerticalContentPadding(ListHeaderDefaults.minimumTopListContentPadding),
                transformation = SurfaceTransformation(transformationSpec)
            ) {
                Text("Header")
            }
        }
    }
}

নিচের ছবিগুলোতে একটি সাধারণ তালিকা এবং একটি বিপরীত তালিকার মধ্যে পার্থক্য দেখানো হয়েছে:

সাধারণ লেআউট সহ একটি TransformingLazyColumn, যা শীর্ষে আইটেম ১ এবং বাকি আইটেমগুলো আরোহী ক্রমে প্রদর্শন করে।
Figure 1. A standard list layout where content fills from top to bottom.
A TransformingLazyColumn with reverse layout, showing Item 1 at the bottom and items in descending order towards the top.
চিত্র ২. একটি বিপরীত তালিকা বিন্যাস যেখানে বিষয়বস্তু নিচ থেকে উপরের দিকে পূরণ হয়।
{% হুবহু %} {% endverbatim %} {% হুবহু %} {% endverbatim %}