Compose-এ Material Design 2

Jetpack Compose, মেটেরিয়াল ডিজাইন ইমপ্লিমেন্ট করার সুবিধা দেয়, এটি হল ডিজিটাল ইন্টারফেস তৈরি করার জন্য একটি বিস্তারিত ডিজাইন সিস্টেম। মেটেরিয়াল ডিজাইন কম্পোনেন্ট (বোতাম, কার্ড, সুইচ ইত্যাদি) মেটেরিয়াল থিমিংয়ের উপর ভিত্তি করে তৈরি করা হয়, যা আপনার প্রোডাক্টের ব্র্যান্ডকে আরও ভালোভাবে ফুটিয়ে তুলতে মেটেরিয়াল ডিজাইন কাস্টমাইজ করার একটি পদ্ধতিগত উপায়। একটি Material থিমের মধ্যে রঙ, টাইপোগ্রাফি এবং আকৃতি অ্যাট্রিবিউট থাকে। এইসব অ্যাট্রিবিউট কাস্টমাইজ করলে, আপনার পরিবর্তনগুলি অ্যাপ তৈরি করার জন্য ব্যবহার করা কম্পোনেন্টগুলিতে অটোমেটিক প্রতিফলিত হয়।

Jetpack Compose MaterialTheme কম্পোজ করার উপযুক্ত আইটেমের মাধ্যমে এইসব ধারণা প্রয়োগ করে:

MaterialTheme(
    colors = // ...
    typography = // ...
    shapes = // ...
) {
    // app content
}

আপনার অ্যাপ্লিকেশনকে থিম করার জন্য MaterialTheme-এ পাস করা প্যারামিটার কনফিগার করুন।

দুটি বিপরীতধর্মী স্ক্রিনশট। প্রথমটিতে ডিফল্ট MaterialTheme স্টাইলিং ব্যবহার করা হয়েছে, দ্বিতীয় স্ক্রিনশটে পরিবর্তিত স্টাইলিং ব্যবহার করা হয়েছে।
ছবি ১. প্রথম স্ক্রিনশটে এমন একটি অ্যাপ দেখানো হয়েছে যা `MaterialTheme` কনফিগার করে না, তাই এটি ডিফল্ট স্টাইলিং ব্যবহার করে। দ্বিতীয় স্ক্রিনশটে এমন একটি অ্যাপ দেখানো হয়েছে যা স্টাইলিং কাস্টমাইজ করার জন্য `MaterialTheme`-এ প্যারামিটার পাস করে।

রঙ

Color ক্লাসের মাধ্যমে Compose-এ রঙ মডেল করা হয়, এটি একটি ডেটা-হোল্ডিং ক্লাস।

val Red = Color(0xffff0000)
val Blue = Color(red = 0f, green = 0f, blue = 1f)

আপনি এগুলিকে যেভাবে খুশি সেভাবে সাজাতে পারলেও (টপ-লেভেল কনস্ট্যান্ট হিসেবে, কোনও সিঙ্গেলটনের মধ্যে অথবা ইনলাইন হিসেবে ডিফাইন করা), আমরা দৃঢ়ভাবে সাজেস্ট করি যে আপনার থিমে কালার নির্দিষ্ট করুন এবং সেখান থেকে কালার রিট্রিভ করুন। এই পদ্ধতির মাধ্যমে ডার্ক থিম ও নেস্টেড থিম ব্যবহার করা যায়।

থিমের কালার প্যালেটের উদাহরণ
ছবি ২. Material কালার সিস্টেম।

Material color system মডেল করার জন্য Compose Colors ক্লাস প্রদান করে। Colors লাইট বা ডার্ক রঙের সেট তৈরি করার জন্য বিল্ডার ফাংশন প্রদান করে:

private val Yellow200 = Color(0xffffeb46)
private val Blue200 = Color(0xff91a4fc)
// ...

