টিউটোরিয়াল

জেটপ্যাক কম্পোজ টিউটোরিয়াল

জেটপ্যাক কম্পোজ হল নেটিভ অ্যান্ড্রয়েড UI তৈরির জন্য একটি আধুনিক টুলকিট। জেটপ্যাক কম্পোজ কম কোড, শক্তিশালী টুলস এবং স্বজ্ঞাত Kotlin APIs সহ Android-এ UI ডেভেলপমেন্টকে সহজ করে এবং ত্বরান্বিত করে।

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

সম্পূর্ণ পূর্বরূপ
সম্পূর্ণ পূর্বরূপ

একটি পাঠ্য উপাদান যোগ করুন

শুরু করতে, অ্যান্ড্রয়েড স্টুডিওর সাম্প্রতিকতম সংস্করণ ডাউনলোড করুন এবং নতুন প্রকল্প নির্বাচন করে একটি অ্যাপ তৈরি করুন এবং ফোন এবং ট্যাবলেট বিভাগের অধীনে, খালি কার্যকলাপ নির্বাচন করুন। আপনার অ্যাপের নাম ComposeTutorial এবং Finish এ ক্লিক করুন। ডিফল্ট টেমপ্লেটে ইতিমধ্যেই কিছু রচনা উপাদান রয়েছে, কিন্তু এই টিউটোরিয়ালে আপনি ধাপে ধাপে এটি তৈরি করবেন।

প্রথমে একটি "হ্যালো ওয়ার্ল্ড!" প্রদর্শন করুন। onCreate পদ্ধতির ভিতরে একটি পাঠ্য উপাদান যোগ করে পাঠ্য। আপনি একটি বিষয়বস্তু ব্লক সংজ্ঞায়িত করে এবং Text কম্পোজেবল ফাংশন কল করে এটি করেন। setContent ব্লক কার্যকলাপের বিন্যাস সংজ্ঞায়িত করে যেখানে কম্পোজযোগ্য ফাংশন বলা হয়। কম্পোজেবল ফাংশন শুধুমাত্র অন্যান্য কম্পোজেবল ফাংশন থেকে কল করা যেতে পারে।

জেটপ্যাক কম্পোজ এই কম্পোজযোগ্য ফাংশনগুলিকে অ্যাপের UI উপাদানগুলিতে রূপান্তর করতে একটি Kotlin কম্পাইলার প্লাগইন ব্যবহার করে। উদাহরণস্বরূপ, Text কম্পোজেবল ফাংশন যা কম্পোজ UI লাইব্রেরি দ্বারা সংজ্ঞায়িত করা হয় স্ক্রিনে একটি টেক্সট লেবেল প্রদর্শন করে।

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.Text

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Text("Hello world!")
        }
    }
}
  
পূর্বরূপ দেখান
পূর্বরূপ লুকান

একটি সংমিশ্রণযোগ্য ফাংশন সংজ্ঞায়িত করুন

একটি ফাংশন কম্পোজেবল করতে, @Composable টীকা যোগ করুন। এটি চেষ্টা করার জন্য, একটি MessageCard ফাংশন সংজ্ঞায়িত করুন যা একটি নাম পাস করে এবং পাঠ্য উপাদানটি কনফিগার করতে এটি ব্যবহার করে।

// ...
import androidx.compose.runtime.Composable

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MessageCard("Android")
        }
    }
}

@Composable
fun MessageCard(name: String) {
    Text(text = "Hello $name!")
}

  
পূর্বরূপ দেখান
পূর্বরূপ লুকান

অ্যান্ড্রয়েড স্টুডিওতে আপনার ফাংশনের পূর্বরূপ দেখুন

@Preview টীকা আপনাকে অ্যান্ড্রয়েড স্টুডিওর মধ্যে আপনার কম্পোজযোগ্য ফাংশনগুলির পূর্বরূপ দেখতে দেয় এবং কোনও অ্যান্ড্রয়েড ডিভাইস বা এমুলেটরে অ্যাপটি তৈরি এবং ইনস্টল না করেই। টীকাটি অবশ্যই একটি কম্পোজযোগ্য ফাংশনে ব্যবহার করা উচিত যা প্যারামিটারগুলিতে নেয় না। এই কারণে, আপনি সরাসরি MessageCard ফাংশনের পূর্বরূপ দেখতে পারবেন না। পরিবর্তে, PreviewMessageCard নামে একটি দ্বিতীয় ফাংশন তৈরি করুন, যা একটি উপযুক্ত প্যারামিটার সহ MessageCard কল করে। @Composable এর আগে @Preview টীকা যোগ করুন।

// ...
import androidx.compose.ui.tooling.preview.Preview

@Composable
fun MessageCard(name: String) {
    Text(text = "Hello $name!")
}

@Preview
@Composable
fun PreviewMessageCard() {
    MessageCard("Android")
}
  
পূর্বরূপ দেখান
পূর্বরূপ লুকান

