ایجاد Kotlin DSL برای اجزای آهنگسازی Jetpack

آشنایی با Kotlin DSL
Kotlin DSL (زبان خاص دامنه) یک ویژگی قدرتمند Kotlin است که به شما امکان می دهد API های اعلانی و بصری را ایجاد کنید. این ماده به طور گسترده ای در اکوسیستم کوتلین استفاده می شود که Gradle Kotlin DSL یک نمونه کلاسیک است. با استفاده از Kotlin DSL ، می توانید تنظیمات پیچیده را به بلوک های ساده و سازمان یافته تبدیل کنید.
اما اگر بتوانیم همان مفهوم را برای آهنگسازی Jetpack بیاوریم ، چه می شود؟ تصور کنید که اجزای UI خود را با استفاده از یک رویکرد اعلانی و انعطاف پذیر تعریف کنید. در این مقاله به بررسی نحوه ساخت DSL سفارشی برای یک مؤلفه آهنگسازی ، مانند CustomButton می پردازیم.CustomButton
این مقاله در ابتدا در Medium منتشر شده است: ایجاد Kotlin DSL برای اجزای آهنگسازی Jetpack
چرا DSL برای اجزای آهنگسازی ایجاد می کنید؟
رویکرد اعلانی آهنگسازی JetPack در حال حاضر تعاریف UI را بصری تر می کند. با این حال ، هنگام برخورد با مؤلفه های قابل استفاده مجدد و بسیار قابل تنظیم ، DSL مزایای اضافی را ارائه می دهد:
- خوانایی روشن: تنظیمات به بلوک های منطقی سازماندهی می شوند و درک آنها را آسان تر می کنند.
- قابلیت استفاده مجدد: شما می توانید منطق تکراری را محاصره کرده و API های ساده را برای استفاده مجدد ایجاد کنید.
- قابلیت گسترش: افزودن تنظیمات جدید ساده و بصری است.
بیایید یک مثال عملی بسازیم تا بهتر این کار را درک کنیم.
ساختن DSL از ابتدا
تعریف کلاس پیکربندی
ابتدا یک کلاس ایجاد می کنیم تا پیکربندی های مؤلفه خود را نگه دارید:
class CustomButtonConfig {
var text: String = ""
var icon: ImageVector? = null
var onClick: (() -> Unit)? = null
var backgroundColor: Color = MaterialTheme.colors.primary
var textColor: Color = Color.White
val shapes = mutableListOf<ComposedShape>()
}
این کلاس خواصی را که کاربران می توانند در این مؤلفه پیکربندی کنند ، از جمله اشکال تشکیل شده تعریف می کند.
ایجاد @DslMarker
حاشیه نویسی
برای جداسازی دامنه DSL و جلوگیری از درگیری بین بلوک های مختلف ، یک حاشیه نویسی سفارشی ایجاد می کنیم:
@DslMarker
annotation class CustomButtonDSL
ما کلاسهای مربوطه را به روز می کنیم تا این حاشیه نویسی را اعمال کنیم:
@CustomButtonDSL
class ComposedShape {
val shapes = mutableListOf<ShapeConfig>()
}
@CustomButtonDSL
sealed class ShapeConfig {
data class TriangleConfig(var base: Float, var height: Float, var color: Color) : ShapeConfig()
data class RhombusConfig(var sideLength: Float, var angle: Float, var color: Color) : ShapeConfig()
}
ایجاد توابع DSL برای شکل در متن دکمه
ما توابع را برای پیکربندی اشکال در دکمه DSL اضافه می کنیم:
fun CustomButtonConfig.composedShape(block: ComposedShape.() -> Unit) {
shapes.add(ComposedShape().apply(block))
}
fun ComposedShape.triangle(base: Float, height: Float, color: Color) {
shapes.add(ShapeConfig.TriangleConfig(base, height, color))
}
fun ComposedShape.rhombus(sideLength: Float, angle: Float, color: Color) {
shapes.add(ShapeConfig.RhombusConfig(sideLength, angle, color))
}
به روزرسانی CustomButton
جزء
ما اصلاح می کنیم customButton
عملکرد برای ارائه اشکال ترکیب شده:
@Composable
fun customButton(configure: CustomButtonConfig.() -> Unit) {
val config = CustomButtonConfig().apply(configure)
Button(
onClick = config.onClick ?: {},
colors = ButtonDefaults.buttonColors(backgroundColor = config.backgroundColor),
modifier = Modifier.padding(8.dp)
) {
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally
) {
// Render Shapes
config.shapes.forEach { composedShape ->
composedShape.shapes.forEach { shape ->
when (shape) {
is ShapeConfig.TriangleConfig -> {
Text(
text = "\u25B2", // Triangle representation
color = shape.color,
modifier = Modifier.size(shape.base.dp, shape.height.dp)
)
}
is ShapeConfig.RhombusConfig -> {
Text(
text = "\u25C6", // Rhombus representation
color = shape.color,
modifier = Modifier.size(shape.sideLength.dp)
)
}
}
}
}
// Render Text and Icon
Row(
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {
config.icon?.let {
Icon(imageVector = it, contentDescription = null, tint = config.textColor)
}
if (config.icon != null) Spacer(modifier = Modifier.width(8.dp))
Text(text = config.text, color = config.textColor)
}
}
}
}
نمونه های عملی
مثال 1: دکمه با مثلث و رومبوس
customButton {
text = "With Shapes"
textColor = Color.Black
backgroundColor = Color.LightGray
onClick = { println("Button with shapes clicked!") }
composedShape {
triangle(base = 50f, height = 30f, color = Color.Red)
rhombus(sideLength = 40f, angle = 45f, color = Color.Blue)
}
}
مثال 2: دکمه ساده
customButton {
text = "Click Here"
textColor = Color.Black
onClick = { println("Button clicked!") }
}
مثال 3: دکمه با نماد
customButton {
text = "Favorite"
icon = Icons.Default.Favorite
textColor = Color.Black
onClick = { println("Favorite clicked!") }
}
مثال 4: دکمه با سبک سفارشی
customButton {
text = "Send"
icon = Icons.Default.Send
onClick = { println("Send clicked!") }
backgroundColor = Color.Green
textColor = Color.White
}
مزایای Kotlin DSL
- خوانایی بهبود یافته: تنظیمات به بلوک های واضح و منطقی سازماندهی می شوند.
- دیگ بخار کاهش یافته: کد کمتر تکراری ، بیشتر روی آنچه مهم است تمرکز کنید.
- قابلیت گسترش: ویژگی های جدید را می توان بدون تغییر کد موجود به DSL اضافه کرد.
- بهره وری: API اعلانی باعث پیشرفت می شود و تجربه توسعه دهنده را افزایش می دهد.
نمونه
پایان
ایجاد Kotlin DSL برای اجزای سازنده به شما امکان می دهد تا از قدرت کوتلین برای ساده سازی و سازماندهی UI خود به روشی اعلامیه استفاده کنید. علاوه بر این که کد قابل خواندن تر است ، این روش قابلیت استفاده مجدد و مقیاس پذیری قطعات را ترویج می کند.
چرا آن را امتحان نکنید و DSL خود را ایجاد کنید؟ با کوتلین ، امکانات بی پایان است. بیایید کار کنیم!