private val DarkColors = darkColors(
    primary = Yellow200,
    secondary = Blue200,
    // ...
)
private val LightColors = lightColors(
    primary = Yellow500,
    primaryVariant = Yellow400,
    secondary = Blue700,
    // ...
)

Colors নির্ধারণ করার পরে, আপনি সেগুলি MaterialTheme-এ পাস করতে পারবেন:

MaterialTheme(
    colors = if (darkTheme) DarkColors else LightColors
) {
    // app content
}

থিমের রঙ ব্যবহার করুন

আপনি MaterialTheme কম্পোজ করার উপযুক্ত আইটেমকে দেওয়া Colors MaterialTheme.colors ব্যবহার করে ফিরিয়ে আনতে পারবেন।

Text(
    text = "Hello theming",
    color = MaterialTheme.colors.primary
)

সারফেস ও কন্টেন্টের রঙ

অনেক কম্পোনেন্ট রঙ ও কন্টেন্ট রঙের একটি পেয়ার গ্রহণ করে:

Surface(
    color = MaterialTheme.colors.surface,
    contentColor = contentColorFor(color),
    // ...
) { /* ... */ }

TopAppBar(
    backgroundColor = MaterialTheme.colors.primarySurface,
    contentColor = contentColorFor(backgroundColor),
    // ...
) { /* ... */ }

এটি আপনাকে শুধুমাত্র কম্পোজ করার উপযুক্ত আইটেমের রঙ সেট করতে দেয় না, এর সাথে সাথে এর মধ্যে থাকা কম্পোজ করার উপযুক্ত আইটেমের কন্টেন্টের জন্য একটি ডিফল্ট রঙও প্রদান করে। অনেক কম্পোজেবল ডিফল্ট হিসেবে এই কন্টেন্ট কালার ব্যবহার করে। যেমন, Text তার রঙ তার পেরেন্টের কন্টেন্টের রঙের উপর ভিত্তি করে তৈরি করে এবং Icon সেই রঙ ব্যবহার করে তার টিন্ট সেট করে।

একই ব্যানারের দুটি উদাহরণ, আলাদা আলাদা রঙ সহ
ছবি ৩. আলাদা আলাদা ব্যাকগ্রাউন্ড কালার সেট করলে আলাদা আলাদা টেক্সট ও আইকন কালার তৈরি হয়।

contentColorFor() পদ্ধতিটি যেকোনও থিমের রঙের জন্য উপযুক্ত "চালু" রঙ পুনরুদ্ধার করে। যেমন, আপনি যদি Surface-এ primary ব্যাকগ্রাউন্ড কালার সেট করেন, তাহলে এটি onPrimary-কে কন্টেন্ট কালার হিসেবে সেট করতে এই ফাংশন ব্যবহার করে। আপনি থিম নয় এমন ব্যাকগ্রাউন্ড কালার সেট করলে, আপনাকে উপযুক্ত কন্টেন্ট কালারও নির্দিষ্ট করতে হবে। হায়ারার্কিতে প্রদত্ত পজিশনে বর্তমান ব্যাকগ্রাউন্ডের জন্য পছন্দসই কন্টেন্ট কালার রিট্রিভ করতে LocalContentColor ব্যবহার করুন।

কন্টেন্ট আলফা

গুরুত্ব বোঝাতে এবং ভিজ্যুয়াল হায়ারার্কি প্রদান করতে, কন্টেন্টের উপর কতটা জোর দেবেন তা প্রায়ই পরিবর্তন করতে হয়। Material Design টেক্সট লেজিবিলিটি সাজেস্ট করে যে বিভিন্ন গুরুত্বের লেভেল বোঝাতে বিভিন্ন লেভেলের অস্বচ্ছতা ব্যবহার করা উচিত।