আপনার প্রকল্প পুনর্নির্মাণ. অ্যাপটি নিজেই পরিবর্তন হয় না, যেহেতু নতুন PreviewMessageCard ফাংশনটি কোথাও বলা হয় না, তবে Android Studio একটি প্রিভিউ উইন্ডো যোগ করে যা আপনি স্প্লিট (ডিজাইন/কোড) ভিউতে ক্লিক করে প্রসারিত করতে পারেন। এই উইন্ডোটি @Preview টীকা দিয়ে চিহ্নিত কম্পোজেবল ফাংশন দ্বারা তৈরি UI উপাদানগুলির একটি পূর্বরূপ দেখায়। যেকোন সময় প্রিভিউ আপডেট করতে, প্রিভিউ উইন্ডোর উপরে রিফ্রেশ বোতামে ক্লিক করুন।

অ্যান্ড্রয়েড স্টুডিওতে একটি রচনাযোগ্য ফাংশনের পূর্বরূপ
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.Text

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Text("Hello world!")
        }
    }
}
  
পূর্বরূপ দেখান
পূর্বরূপ লুকান
// ...
import androidx.compose.runtime.Composable

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MessageCard("Android")
        }
    }
}

@Composable
fun MessageCard(name: String) {
    Text(text = "Hello $name!")
}

  
পূর্বরূপ দেখান
পূর্বরূপ লুকান
// ...
import androidx.compose.ui.tooling.preview.Preview

@Composable
fun MessageCard(name: String) {
    Text(text = "Hello $name!")
}

@Preview
@Composable
fun PreviewMessageCard() {
    MessageCard("Android")
}
  
পূর্বরূপ দেখান
পূর্বরূপ লুকান
অ্যান্ড্রয়েড স্টুডিওতে একটি রচনাযোগ্য ফাংশনের পূর্বরূপ

একাধিক পাঠ্য যোগ করুন

এখন পর্যন্ত আপনি আপনার প্রথম কম্পোজযোগ্য ফাংশন এবং পূর্বরূপ তৈরি করেছেন! আরও জেটপ্যাক রচনা ক্ষমতা আবিষ্কার করতে, আপনি কিছু অ্যানিমেশন সহ প্রসারিত করা যেতে পারে এমন বার্তাগুলির একটি তালিকা সহ একটি সাধারণ মেসেজিং স্ক্রিন তৈরি করতে যাচ্ছেন।

এর লেখকের নাম এবং একটি বার্তার বিষয়বস্তু প্রদর্শন করে বার্তাটিকে আরও সমৃদ্ধ করে কম্পোজ করা শুরু করুন। একটি String এর পরিবর্তে একটি Message অবজেক্ট গ্রহণ করতে আপনাকে প্রথমে কম্পোজযোগ্য প্যারামিটার পরিবর্তন করতে হবে এবং MessageCard কম্পোজেবলের ভিতরে অন্য একটি Text যোগ করতে হবে। পাশাপাশি প্রিভিউ আপডেট করতে ভুলবেন না।

// ...

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MessageCard(Message("Android", "Jetpack Compose"))
        }
    }
}

data class Message(val author: String, val body: String)

@Composable
fun MessageCard(msg: Message) {
    Text(text = msg.author)
    Text(text = msg.body)
}

@Preview
@Composable
fun PreviewMessageCard() {
    MessageCard(
        msg = Message("Lexi", "Hey, take a look at Jetpack Compose, it's great!")
    )
}

  
পূর্বরূপ দেখান
পূর্বরূপ লুকান

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

একটি কলাম ব্যবহার করে

Column ফাংশন আপনাকে উপাদানগুলি উল্লম্বভাবে সাজাতে দেয়। MessageCard ফাংশনে Column যোগ করুন।
আপনি আইটেমগুলিকে অনুভূমিকভাবে সাজানোর জন্য Row এবং উপাদানগুলিকে স্ট্যাক করার জন্য Box ব্যবহার করতে পারেন।

// ...
import androidx.compose.foundation.layout.Column

@Composable
fun MessageCard(msg: Message) {
    Column {
        Text(text = msg.author)
        Text(text = msg.body)
    }
}

পূর্বরূপ দেখান
পূর্বরূপ লুকান

একটি ইমেজ উপাদান যোগ করুন

প্রেরকের প্রোফাইল ছবি যোগ করে আপনার বার্তা কার্ডকে সমৃদ্ধ করুন। আপনার ফটো লাইব্রেরি থেকে একটি ছবি আমদানি করতে রিসোর্স ম্যানেজার ব্যবহার করুন বা এটি ব্যবহার করুন। একটি সুগঠিত নকশা এবং এর ভিতরে একটি Image সংমিশ্রণযোগ্য করতে একটি Row যোগ করুন।

// ...
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Row
import androidx.compose.ui.res.painterResource

@Composable
fun MessageCard(msg: Message) {
    Row {
        Image(
            painter = painterResource(R.drawable.profile_picture),
            contentDescription = "Contact profile picture",
        )
    
       Column {
            Text(text = msg.author)
            Text(text = msg.body)
        }
  
    }
  
}
  
