Jetpack Compose, মেটেরিয়াল ডিজাইন ইমপ্লিমেন্ট করার সুবিধা দেয়, এটি হল ডিজিটাল ইন্টারফেস তৈরি করার জন্য একটি বিস্তারিত ডিজাইন সিস্টেম। মেটেরিয়াল ডিজাইন কম্পোনেন্ট (বোতাম, কার্ড, সুইচ ইত্যাদি) মেটেরিয়াল থিমিংয়ের উপর ভিত্তি করে তৈরি করা হয়, যা আপনার প্রোডাক্টের ব্র্যান্ডকে আরও ভালোভাবে ফুটিয়ে তুলতে মেটেরিয়াল ডিজাইন কাস্টমাইজ করার একটি পদ্ধতিগত উপায়। একটি Material থিমের মধ্যে রঙ, টাইপোগ্রাফি এবং আকৃতি অ্যাট্রিবিউট থাকে। এইসব অ্যাট্রিবিউট কাস্টমাইজ করলে, আপনার পরিবর্তনগুলি অ্যাপ তৈরি করার জন্য ব্যবহার করা কম্পোনেন্টগুলিতে অটোমেটিক প্রতিফলিত হয়।
Jetpack Compose MaterialTheme
কম্পোজ করার উপযুক্ত আইটেমের মাধ্যমে এইসব ধারণা প্রয়োগ করে:
MaterialTheme( colors = // ... typography = // ... shapes = // ... ) { // app content }
আপনার অ্যাপ্লিকেশনকে থিম করার জন্য MaterialTheme-এ পাস করা প্যারামিটার কনফিগার করুন।
রঙ
Color ক্লাসের মাধ্যমে Compose-এ রঙ মডেল করা হয়, এটি একটি ডেটা-হোল্ডিং ক্লাস।
val Red = Color(0xffff0000) val Blue = Color(red = 0f, green = 0f, blue = 1f)
আপনি এগুলিকে যেভাবে খুশি সেভাবে সাজাতে পারলেও (টপ-লেভেল কনস্ট্যান্ট হিসেবে, কোনও সিঙ্গেলটনের মধ্যে অথবা ইনলাইন হিসেবে ডিফাইন করা), আমরা দৃঢ়ভাবে সাজেস্ট করি যে আপনার থিমে কালার নির্দিষ্ট করুন এবং সেখান থেকে কালার রিট্রিভ করুন। এই পদ্ধতির মাধ্যমে ডার্ক থিম ও নেস্টেড থিম ব্যবহার করা যায়।
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-এর মতো মেটেরিয়াল কম্পোজেবল ডিফল্ট হিসেবে
এই আচরণ প্রয়োগ করে।
কাস্টম সিনারিওর জন্য, 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 একটি শেপ সিস্টেম নির্ধারণ করে, যা আপনাকে বড়, মাঝারি ও ছোট কম্পোনেন্টের জন্য শেপ নির্ধারণ করতে দেয়।
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, /*...*/ ) { /*...*/ }
ডিফল্ট স্টাইল
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 ) }
RippleConfigurationআরও জানুন
Compose-এ মেটেরিয়াল থিমিং সম্পর্কে আরও জানতে, নিম্নলিখিত অতিরিক্ত রিসোর্স দেখুন।
কোডল্যাবস
ভিডিও
আপনার জন্য সাজেস্ট করা হয়েছে
- মনে রাখবেন: জাভাস্ক্রিপ্ট বন্ধ থাকলে লিঙ্ক টেক্সট দেখানো হয়
- Compose-এ কাস্টম ডিজাইন সিস্টেম
- Compose-এ Material 2 থেকে Material 3-তে মাইগ্রেট করা
- Compose-এ অ্যাক্সেসিবিলিটি