Jetpack Compose LocalContentAlpha ব্যবহার করে এটি প্রয়োগ করে। আপনি এই CompositionLocal-এর জন্য একটি ভ্যালু প্রদান করে কোনও হায়ারার্কির জন্য কন্টেন্ট আলফা নির্দিষ্ট করতে পারবেন। নেস্টেড কম্পোজ করার উপযুক্ত আইটেম এই ভ্যালু ব্যবহার করে সেগুলির কন্টেন্টে আলফা ট্রিটমেন্ট প্রয়োগ করতে পারে। যেমন, Text এবং Icon ডিফল্ট হিসেবে LocalContentColor-এর কম্বিনেশন ব্যবহার করে যা LocalContentAlpha ব্যবহার করার জন্য অ্যাডজাস্ট করা হয়। মেটেরিয়ালে কিছু স্ট্যান্ডার্ড আলফা ভ্যালু (high, medium, disabled) নির্দিষ্ট করা আছে, যা ContentAlpha অবজেক্টের মাধ্যমে মডেল করা হয়।

// By default, both Icon & Text use the combination of LocalContentColor &
// LocalContentAlpha. De-emphasize content by setting content alpha
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
    Text(
        // ...
    )
}
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.disabled) {
    Icon(
        // ...
    )
    Text(
        // ...
    )
}

CompositionLocal সম্পর্কে আরও জানতে, কম্পোজিশন লোকাল সহ লোকাল স্কোপ করা ডেটা দেখুন।

টেক্সটের উপর জোর দেওয়ার বিভিন্ন লেভেল দেখানো একটি নিবন্ধের শীর্ষকের স্ক্রিনশট
ছবি ৪. তথ্যের হায়ারার্কি দৃশ্যমানভাবে কমিউনিকেট করতে টেক্সটে বিভিন্ন লেভেলের গুরুত্ব প্রয়োগ করুন। টেক্সটের প্রথম লাইনটি হল শীর্ষক এবং এতে সবচেয়ে গুরুত্বপূর্ণ তথ্য থাকে, তাই ContentAlpha.high ব্যবহার করা হয়। দ্বিতীয় লাইনে কম গুরুত্বপূর্ণ মেটাডেটা থাকে, তাই ContentAlpha.medium.
ব্যবহার করা হয়।

ডার্ক থিম

Compose-এ, আপনি Colors-এর বিভিন্ন সেট MaterialTheme কম্পোজ করার উপযুক্ত আইটেমে প্রদান করে লাইট ও ডার্ক থিম প্রয়োগ করেন:

@Composable
fun MyTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    content: @Composable () -> Unit
) {
    MaterialTheme(
        colors = if (darkTheme) DarkColors else LightColors,
        /*...*/
        content = content
    )
}

এই উদাহরণে, MaterialTheme-কে নিজস্ব কম্পোজ করার উপযুক্ত ফাংশনের মধ্যে র‍্যাপ করা হয়েছে, যা একটি প্যারামিটার গ্রহণ করে যা ডার্ক থিম ব্যবহার করা হবে কিনা তা নির্দিষ্ট করে। এই ক্ষেত্রে, darkTheme-এর ডিফল্ট মান পেতে, ফাংশনটি ডিভাইস থিম সেটিং কোয়েরি করে।

বর্তমান Colors হালকা বা গাঢ় কিনা তা চেক করতে আপনি এই ধরনের কোড ব্যবহার করতে পারেন:

val isLightTheme = MaterialTheme.colors.isLight
Icon(
    painterResource(
        id = if (isLightTheme) {
            R.drawable.ic_sun_24
        } else {
            R.drawable.ic_moon_24
        }
    ),
    contentDescription = "Theme"
)

উচ্চতা ওভারলে

Material-এ, বেশি উচ্চতায় থাকা ডার্ক থিমের সারফেস উচ্চতা ওভারলে পায়, যা সেগুলির ব্যাকগ্রাউন্ডকে হালকা করে। কোনও সারফেসের উচ্চতা যত বেশি হবে (সেটিকে কোনও কাল্পনিক আলোর উৎসের কাছাকাছি নিয়ে যাওয়া), সেই সারফেসটি তত বেশি হালকা হয়ে যাবে।