পূর্বরূপ দেখান
পূর্বরূপ লুকান

আপনার লেআউট কনফিগার করুন

আপনার বার্তা বিন্যাস সঠিক কাঠামো আছে কিন্তু এর উপাদানগুলি ভাল ব্যবধানে নেই এবং চিত্রটি খুব বড়! একটি কম্পোজযোগ্য সাজাতে বা কনফিগার করতে, কম্পোজ মডিফায়ার ব্যবহার করে। তারা আপনাকে কম্পোজেবলের আকার, লেআউট, চেহারা পরিবর্তন করতে বা উচ্চ-স্তরের মিথস্ক্রিয়া যোগ করার অনুমতি দেয়, যেমন একটি উপাদানকে ক্লিকযোগ্য করে তোলা। আপনি আরও সমৃদ্ধ কম্পোজেবল তৈরি করতে তাদের চেইন করতে পারেন। আপনি লেআউট উন্নত করতে তাদের কিছু ব্যবহার করবেন।

// ...
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.unit.dp

@Composable
fun MessageCard(msg: Message) {
    // Add padding around our message
    Row(modifier = Modifier.padding(all = 8.dp)) {
        Image(
            painter = painterResource(R.drawable.profile_picture),
            contentDescription = "Contact profile picture",
            modifier = Modifier
                // Set image size to 40 dp
                .size(40.dp)
                // Clip image to be shaped as a circle
                .clip(CircleShape)
        )

        // Add a horizontal space between the image and the column
        Spacer(modifier = Modifier.width(8.dp))

        Column {
            Text(text = msg.author)
            // Add a vertical space between the author and message texts
            Spacer(modifier = Modifier.height(4.dp))
            Text(text = msg.body)
        }
    }
}
  
পূর্বরূপ দেখান
পূর্বরূপ লুকান
// ...

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MessageCard(Message("Android", "Jetpack Compose"))
        }
    }
}

data class Message(val author: String, val body: String)

@Composable
fun MessageCard(msg: Message) {
    Text(text = msg.author)
    Text(text = msg.body)
}

@Preview
@Composable
fun PreviewMessageCard() {
    MessageCard(
        msg = Message("Lexi", "Hey, take a look at Jetpack Compose, it's great!")
    )
}

  
পূর্বরূপ দেখান
পূর্বরূপ লুকান
দুটি ওভারল্যাপিং টেক্সট কম্পোজেবলের পূর্বরূপ
// ...
import androidx.compose.foundation.layout.Column

@Composable
fun MessageCard(msg: Message) {
    Column {
        Text(text = msg.author)
        Text(text = msg.body)
    }
}

পূর্বরূপ দেখান
পূর্বরূপ লুকান
// ...
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Row
import androidx.compose.ui.res.painterResource

@Composable
fun MessageCard(msg: Message) {
    Row {
        Image(
            painter = painterResource(R.drawable.profile_picture),
            contentDescription = "Contact profile picture",
        )
    
       Column {
            Text(text = msg.author)
            Text(text = msg.body)
        }
  
    }
  
}
  
পূর্বরূপ দেখান
পূর্বরূপ লুকান
// ...
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.unit.dp

@Composable
fun MessageCard(msg: Message) {
    // Add padding around our message
    Row(modifier = Modifier.padding(all = 8.dp)) {
        Image(
            painter = painterResource(R.drawable.profile_picture),
            contentDescription = "Contact profile picture",
            modifier = Modifier
                // Set image size to 40 dp
                .size(40.dp)
                // Clip image to be shaped as a circle
                .clip(CircleShape)
        )

        // Add a horizontal space between the image and the column
        Spacer(modifier = Modifier.width(8.dp))

        Column {
            Text(text = msg.author)
            // Add a vertical space between the author and message texts
            Spacer(modifier = Modifier.height(4.dp))
            Text(text = msg.body)
        }
    }
}
  
পূর্বরূপ দেখান
পূর্বরূপ লুকান

মেটেরিয়াল ডিজাইন ব্যবহার করুন

আপনার বার্তা ডিজাইনে এখন একটি লেআউট রয়েছে, কিন্তু এটি এখনও দুর্দান্ত দেখাচ্ছে না৷

জেটপ্যাক কম্পোজ ম্যাটেরিয়াল ডিজাইন 3 এবং এর UI উপাদানগুলিকে বাক্সের বাইরে একটি বাস্তবায়ন প্রদান করে। আপনি মেটেরিয়াল ডিজাইন স্টাইলিং ব্যবহার করে আমাদের MessageCard কম্পোজেবলের চেহারা উন্নত করবেন।

শুরু করতে, আপনার প্রোজেক্টে তৈরি ম্যাটেরিয়াল থিম, ComposeTutorialTheme , পাশাপাশি একটি Surface দিয়ে MessageCard ফাংশনটি মোড়ানো। এটি @Preview এবং setContent ফাংশনে উভয়ই করুন। এটি করার ফলে আপনার কম্পোজেবলগুলিকে আপনার অ্যাপের থিমে সংজ্ঞায়িত স্টাইলগুলিকে উত্তরাধিকার সূত্রে পেতে অনুমতি দেবে যা আপনার অ্যাপ জুড়ে ধারাবাহিকতা নিশ্চিত করবে।

