এই আর্টিকেলে, আমরা শিখব কিভাবে Jetpack Compose-এ একটি অ্যাপ্লিকেশন স্টাইল এবং থিম করতে হয়।
Compose হল অ্যান্ড্রয়েডের জন্য একটি নতুন UI ফ্রেমওয়ার্ক (যদিও ডেস্কটপ এবং ওয়েব সাপোর্ট ডেভেলপ করা হচ্ছে), যা পুরনো XML-ভিত্তিক ভিউ সিস্টেমকে রিপ্লেস করে।
লেখার সময় এটি এখনও বেটা রিলিজে, আমি এই লাইব্রেরির এই নির্দিষ্ট অংশের স্টেবল রিলিজে ড্রাস্টিক্যালি পরিবর্তন হওয়ার আশা করি না।
বিষয়গুলো شامل:
- XML পদ্ধতির সংক্ষিপ্ত রিক্যাপ
- XML-ভিত্তিক রং, থিম, এবং টাইপোগ্রাফি (ফন্ট) সিস্টেম থেকে মাইগ্রেট করা
- কয়েক লাইন কোডে আপনার অ্যাপের জন্য লাইট এবং ডার্ক থিম সেট আপ করা
- আপনার নতুন কোটলিন-ভিত্তিক স্টাইল ইনফরমেশন কমপোজেবলসে কিভাবে ব্যবহার করবেন
- Text Composables নির্দিষ্টভাবে কিভাবে স্টাইল করবেন
আগে যাওয়ার আগে, কমপোজেবল কী সেটা বুঝতে গুরুত্বপূর্ণ। আমি এখানে সেই কনসেপ্ট ব্যাখ্যা করব না, কারণ আমি ইতিমধ্যে এই আর্টিকেলে করেেছি।
XML রিসোর্স ব্যবহার করে অ্যান্ড্রয়েড অ্যাপ স্টাইল করার পুরনো পদ্ধতি
সাধারণত, আমি আপনাদের সাথে এই টপিকগুলোর মোটিভেশন এবং কিছু ইতিহাস শেয়ার করতে পছন্দ করি। যদি আপনিーケयर না করেন, তবে প্র্যাকটিক্যাল জিনিসে যেতে পরবর্তী সেকশনে স্কিপ করতে পারেন।
অ্যান্ড্রয়েড রিসোর্স
অ্যান্ড্রয়েড অ্যাপ রিসোর্স সিস্টেম হল একটি ऐसी জিনিস যার জন্য অ্যান্ড্রয়েড টিমের হাই ফাইভ তৈরি, কমপক্ষে আমার মতামতে। কিন্তু প্রতিটি ডিজাইন ডিসিশনের মত, একটি ফিচার একটি পরিস্থিতিতে অন্য পরিস্থিতিতে ফ্লয়ে রূপ নেয়।
স্পেসিফিক্যালি, প্ল্যাটফর্ম এবং অ্যাপ্লিকেশন ডেভেলপারদের জন্য সবচেয়ে বড় চ্যালেঞ্জের একটি হলো যা আমি লোকালাইজড রিসোর্স বলব। আমি এরेफার করছি অ্যাপ তৈরি করার চ্যালেঞ্জ যেগুলো:
- বিভিন্ন ভাষা এবং অ্যালফাবেটে টেক্সট এবং গ্রাফিক্স ডিসপ্লে করে
- বিভিন্ন ফর্ম ফ্যাক্টর (ডাইমেনশন, ডেনসিটি, ইত্যাদি) অনুযায়ী প্রপোরশনেট দেখাচ্ছে।
এটা শুধু দুটি সাধারণ উদাহরণ – আরও অনেক আছে। রিসোর্স সিস্টেম আমাদের একটি জায়গা দেয় যেখানে অ্যাপ ডেভেলপাররা লোকালাইজড রিসোর্স দিতে পারেন যা প্ল্যাটফর্ম কম্পাইল টাইমে সিলেক্ট করতে পারে। এটি আমাদের নিজে সেই বয়লারপ্লেট কোড লিখতে হয় না।
ফিচার নাকি ফ্লয়?
যদিও আমি লোকালাইজড স্ট্রিং রিসোর্সের জন্য বয়লারপ্লেট কোড ম্যানেজ করতে কখনো চাইব না, তবুও এর মানে আমি XML-এ লিখতে পছন্দ করি না।
আসলে, খুব কম জিনিস আছে যা আমি XML-এ করার চেয়ে কোটলিন বা সুইফটের মত আধুনিক, ইডিওম্যাটিক, এবং এলিগ্যান্ট ল্যাঙ্গুয়েজে করা পছন্দ করব। পারসন্যাল প্রেফারেন্স আলাদা, এখানে একটি আরও টেকনিক্যাল কারণ আছে কেন XML রিসোর্স সবসময় আইডিয়াল নয়।
দয়া করে নোট করুন যে এটি প্ল্যাটফর্ম ডেভেলপার/এঞ্জিনিয়ারদের সমালোচনা করার উদ্দেশ্যে নয়। এটি কেবল ডিজাইন ডিসিশনগুলো কীভাবে বেনিফিট এবং কস্টের সাথে আসে সেটা নirik করাই।
আমাদের XML-ভিত্তিক রিসোর্সগুলো আমাদের JVM-ভিত্তিক অ্যাপ্লিকেশন কোডের সাথে ইন্টিগ্রেট করতে, আমাদের অবশ্যই ট্রান্সলেশন (কম্পাইলেশন) এর লেয়ার এবং প্ল্যাটফর্ম ব্রিজ (API) থাকতে হবে। এটি প্ল্যাটফর্ম এবং অ্যাপ্লিকেশন ডেভেলপারদের উভয়ের জন্য সমস্যা সৃষ্টি করতে পারে।
দুটি সাধারণ সমস্যা যা আমি ফেস করেছি:
- আমি একটি রিসোর্স এক্সেস করতে চাই যেখানে আমি প্ল্যাটফর্ম API-র সাথে টাইট কাপলিং চাই না যা রিসোর্সটি প্রদান করে
- একটি ভিউর লুক পরিবর্তন করতে (অর্থাৎ রিসোর্স স্টাইল এবং থিমের মধ্যে ডিফাইন করা কিছু ওভাররাইড করতে) কতটুকু বিরক্তিকর বয়লারপ্লেট কোড লিখতে হয়
সকলenges উভয়ের জন্য রুট প্রব্লেম হলো ভিউ সিস্টেম এবং অ্যান্ড্রয়েড রিসোর্স সিস্টেমের সাথে টাইট কাপলিং (যেগুলো নিজেদেরও টাইটলি কাপল্ড)।
প্ল্যাটফর্ম ডেভেলপারদের জন্য, এর মানে তারা বড় এবং পুরনো কোডবেসের উপরে বিল্ড করতে হয় বা সেগুলোর ওয়ার্কঅরাউন্ড খুঁজতে হয়। তদুপরি তারা নতুন ফিচারগুলো পুরনো অ্যান্ড্রয়েড ওএস ভার্সনেও কাজ করাতে চান, এবং সেটা একটি কৃতজ্ঞতা বিহীন কাজ হয়ে যায়।
আমরা অ্যাপ্লিকেশন ডেভেলপারদের ফলাফল হলো অধিকাংশ সময় বয়লারপ্লেট কোড, কিছু হ্যাকি ওয়ার্কঅরাউন্ড এমন জিনিসের জন্য যা ইন্টুইটিভলি লাগে যেন এক লাইনের কোড হওয়া উচিত। দূর দিয়ে Главный API এই রিসোর্স পাওয়ার জন্য Context, যা একটি ক্লাস যা আপনি মেমরিতে লিক করতে চান না।
এন্টার Jetpack Compose.
Jetpack Compose-এ থিম, রং, এবং ফন্ট সেট আপ করা
পুরনো সিস্টেমের রিভিউ শেষ করলে, আসুন একটি অনেক সুন্দর এবং সহজ পদ্ধতিতে অ্যান্ড্রয়েড অ্যাপ্লিকেশন স্টাইল এবং থিম করা এক্সপ্লোর করি। আমি বলেছিলাম এটি প্র্যাকটিক্যাল রাখব, কিন্তু এক পয়েন্ট অনুমতি দিন।
যেহেতু আমরা এই কাজটি কোটলিনে করব, এর মানে একটি খুব গুরুত্বপূর্ণ জিনিস: আমরা এবং প্ল্যাটফর্ম ডেভেলপাররা XML এবং JVM-এর মাঝপথে ট্রান্সলেশন (কম্পাইলেশন) এবং API ব্রিজ (অ্যান্ড্রয়েডের R ক্লাস এবং Context) থেকে অনেক কম বাধ্যতামূলক।
সহজ ভাষায়, এর মানে অনেক কম বয়লারপ্লেট কোড, এবং রানটাইমে অনেক বেশি কন্ট্রোল।
এই আর্টিকেলের প্র্যাকটিক্যাল অংশের জন্য, আমার সাজেশন হলো আমি যে ক্রমে ব্যাখ্যা করছি সেটি ফলো করুন। আমি এটি স্ট্রাকচার করেছি সেই ক্রমে যেটি আমি একটি নতুন অ্যাপে এই কোড লিখতে ফলো করি।
Colors.xml রিসোর্স কোটলিন কমপোজ দিয়ে রিপ্লেস করা
আপনি যদি ইতিমধ্যে আপনার অ্যাপ্লিকেশনের জন্য একটি কালার স্কিম ডিসাইড করে না থাকেন, তবে আমি অফিশিয়াল ম্যাটেরিয়াল ডিজাইন ওয়েবসাইটের বিভিন্ন রিসোর্স ব্যবহার করার পরামর্শ দিচ্ছি। ট্রাই করুন:
- কালার প্যালেটস
- কালার টুল
আপনি যদি লাইট এবং ডার্ক অ্যাপ থিম সাপোর্ট করতে চান (शीঘ্রই ব্যাখ্যা করা হয়েছে), তবে এমন একটি কালার স্কিম বেছে নিন যা হোয়াইট টেক্সট এবং ব্ল্যাক টেক্সট দুটোই সাপোর্ট করে।
Color.kt (নেম মেটার করে না) নামে একটি ফাইল তৈরি করুন এবং ইমিউটেবল val দিয়ে পূরণ করুন:
import androidx.compose.ui.graphics.Color val primaryGreen = Color(0XFF00bc00) val primaryCharcoal = Color(0xFF2b2b2b) val accentAmber = Color(0xFFffe400) val textColorLight = Color(0xDCFFFFFF) val textColorDark = Color(0xFFf3f3f3) val gridLineColorLight = Color.Black //...
আপনি অথবা প্রিডিফাইনড ভ্যালু যেমন Color.Black ব্যবহার করতে পারেন অথবা নিজস্ব ARGB Hex ভ্যালু দিতে পারেন।
ARGB Hex হলো কেবল জারগন যা বর্ণনা করে "0XFF00bc00" এর মানে কী, সেটা অনুবাদ করি:
- প্রথম দুটি ক্যারেক্টার
0xকম্পাইলারকে বলে যে এটি একটি হেক্সাডেসিমাল নাম্বার - দ্বিতীয় দুটি ক্যারেক্টার, "
FF" বা "DC", ট্রান্সপেরেন্সি/অপাসিটি/Aলফা কে হেক্সে রিপ্রেজেন্ট করে - বাকি ছয় ক্যারেক্টার পেয়ার Red, Green, এবং Blue রিপ্রেজেন্ট করে
ফন্ট যোগ করা এবং fontFamily অ্যাট্রিবিউট রিপ্লেস করা
টাইপোগ্রাফি (ফন্ট)ও ম্যানেজ করা খুব সহজ। এই ধরনের জিনিসে কোটলিনের ডিফল্ট আর্গুমেন্ট খুব কাজে লাগে।
Type.kt (নেম এখনও মেটার করে না) নামে একটি ফাইল তৈরি করুন এবং Typography ক্লাস তৈরি করুন...:
val typography = Typography( body1 = TextStyle( fontFamily = FontFamily.Default, fontWeight = FontWeight.Normal, fontSize = 16.sp ), button = TextStyle( fontFamily = FontFamily.Default, fontWeight = FontWeight.Bold, fontSize = 32.sp ), caption = TextStyle( fontFamily = FontFamily.Default, fontWeight = FontWeight.Normal, fontSize = 12.sp ) ) //...
...এবং কিছু TextStyle ক্লাস:
//... val mainTitle = TextStyle( fontFamily = FontFamily.Default, fontWeight = FontWeight.Light, fontSize = 48.sp, textAlign = TextAlign.Center ) fun dropdownText(color: Color) = TextStyle( fontFamily = FontFamily.Default, fontWeight = FontWeight.Normal, fontSize = 32.sp, textAlign = TextAlign.Center, color = color ) //...
আপনি পাবলিক ফাংশন বা ভ্যালু দিবেন (আমি এখানে var ব্যবহার না করার পরামর্শ দিচ্ছি) সেটা আপনার ইনডিভিজুয়াল প্রেফারেন্স এবং বর্তমান রিকোয়ারমেন্টের ওপর ডিপেন্ড করে।
Jetpack Compose-এ একটি অ্যাপ থিম তৈরি করা
আপনার কমপোজেবলসে থিম ব্যবহার করার আগে কনফিগার করার শেষ জিনিস হলো একটি MaterialTheme @Composable। আমার যেটি, এবং আমার লাইট ও ডার্ক কালার প্যালেটস একটি ফাইলে আছে GraphSudokuTheme নামে:
import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.material.MaterialTheme import androidx.compose.material.darkColors import androidx.compose.material.lightColors import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.Color private val LightColorPalette = lightColors( primary = primaryGreen, secondary = textColorLight, surface = lightGrey, primaryVariant = gridLineColorLight, onPrimary = accentAmber, onSurface = accentAmber ) private val DarkColorPalette = darkColors( //মেইন ব্যাকগ্রাউন্ড রং primary = primaryCharcoal, //টেক্সট রংয় জন্য ব্যবহৃত হয় secondary = textColorDark, //সুডোকু বোর্ডের ব্যাকগ্রাউন্ড surface = lightGreyAlpha, //সুডোকু বোর্ডের গ্রিড লাইন primaryVariant = gridLineColorLight, onPrimary = accentAmber, onSurface = accentAmber ) @Composable fun GraphSudokuTheme( darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit ) { MaterialTheme( colors = if (darkTheme) DarkColorPalette else LightColorPalette, typography = typography, shapes = shapes, content = content ) }
যেহেতু আপনাকে ইতিমধ্যে কমপোজেবল কী সেটা জানা উচিত (আমি আপনাকে ফেয়ার вор্নিং দিয়েছিলাম), এখানে একমাত্র নতুন জিনিস হলো darkTheme: Boolean = isSystemInDarkTheme()।
সিম্পলিফাইড এক্সপ্লানেশন দিলে, isSystemInDarkTheme() হলো যেকোনো কম্প্যাটিবল অ্যান্ড্রয়েড ডিভাইসকে ইউজারের লাইট বা ডার্ক থিম প্রেফারেন্স জানার একটি কল।
এটি একটি বুলিয়ান ভ্যালু রিটার্ন করে যা আমরা একটি টার্নারি (কন্ডিশনাল) অ্যাসাইনমেন্ট এক্সপ্রেশন যেমন colors = if (darkTheme) DarkColorPalette else LightColorPalette এ ব্যবহার করতে পারি।
এটাই সেটা। রং, ফন্ট, এবং দুটি থিম কয়েক মিনিটে ডিফাইন হয়ে গেলো।
Compose-এ থিম ব্যবহার করা
এখন এই থিমটি আপনার অ্যাপে ব্যবহার করার সময়। এই অ্যাপে, যেটিতে শুধু দুটি প্রাইমারি স্ক্রিন আছে, আমি শুধু একটি Activity ব্যবহার করেছি আমার কমপোজেবলসের কন্টেইনার হিসেবে:
class NewGameActivity : AppCompatActivity(), NewGameContainer { //... override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) //... setContent { GraphSudokuTheme { NewGameScreen( onEventHandler = logic::onEvent, viewModel ) } } //... }
আপনি যেখানে setContent {} কল করেন, বেগুনার জন্য আমার সাজেশন হলো সেটার ভিতরে অবিলম্বে আপনার Theme কমপোজেবল রাখুন। এটি করলে স্টাইল ইনফরমেশন প্রতিটি নেস্টেড কমপোজেবলে ক্যাসকেড/ইনহেরিট হবে।
আপনি শেষ! Почти।
স্টাইল এবং থিম ওভাররাইড করা
যদি আপনি পারেন, আপনার লাইট এবং ডার্ক প্যালেটে যেকোনো রং আপনি চান সেগুলো অন্তর্ভুক্ত করার চেষ্টা করুন। এইভাবে, যখন আপনি MaterialTheme.colors.<Color> কল করবেন, সিস্টেম কন্ডিশনাল লজিক হ্যান্ডেল করে উপযুক্ত প্যালেট পিক করবে:
@Composable fun NewGameContent( onEventHandler: (NewGameEvent) -> Unit, viewModel: NewGameViewModel ) { Surface( Modifier .wrapContentHeight() .fillMaxWidth() ) { ConstraintLayout(Modifier.background(MaterialTheme.colors.primary)) { //... } //... } }
য totsometimes নিজস্ব কন্ডিশনাল লজিক লিখা বেশি উপযুক্ত হয়... অথবা আমি শুধু আলসি হয়ে গেলাম। خوشকিসমتی से Compose অনেক এমন কনফিগারেশন প্রপার্টি হিসেবে উপলব্ধ করে:
@Composable fun DoneIcon(onEventHandler: (NewGameEvent) -> Unit) { Icon( imageVector = Icons.Filled.Done, tint = if (MaterialTheme.colors.isLight) textColorLight else textColorDark, contentDescription = null, modifier = Modifier .clickable( //... ) ) }
MaterialTheme.Colors.isLight একটি বুলিয়ান রিটার্ন করে যা নির্দেশ করে তারা কোন মোডে আছে, তারপর আমরা সেখান থেকে আরেকটি টার্নারি অ্যাসাইনমেন্ট ব্যবহার করতে পারি।
একটি Text Composable স্টাইল করা
শুধু style আর্গুমেন্টকে আপনার টেক্সট স্টাইলগুলোর একটির সমান সেট করুন (চায়ে সেটি MaterialTheme- থেকে আসে অথবা Type.kt-এ থাকা স্টাইলগুলোর মধ্যে থেকে):
Text( text = stat.toTime(), style = statsLabel.copy( color = if (isZero) Color.White else MaterialTheme.colors.onPrimary, fontWeight = FontWeight.Normal ), modifier = Modifier .wrapContentSize() .padding(end = 2.dp, bottom = 4.dp), textAlign = TextAlign.End )
TextStyle-এর নিজস্ব copy ফাংশন রেডি থাকে কোনো কিছু ওভাররাইড করতে চাইলে।
এটাই সেটা! এখন আপনি জানেন Jetpack Compose ব্যবহার করে একটি অ্যাপ্লিকেশন কিভাবে স্টাইল এবং থিম করতে হয়। পড়ার জন্য ধন্যবাদ :)
সোশ্যাল
আপনি আমাকে ইনস্টাগ্রামে এখানে এবং টুইটারে এখানে পাবেন।
আমার কিছু টিউটোরিয়াল ও কোর্স
https://youtube.com/wiseass https://www.freecodecamp.org/news/author/ryan-michael-kay/ https://skl.sh/35IdKsj (Android Studio-তে অ্যান্ড্রয়েডের পরিচিতি)