Surface কম্পোজ করার উপযুক্ত আইটেম, গাঢ় রঙ ব্যবহার করার সময় এইসব ওভারলে অটোমেটিক প্রয়োগ করে এবং সারফেস ব্যবহার করে এমন যেকোনও কম্পোজ করার উপযুক্ত আইটেমও তাই করে:

Surface(
    elevation = 2.dp,
    color = MaterialTheme.colors.surface, // color will be adjusted for elevation
    /*...*/
) { /*...*/ }

অ্যাপের স্ক্রিনশট, যেখানে বিভিন্ন উচ্চতা লেভেলে এলিমেন্টের জন্য ব্যবহৃত রঙগুলি সামান্য আলাদা
ছবি ৫. কার্ড ও নিচের নেভিগেশন, দু'টিই ব্যাকগ্রাউন্ড হিসেবে surface রঙ ব্যবহার করছে। কার্ড ও নিচের নেভিগেশন যেহেতু ব্যাকগ্রাউন্ডের উপরে আলাদা আলাদা উচ্চতায় রয়েছে, তাই সেগুলির রঙও সামান্য আলাদা–কার্ডের রঙ ব্যাকগ্রাউন্ডের চেয়ে হালকা এবং নিচের নেভিগেশনের রঙ কার্ডের চেয়ে হালকা।

Surface নেই এমন কাস্টম পরিস্থিতির জন্য, LocalElevationOverlay ব্যবহার করুন, একটি CompositionLocal যাতে Surface কম্পোনেন্ট দ্বারা ব্যবহৃত ElevationOverlay থাকে:

// Elevation overlays
// Implemented in Surface (and any components that use it)
val color = MaterialTheme.colors.surface
val elevation = 4.dp
val overlaidColor = LocalElevationOverlay.current?.apply(
    color, elevation
)

উচ্চতা ওভারলে বন্ধ করতে, কম্পোজ করার উপযুক্ত হায়ারার্কিতে বেছে নেওয়া পয়েন্টে null দিন:

MyTheme {
    CompositionLocalProvider(LocalElevationOverlay provides null) {
        // Content without elevation overlays
    }
}

সীমিত কালার অ্যাকসেন্ট

ডার্ক থিমের জন্য Material সীমিত কালার অ্যাকসেন্ট প্রয়োগ করার সাজেশন দেয়। এর জন্য বেশিরভাগ ক্ষেত্রে primary রঙের পরিবর্তে surface রঙ ব্যবহার করা উত্তম। TopAppBar ও BottomNavigation-এর মতো মেটেরিয়াল কম্পোজেবল ডিফল্ট হিসেবে এই আচরণ প্রয়োগ করে।

সীমিত কালার অ্যাকসেন্টের জন্য প্রাথমিক রঙের পরিবর্তে সারফেস কালার ব্যবহার করে এমন টপ অ্যাপ বারের একটি Material ডার্ক থিমের স্ক্রিনশট
ছবি ৬. সীমিত কালার অ্যাকসেন্ট সহ Material ডার্ক থিম। লাইট থিমে উপরের অ্যাপ বার প্রাথমিক রঙ এবং ডার্ক থিমে সারফেস রঙ ব্যবহার করে।

কাস্টম সিনারিওর জন্য, primarySurface এক্সটেনশন প্রপার্টি ব্যবহার করুন:

Surface(
    // Switches between primary in light theme and surface in dark theme
    color = MaterialTheme.colors.primarySurface,
    /*...*/
) { /*...*/ }

টাইপোগ্রাফি

Material একটি টাইপ সিস্টেম নির্দিষ্ট করে, যা আপনাকে অল্প সংখ্যক অর্থপূর্ণ নামযুক্ত স্টাইল ব্যবহার করতে উৎসাহিত করে।