মেটেরিয়াল ডিজাইন তিনটি স্তম্ভের চারপাশে নির্মিত: Color , Typography এবং Shape । আপনি তাদের একে একে যুক্ত করবেন।

দ্রষ্টব্য: খালি রচনা কার্যকলাপ টেমপ্লেট আপনার প্রকল্পের জন্য একটি ডিফল্ট থিম তৈরি করে যা আপনাকে MaterialTheme কাস্টমাইজ করতে দেয়। আপনি যদি আপনার প্রজেক্টের নাম ComposeTutorial থেকে ভিন্ন কিছু রাখেন, তাহলে আপনি ui.theme সাবপ্যাকেজে Theme.kt ফাইলে আপনার কাস্টম থিম খুঁজে পেতে পারেন।

// ...

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ComposeTutorialTheme {
                Surface(modifier = Modifier.fillMaxSize()) {
                    MessageCard(Message("Android", "Jetpack Compose"))
                }
            }
        }
    }
}

@Preview
@Composable
fun PreviewMessageCard() {
    ComposeTutorialTheme {
        Surface {
            MessageCard(
                msg = Message("Lexi", "Take a look at Jetpack Compose, it's great!")
            )
        }
    }
}


  
পূর্বরূপ দেখান
পূর্বরূপ লুকান

রঙ

মোড়ানো থিম থেকে রং দিয়ে স্টাইল করতে MaterialTheme.colorScheme ব্যবহার করুন। আপনি থিম থেকে এই মানগুলি ব্যবহার করতে পারেন যেখানে একটি রঙের প্রয়োজন হয়। এই উদাহরণটি গতিশীল থিমিং রঙ ব্যবহার করে (ডিভাইস পছন্দ দ্বারা সংজ্ঞায়িত)। আপনি এটি পরিবর্তন করতে MaterialTheme.kt ফাইলে dynamicColor false সেট করতে পারেন।

শিরোনাম স্টাইল করুন এবং ছবিতে একটি বর্ডার যোগ করুন।

// ...
import androidx.compose.foundation.border
import androidx.compose.material3.MaterialTheme

@Composable
fun MessageCard(msg: Message) {
   Row(modifier = Modifier.padding(all = 8.dp)) {
       Image(
           painter = painterResource(R.drawable.profile_picture),
           contentDescription = null,
           modifier = Modifier
               .size(40.dp)
               .clip(CircleShape)
               .border(1.5.dp, MaterialTheme.colorScheme.primary, CircleShape)
       )

       Spacer(modifier = Modifier.width(8.dp))

       Column {
           Text(
               text = msg.author,
               color = MaterialTheme.colorScheme.secondary
           )

           Spacer(modifier = Modifier.height(4.dp))
           Text(text = msg.body)
       }
   }
}

  
পূর্বরূপ দেখান
পূর্বরূপ লুকান

টাইপোগ্রাফি

ম্যাটেরিয়াল MaterialTheme মেটেরিয়াল টাইপোগ্রাফি শৈলী পাওয়া যায়, শুধু সেগুলিকে Text কম্পোজেবলে যোগ করুন।

// ...

@Composable
fun MessageCard(msg: Message) {
   Row(modifier = Modifier.padding(all = 8.dp)) {
       Image(
           painter = painterResource(R.drawable.profile_picture),
           contentDescription = null,
           modifier = Modifier
               .size(40.dp)
               .clip(CircleShape)
               .border(1.5.dp, MaterialTheme.colorScheme.primary, CircleShape)
       )
       Spacer(modifier = Modifier.width(8.dp))

       Column {
           Text(
               text = msg.author,
               color = MaterialTheme.colorScheme.secondary,
               style = MaterialTheme.typography.titleSmall
           )

           Spacer(modifier = Modifier.height(4.dp))

           Text(
               text = msg.body,
               style = MaterialTheme.typography.bodyMedium
           )
       }
   }
}

  
পূর্বরূপ দেখান
পূর্বরূপ লুকান

আকৃতি

Shape দিয়ে আপনি চূড়ান্ত স্পর্শ যোগ করতে পারেন। প্রথমে, একটি Surface কম্পোজেবলের চারপাশে মেসেজের বডি টেক্সটটি মোড়ানো। এটি করার ফলে বার্তার শরীরের আকৃতি এবং উচ্চতা কাস্টমাইজ করা যায়। আরও ভালো লেআউটের জন্য বার্তায় প্যাডিং যোগ করা হয়েছে।

// ...
import androidx.compose.material3.Surface

@Composable
fun MessageCard(msg: Message) {
   Row(modifier = Modifier.padding(all = 8.dp)) {
       Image(
           painter = painterResource(R.drawable.profile_picture),
           contentDescription = null,
           modifier = Modifier
               .size(40.dp)
               .clip(CircleShape)
               .border(1.5.dp, MaterialTheme.colorScheme.primary, CircleShape)
       )
       Spacer(modifier = Modifier.width(8.dp))

       Column {
           Text(
               text = msg.author,
               color = MaterialTheme.colorScheme.secondary,
               style = MaterialTheme.typography.titleSmall
           )

           Spacer(modifier = Modifier.height(4.dp))

           Surface(shape = MaterialTheme.shapes.medium, shadowElevation = 1.dp) {
               Text(
                   text = msg.body,
                   modifier = Modifier.padding(all = 4.dp),
                   style = MaterialTheme.typography.bodyMedium
               )
           }
       }
   }
}

  
পূর্বরূপ দেখান
পূর্বরূপ লুকান

অন্ধকার থিম সক্ষম করুন

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

আপনি আলাদা ফাংশন হিসাবে আপনার ফাইলে একাধিক পূর্বরূপ তৈরি করতে পারেন, বা একই ফাংশনে একাধিক টীকা যোগ করতে পারেন।

একটি নতুন পূর্বরূপ টীকা যোগ করুন এবং রাতের মোড সক্ষম করুন৷

// ...
import android.content.res.Configuration

@Preview(name = "Light Mode")
@Preview(
    uiMode = Configuration.UI_MODE_NIGHT_YES,
    showBackground = true,
    name = "Dark Mode"
)
@Composable
fun PreviewMessageCard() {
   ComposeTutorialTheme {
    Surface {
      MessageCard(
        msg = Message("Lexi", "Hey, take a look at Jetpack Compose, it's great!")
      )
    }
   }
}
  
পূর্বরূপ দেখান
পূর্বরূপ লুকান

হালকা এবং অন্ধকার থিমগুলির জন্য রঙের পছন্দগুলি IDE-উত্পাদিত Theme.kt ফাইলে সংজ্ঞায়িত করা হয়েছে৷

এখনও অবধি, আপনি একটি বার্তা UI উপাদান তৈরি করেছেন যা একটি চিত্র এবং দুটি পাঠ্যকে বিভিন্ন শৈলী সহ প্রদর্শন করে এবং এটি হালকা এবং অন্ধকার উভয় থিমেই ভাল দেখায়!

// ...
import android.content.res.Configuration

@Preview(name = "Light Mode")
@Preview(
    uiMode = Configuration.UI_MODE_NIGHT_YES,
    showBackground = true,
    name = "Dark Mode"
)
@Composable
fun PreviewMessageCard() {
   ComposeTutorialTheme {
    Surface {
      MessageCard(
        msg = Message("Lexi", "Hey, take a look at Jetpack Compose, it's great!")
      )
    }
   }
}
  
পূর্বরূপ দেখান
পূর্বরূপ লুকান
// ...

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ComposeTutorialTheme {
                Surface(modifier = Modifier.fillMaxSize()) {
                    MessageCard(Message("Android", "Jetpack Compose"))
                }
            }
        }
    }
}

@Preview
@Composable
fun PreviewMessageCard() {
    ComposeTutorialTheme {
        Surface {
            MessageCard(
                msg = Message("Lexi", "Take a look at Jetpack Compose, it's great!")
            )
        }
    }
}


  
পূর্বরূপ দেখান
পূর্বরূপ লুকান
// ...
import androidx.compose.foundation.border
import androidx.compose.material3.MaterialTheme

@Composable
fun MessageCard(msg: Message) {
   Row(modifier = Modifier.padding(all = 8.dp)) {
       Image(
           painter = painterResource(R.drawable.profile_picture),
           contentDescription = null,
           modifier = Modifier
               .size(40.dp)
               .clip(CircleShape)
               .border(1.5.dp, MaterialTheme.colorScheme.primary, CircleShape)
       )

       Spacer(modifier = Modifier.width(8.dp))

       Column {
           Text(
               text = msg.author,
               color = MaterialTheme.colorScheme.secondary
           )

           Spacer(modifier = Modifier.height(4.dp))
           Text(text = msg.body)
       }
   }
}

  
পূর্বরূপ দেখান
পূর্বরূপ লুকান
// ...

@Composable
fun MessageCard(msg: Message) {
   Row(modifier = Modifier.padding(all = 8.dp)) {
       Image(
           painter = painterResource(R.drawable.profile_picture),
           contentDescription = null,
           modifier = Modifier
               .size(40.dp)
               .clip(CircleShape)
               .border(1.5.dp, MaterialTheme.colorScheme.primary, CircleShape)
       )
       Spacer(modifier = Modifier.width(8.dp))

       Column {
           Text(
               text = msg.author,
               color = MaterialTheme.colorScheme.secondary,
               style = MaterialTheme.typography.titleSmall
           )

           Spacer(modifier = Modifier.height(4.dp))

           Text(
               text = msg.body,
               style = MaterialTheme.typography.bodyMedium
           )
       }
   }
}

  
পূর্বরূপ দেখান
পূর্বরূপ লুকান
// ...
import androidx.compose.material3.Surface