বিভিন্ন স্টাইলে একাধিক আলাদা আলাদা টাইপফেসের উদাহরণ
ছবি ৭. মেটেরিয়ালের ধরন সংক্রান্ত সিস্টেম।

Compose Typography, TextStyle এবং ফন্ট-সম্পর্কিত ক্লাস সহ টাইপ সিস্টেম প্রয়োগ করে। Typography কনস্ট্রাক্টর প্রতিটি স্টাইলের জন্য ডিফল্ট অফার করে, তাই আপনি কাস্টমাইজ করতে চান না এমন যেকোনও কিছু বাদ দিতে পারেন:

val raleway = FontFamily(
    Font(R.font.raleway_regular),
    Font(R.font.raleway_medium, FontWeight.W500),
    Font(R.font.raleway_semibold, FontWeight.SemiBold)
)

val myTypography = Typography(
    h1 = TextStyle(
        fontFamily = raleway,
        fontWeight = FontWeight.W300,
        fontSize = 96.sp
    ),
    body1 = TextStyle(
        fontFamily = raleway,
        fontWeight = FontWeight.W600,
        fontSize = 16.sp
    )
    /*...*/
)
MaterialTheme(typography = myTypography, /*...*/) {
    /*...*/
}

আপনি যদি পুরো টেক্সট জুড়ে একই টাইপফেস ব্যবহার করতে চান, তাহলে defaultFontFamily প্যারামিটার নির্দিষ্ট করুন এবং যেকোনও TextStyle এলিমেন্টের fontFamily বাদ দিন:

val typography = Typography(defaultFontFamily = raleway)
MaterialTheme(typography = typography, /*...*/) {
    /*...*/
}

টেক্সট স্টাইল ব্যবহার করা

MaterialTheme.typography ব্যবহার করে TextStyle এলিমেন্ট অ্যাক্সেস করা হয়। নিম্নলিখিত TextStyle এলিমেন্টগুলি রিট্রিভ করুন:

Text(
    text = "Subtitle2 styled",
    style = MaterialTheme.typography.subtitle2
)

বিভিন্ন উদ্দেশ্যে বিভিন্ন ধরনের টাইপফেসের মিশ্রণ দেখানো স্ক্রিনশট
ছবি ৮. আপনার ব্র্যান্ডকে তুলে ধরতে বিভিন্ন ধরনের টাইপফেস ও স্টাইল ব্যবহার করুন।

আকার

Material একটি শেপ সিস্টেম নির্ধারণ করে, যা আপনাকে বড়, মাঝারি ও ছোট কম্পোনেন্টের জন্য শেপ নির্ধারণ করতে দেয়।

বিভিন্ন ধরনের মেটেরিয়াল ডিজাইন শেপ দেখায়
ছবি ৯. Material শেপ সিস্টেম।

Compose Shapes ক্লাসের মাধ্যমে শেপ সিস্টেম প্রয়োগ করে, যা আপনাকে প্রতিটি সাইজ ক্যাটেগরির জন্য CornerBasedShape নির্দিষ্ট করতে দেয়:

val shapes = Shapes(
    small = RoundedCornerShape(percent = 50),
    medium = RoundedCornerShape(0f),
    large = CutCornerShape(
        topStart = 16.dp,
        topEnd = 0.dp,
        bottomEnd = 0.dp,
        bottomStart = 16.dp
    )
)

MaterialTheme(shapes = shapes, /*...*/) {
    /*...*/
}

অনেক কম্পোনেন্ট ডিফল্ট হিসেবে এই আকারগুলি ব্যবহার করে। যেমন, Button, TextField এবং FloatingActionButton ডিফল্ট হিসেবে ছোট, AlertDialog ডিফল্ট হিসেবে মাঝারি এবং ModalDrawer ডিফল্ট হিসেবে বড় — সম্পূর্ণ ম্যাপিংয়ের জন্য আকৃতি স্কিম রেফারেন্স দেখুন।

আকার ব্যবহার করা