@Composable
fun MessageCard(msg: Message) {
   Row(modifier = Modifier.padding(all = 8.dp)) {
       Image(
           painter = painterResource(R.drawable.profile_picture),
           contentDescription = null,
           modifier = Modifier
               .size(40.dp)
               .clip(CircleShape)
               .border(1.5.dp, MaterialTheme.colorScheme.primary, CircleShape)
       )
       Spacer(modifier = Modifier.width(8.dp))

       Column {
           Text(
               text = msg.author,
               color = MaterialTheme.colorScheme.secondary,
               style = MaterialTheme.typography.titleSmall
           )

           Spacer(modifier = Modifier.height(4.dp))

           Surface(shape = MaterialTheme.shapes.medium, shadowElevation = 1.dp) {
               Text(
                   text = msg.body,
                   modifier = Modifier.padding(all = 4.dp),
                   style = MaterialTheme.typography.bodyMedium
               )
           }
       }
   }
}

  
পূর্বরূপ দেখান
পূর্বরূপ লুকান
// ...
import android.content.res.Configuration

@Preview(name = "Light Mode")
@Preview(
    uiMode = Configuration.UI_MODE_NIGHT_YES,
    showBackground = true,
    name = "Dark Mode"
)
@Composable
fun PreviewMessageCard() {
   ComposeTutorialTheme {
    Surface {
      MessageCard(
        msg = Message("Lexi", "Hey, take a look at Jetpack Compose, it's great!")
      )
    }
   }
}
  
পূর্বরূপ দেখান
পূর্বরূপ লুকান
প্রিভিউ হালকা এবং গাঢ় থিমযুক্ত কম্পোজেবল উভয়ই দেখাচ্ছে।

বার্তাগুলির একটি তালিকা তৈরি করুন

একটি বার্তার সাথে একটি চ্যাট কিছুটা একাকী বোধ করে, তাই আমরা একাধিক বার্তার জন্য কথোপকথন পরিবর্তন করতে যাচ্ছি। আপনাকে একটি Conversation ফাংশন তৈরি করতে হবে যা একাধিক বার্তা দেখাবে। এই ব্যবহারের ক্ষেত্রে, কম্পোজের LazyColumn এবং LazyRow ব্যবহার করুন। এই কম্পোজেবলগুলি কেবলমাত্র সেই উপাদানগুলিকে রেন্ডার করে যা স্ক্রিনে দৃশ্যমান, তাই এগুলি দীর্ঘ তালিকার জন্য খুব দক্ষ হওয়ার জন্য ডিজাইন করা হয়েছে।

এই কোড স্নিপেটে, আপনি দেখতে পারেন যে LazyColumn একটি items চাইল্ড আছে। এটি একটি প্যারামিটার হিসাবে একটি List নেয় এবং এর ল্যাম্বডা একটি প্যারামিটার পায় যা আমরা message নাম দিয়েছি (আমরা যা চাই তা নাম দিতে পারতাম) যা Message একটি উদাহরণ। সংক্ষেপে, এই ল্যাম্বডা প্রদত্ত List প্রতিটি আইটেমের জন্য বলা হয়। কথোপকথনটি দ্রুত বুটস্ট্র্যাপ করতে আপনার প্রকল্পে নমুনা ডেটাসেটটি অনুলিপি করুন।

// ...
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items

@Composable
fun Conversation(messages: List<Message>) {
    LazyColumn {
        items(messages) { message ->
            MessageCard(message)
        }
    }
}

@Preview
@Composable
fun PreviewConversation() {
    ComposeTutorialTheme {
        Conversation(SampleData.conversationSample)
    }
}

  
পূর্বরূপ দেখান
পূর্বরূপ লুকান

প্রসারিত করার সময় বার্তাগুলিকে অ্যানিমেট করুন

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

কম্পোজেবল ফাংশন remember ব্যবহার করে স্থানীয় অবস্থাকে মেমরিতে সংরক্ষণ করতে পারে এবং mutableStateOf এ পাস করা মানের পরিবর্তনগুলি ট্র্যাক করতে পারে। মান আপডেট করা হলে কম্পোজেবল (এবং তাদের সন্তানদের) এই অবস্থা ব্যবহার করে স্বয়ংক্রিয়ভাবে পুনরায় আঁকা হবে। একে বলা হয় পুনর্গঠন

Compose এর স্টেট APIs ব্যবহার করে remember এবং mutableStateOf , রাজ্যের যেকোন পরিবর্তন স্বয়ংক্রিয়ভাবে UI আপডেট করে।

দ্রষ্টব্য: আপনাকে সঠিকভাবে Kotlin এর অর্পিত সম্পত্তি সিনট্যাক্স (কীওয়ার্ড by ) ব্যবহার করতে নিম্নলিখিত আমদানি যোগ করতে হবে। Alt+Enter বা Option+Enter এগুলি আপনার জন্য যোগ করে।
import androidx.compose.runtime.getValue import androidx.compose.runtime.setValue

// ...
import androidx.compose.foundation.clickable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue

class MainActivity : ComponentActivity() {
   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContent {
           ComposeTutorialTheme {
               Conversation(SampleData.conversationSample)
           }
       }
   }
}

@Composable
fun MessageCard(msg: Message) {
    Row(modifier = Modifier.padding(all = 8.dp)) {
        Image(
            painter = painterResource(R.drawable.profile_picture),
            contentDescription = null,
            modifier = Modifier
                .size(40.dp)
                .clip(CircleShape)
                .border(1.5.dp, MaterialTheme.colorScheme.primary, CircleShape)
        )
        Spacer(modifier = Modifier.width(8.dp))

        // We keep track if the message is expanded or not in this
        // variable
        var isExpanded by remember { mutableStateOf(false) }

        // We toggle the isExpanded variable when we click on this Column
        Column(modifier = Modifier.clickable { isExpanded = !isExpanded }) {
            Text(
                text = msg.author,
                color = MaterialTheme.colorScheme.secondary,
                style = MaterialTheme.typography.titleSmall
            )

            Spacer(modifier = Modifier.height(4.dp))

            Surface(
                shape = MaterialTheme.shapes.medium,
                shadowElevation = 1.dp,
            ) {
                Text(
                    text = msg.body,
                    modifier = Modifier.padding(all = 4.dp),
                    // If the message is expanded, we display all its content
                    // otherwise we only display the first line
                    maxLines = if (isExpanded) Int.MAX_VALUE else 1,
                    style = MaterialTheme.typography.bodyMedium
                )
            }
        }
    }
}

  
পূর্বরূপ দেখান
পূর্বরূপ লুকান

এখন আমরা যখন একটি বার্তায় ক্লিক করি তখন আপনি isExpanded এর উপর ভিত্তি করে বার্তা সামগ্রীর পটভূমি পরিবর্তন করতে পারেন। আপনি কম্পোজেবলের ক্লিক ইভেন্টগুলি পরিচালনা করতে clickable মডিফায়ার ব্যবহার করবেন। শুধু Surface পটভূমির রঙ টগল করার পরিবর্তে, আপনি পটভূমির রঙকে ধীরে ধীরে MaterialTheme.colorScheme.surface থেকে MaterialTheme.colorScheme.primary এবং এর বিপরীতে পরিবর্তন করে অ্যানিমেট করবেন। এটি করার জন্য, আপনি animateColorAsState ফাংশন ব্যবহার করবেন। পরিশেষে, আপনি বার্তা কন্টেইনারের আকার মসৃণভাবে অ্যানিমেট করতে animateContentSize সংশোধক ব্যবহার করবেন:

// ...
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.animateContentSize

@Composable
fun MessageCard(msg: Message) {
    Row(modifier = Modifier.padding(all = 8.dp)) {
        Image(
            painter = painterResource(R.drawable.profile_picture),
            contentDescription = null,
            modifier = Modifier
                .size(40.dp)
                .clip(CircleShape)
                .border(1.5.dp, MaterialTheme.colorScheme.secondary, CircleShape)
        )
        Spacer(modifier = Modifier.width(8.dp))

        // We keep track if the message is expanded or not in this
        // variable
        var isExpanded by remember { mutableStateOf(false) }
        // surfaceColor will be updated gradually from one color to the other
        val surfaceColor by animateColorAsState(
            if (isExpanded) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.surface,
        )

        // We toggle the isExpanded variable when we click on this Column
        Column(modifier = Modifier.clickable { isExpanded = !isExpanded }) {
            Text(
                text = msg.author,
                color = MaterialTheme.colorScheme.secondary,
                style = MaterialTheme.typography.titleSmall
            )

            Spacer(modifier = Modifier.height(4.dp))

            Surface(
                shape = MaterialTheme.shapes.medium,
                shadowElevation = 1.dp,
                // surfaceColor color will be changing gradually from primary to surface
                color = surfaceColor,
                // animateContentSize will change the Surface size gradually
                modifier = Modifier.animateContentSize().padding(1.dp)
            ) {
                Text(
                    text = msg.body,
                    modifier = Modifier.padding(all = 4.dp),
                    // If the message is expanded, we display all its content
                    // otherwise we only display the first line
                    maxLines = if (isExpanded) Int.MAX_VALUE else 1,
                    style = MaterialTheme.typography.bodyMedium
                )
            }
        }
    }
}

  
পূর্বরূপ দেখান
পূর্বরূপ লুকান
// ...
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items

@Composable
fun Conversation(messages: List<Message>) {
    LazyColumn {
        items(messages) { message ->
            MessageCard(message)
        }
    }
}

@Preview
@Composable
fun PreviewConversation() {
    ComposeTutorialTheme {
        Conversation(SampleData.conversationSample)
    }
}

  
পূর্বরূপ দেখান
পূর্বরূপ লুকান
// ...
import androidx.compose.foundation.clickable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue

class MainActivity : ComponentActivity() {
   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContent {
           ComposeTutorialTheme {
               Conversation(SampleData.conversationSample)
           }
       }
   }
}