MaterialTheme.shapes ব্যবহার করে Shape এলিমেন্ট অ্যাক্সেস করা হয়। এই ধরনের কোড ব্যবহার করে Shape এলিমেন্ট রিট্রিভ করুন:

Surface(
    shape = MaterialTheme.shapes.medium, /*...*/
) {
    /*...*/
}

কোনও এলিমেন্ট কোন অবস্থায় আছে তা বোঝাতে Material শেপ ব্যবহার করে এমন অ্যাপের স্ক্রিনশট
ছবি ১০. ব্র্যান্ড বা স্টেটমেন্ট বোঝাতে শেপ ব্যবহার করুন।

ডিফল্ট স্টাইল

Android Views-এর ডিফল্ট স্টাইল-এর মতো কোনও ধারণা Compose-এ নেই। আপনি Material কম্পোনেন্ট র‍্যাপ করে নিজের overload কম্পোজ করা যায় এমন ফাংশন তৈরি করার মাধ্যমে একই ধরনের কার্যকারিতা প্রদান করতে পারেন। যেমন, বোতামের স্টাইল তৈরি করতে, আপনার নিজস্ব কম্পোজ করার উপযুক্ত ফাংশনে বোতামটি র‍্যাপ করুন, সরাসরি আপনার পছন্দমতো বা পরিবর্তন করতে হবে এমন প্যারামিটার সেট করুন এবং কন্টেন করা কম্পোজ করার উপযুক্ত ফাংশনে অন্যান্য প্যারামিটার এক্সপোজ করুন।

@Composable
fun MyButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    content: @Composable RowScope.() -> Unit
) {
    Button(
        colors = ButtonDefaults.buttonColors(
            backgroundColor = MaterialTheme.colors.secondary
        ),
        onClick = onClick,
        modifier = modifier,
        content = content
    )
}

থিম ওভারলে

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

এছাড়াও, View-ভিত্তিক স্ক্রিন থেকে Compose-এ মাইগ্রেট করার সময়, android:theme অ্যাট্রিবিউটের ব্যবহার নজরে রাখুন। কম্পোজ UI ট্রি-এর ওই অংশে আপনার সম্ভবত একটি নতুন MaterialTheme প্রয়োজন।

এই উদাহরণে, বিবরণের স্ক্রিনে বেশিরভাগ স্ক্রিনের জন্য PinkTheme ব্যবহার করা হয়েছে, এবং তারপরে প্রাসঙ্গিক বিভাগের জন্য BlueTheme ব্যবহার করা হয়েছে। নিচের স্ক্রিনশট ও কোড থেকে এই ধারণাটি স্পষ্ট বোঝা যায়:

নেস্টেড থিম দেখানো একটি অ্যাপের স্ক্রিনশট, যেখানে মূল স্ক্রিনের জন্য একটি পিঙ্ক থিম এবং সম্পর্কিত বিভাগের জন্য একটি নীল থিম রয়েছে
ছবি ১১. নেস্টেড থিম।

@Composable
fun DetailsScreen(/* ... */) {
    PinkTheme {
        // other content
        RelatedSection()
    }
}

@Composable
fun RelatedSection(/* ... */) {
    BlueTheme {
        // content
    }
}

কম্পোনেন্ট স্টেট

ইন্টার‍্যাক্ট করা যায় এমন মেটেরিয়াল কম্পোনেন্ট (ক্লিক করা, টগল করা ইত্যাদি) বিভিন্ন ভিজ্যুয়াল স্টেটে থাকতে পারে। স্টেটের মধ্যে চালু, বন্ধ, প্রেস করা ইত্যাদি অন্তর্ভুক্ত।

কম্পোজ করার উপযুক্ত আইটেমে প্রায়ই enabled প্যারামিটার থাকে। এটি false-এ সেট করলে ইন্টার‍্যাকশন বন্ধ হয়ে যায় এবং কম্পোনেন্টের স্টেটকে দৃশ্যমানভাবে বোঝাতে রঙ ও এলিভেশনের মতো প্রপার্টি পরিবর্তন করে।

দুটি বোতামের স্ক্রিনশট: একটি চালু, একটি বন্ধ, তাদের আলাদা আলাদা ভিজ্যুয়াল স্টেট দেখানো হচ্ছে
ছবি ১২. enabled = true (বাঁদিকে) ও enabled = false (ডানদিকে) সহ বোতাম।

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

Button(
    onClick = { /* ... */ },
    enabled = true,
    // Custom colors for different states
    colors = ButtonDefaults.buttonColors(
        backgroundColor = MaterialTheme.colors.secondary,
        disabledBackgroundColor = MaterialTheme.colors.onBackground
            .copy(alpha = 0.2f)
            .compositeOver(MaterialTheme.colors.background)
        // Also contentColor and disabledContentColor
    ),
    // Custom elevation for different states
    elevation = ButtonDefaults.elevation(
        defaultElevation = 8.dp,
        disabledElevation = 2.dp,
        // Also pressedElevation
    )
) { /* ... */ }

চালু ও বন্ধ করা অবস্থার জন্য অ্যাডজাস্ট করা রঙ ও উচ্চতা সহ দুটি বোতামের স্ক্রিনশট
ছবি ১৩. enabled = true (বাঁদিকে) ও enabled = false (ডানদিকে) সহ বোতাম, যার রঙ ও উচ্চতা সংক্রান্ত ভ্যালু অ্যাডজাস্ট করা হয়েছে।

লহর

মেটেরিয়াল কম্পোনেন্ট, সেগুলির সাথে ইন্টার‍্যাক্ট করা হচ্ছে তা বোঝাতে রিপেল ব্যবহার করে। আপনি যদি হায়রার্কিতে MaterialTheme ব্যবহার করেন, তাহলে clickable এবং indication-এর মতো মডিফায়ারের মধ্যে Ripple-কে ডিফল্ট Indication হিসেবে ব্যবহার করা হয়।

বেশিরভাগ ক্ষেত্রে আপনি ডিফল্ট Ripple-এর উপর ভরসা করতে পারেন। সেগুলির চেহারা কনফিগার করতে চাইলে, আপনি RippleTheme ব্যবহার করে রঙ ও আলফার মতো প্রপার্টি পরিবর্তন করতে পারবেন।

আপনি RippleTheme-এর মেয়াদ বাড়াতে এবং defaultRippleColor ও defaultRippleAlpha ইউটিলিটি ফাংশন ব্যবহার করতে পারবেন। তারপরে, আপনি LocalRippleTheme ব্যবহার করে আপনার হায়ারার্কিতে কাস্টম রিপল থিম প্রদান করতে পারবেন:

@Composable
fun MyApp() {
    MaterialTheme {
        CompositionLocalProvider(
            LocalRippleTheme provides SecondaryRippleTheme
        ) {
            // App content
        }
    }
}

@Immutable
private object SecondaryRippleTheme : RippleTheme {
    @Composable
    override fun defaultColor() = RippleTheme.defaultRippleColor(
        contentColor = MaterialTheme.colors.secondary,
        lightTheme = MaterialTheme.colors.isLight
    )

    @Composable
    override fun rippleAlpha() = RippleTheme.defaultRippleAlpha(
        contentColor = MaterialTheme.colors.secondary,
        lightTheme = MaterialTheme.colors.isLight
    )
}

অ্যানিমেটেড GIF-এ ট্যাপ করলে বোতামে আলাদা আলাদা রিপেল এফেক্ট দেখা যায়
ছবি ১৪. RippleConfiguration
ব্যবহার করে বিভিন্ন রিপেল ভ্যালু সহ বোতাম।

আরও জানুন

Compose-এ মেটেরিয়াল থিমিং সম্পর্কে আরও জানতে, নিম্নলিখিত অতিরিক্ত রিসোর্স দেখুন।

কোডল্যাবস

ভিডিও