@Composable
fun MessageCard(msg: Message) {
    Row(modifier = Modifier.padding(all = 8.dp)) {
        Image(
            painter = painterResource(R.drawable.profile_picture),
            contentDescription = null,
            modifier = Modifier
                .size(40.dp)
                .clip(CircleShape)
                .border(1.5.dp, MaterialTheme.colorScheme.primary, CircleShape)
        )
        Spacer(modifier = Modifier.width(8.dp))

        // We keep track if the message is expanded or not in this
        // variable
        var isExpanded by remember { mutableStateOf(false) }

        // We toggle the isExpanded variable when we click on this Column
        Column(modifier = Modifier.clickable { isExpanded = !isExpanded }) {
            Text(
                text = msg.author,
                color = MaterialTheme.colorScheme.secondary,
                style = MaterialTheme.typography.titleSmall
            )

            Spacer(modifier = Modifier.height(4.dp))

            Surface(
                shape = MaterialTheme.shapes.medium,
                shadowElevation = 1.dp,
            ) {
                Text(
                    text = msg.body,
                    modifier = Modifier.padding(all = 4.dp),
                    // If the message is expanded, we display all its content
                    // otherwise we only display the first line
                    maxLines = if (isExpanded) Int.MAX_VALUE else 1,
                    style = MaterialTheme.typography.bodyMedium
                )
            }
        }
    }
}

  
পূর্বরূপ দেখান
পূর্বরূপ লুকান
// ...
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.animateContentSize

@Composable
fun MessageCard(msg: Message) {
    Row(modifier = Modifier.padding(all = 8.dp)) {
        Image(
            painter = painterResource(R.drawable.profile_picture),
            contentDescription = null,
            modifier = Modifier
                .size(40.dp)
                .clip(CircleShape)
                .border(1.5.dp, MaterialTheme.colorScheme.secondary, CircleShape)
        )
        Spacer(modifier = Modifier.width(8.dp))

        // We keep track if the message is expanded or not in this
        // variable
        var isExpanded by remember { mutableStateOf(false) }
        // surfaceColor will be updated gradually from one color to the other
        val surfaceColor by animateColorAsState(
            if (isExpanded) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.surface,
        )

        // We toggle the isExpanded variable when we click on this Column
        Column(modifier = Modifier.clickable { isExpanded = !isExpanded }) {
            Text(
                text = msg.author,
                color = MaterialTheme.colorScheme.secondary,
                style = MaterialTheme.typography.titleSmall
            )

            Spacer(modifier = Modifier.height(4.dp))

            Surface(
                shape = MaterialTheme.shapes.medium,
                shadowElevation = 1.dp,
                // surfaceColor color will be changing gradually from primary to surface
                color = surfaceColor,
                // animateContentSize will change the Surface size gradually
                modifier = Modifier.animateContentSize().padding(1.dp)
            ) {
                Text(
                    text = msg.body,
                    modifier = Modifier.padding(all = 4.dp),
                    // If the message is expanded, we display all its content
                    // otherwise we only display the first line
                    maxLines = if (isExpanded) Int.MAX_VALUE else 1,
                    style = MaterialTheme.typography.bodyMedium
                )
            }
        }
    }
}

  
পূর্বরূপ দেখান
পূর্বরূপ লুকান

পরবর্তী পদক্ষেপ

অভিনন্দন, আপনি রচনা টিউটোরিয়ালটি শেষ করেছেন! আপনি একটি সাধারণ চ্যাট স্ক্রীন তৈরি করেছেন যাতে একটি চিত্র এবং পাঠ্য সম্বলিত প্রসারণযোগ্য এবং অ্যানিমেটেড বার্তাগুলির একটি তালিকা দেখানো হয়, যা একটি গাঢ় থিম অন্তর্ভুক্ত এবং পূর্বরূপ সহ মেটেরিয়াল ডিজাইনের নীতিগুলি ব্যবহার করে ডিজাইন করা হয়েছে - সমস্ত কোডের 100 লাইনের নিচে!

আপনি এখন পর্যন্ত যা শিখেছেন তা এখানে:

  • কম্পোজযোগ্য ফাংশন সংজ্ঞায়িত করা
  • আপনার কম্পোজেবল বিভিন্ন উপাদান যোগ করা
  • লেআউট কম্পোজেবল ব্যবহার করে আপনার UI উপাদান গঠন করা
  • মডিফায়ার ব্যবহার করে কম্পোজেবল প্রসারিত করা
  • একটি দক্ষ তালিকা তৈরি করা
  • রাষ্ট্রের ট্র্যাক রাখা এবং এটি সংশোধন করা
  • একটি কম্পোজেবল ব্যবহারকারীর মিথস্ক্রিয়া যোগ করা
  • বার্তাগুলিকে প্রসারিত করার সময় অ্যানিমেটিং করা৷

আপনি যদি এই পদক্ষেপগুলির মধ্যে কিছু গভীরভাবে খনন করতে চান তবে নীচের সংস্থানগুলি অন্বেষণ করুন৷

পরবর্তী পদক্ষেপ

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