برنامه نویسی

دکمه Draggable: کاوش در عناصر UI تعاملی با آهنگسازی Jetpack

ایجاد عناصر UI تعاملی روشی خارق العاده برای تقویت تعامل کاربر در برنامه های تلفن همراه است. یکی از این عناصر یک دکمه قابل کشیدن است – یک مؤلفه ساده و در عین حال قدرتمند که می تواند احساس بازیگوش و پویا را به برنامه شما برساند.

در این پست وبلاگ ، ما چگونگی ایجاد دکمه های قابل کشیدن را با استفاده از JetPack Compose ، یک ابزار مدرن برای ساخت UIS بومی بومی بررسی خواهیم کرد. ما دو اثر را پوشش خواهیم داد: یک دکمه قابل کشیدن اساسی و یک نسخه پیشرفته که هنگام انتشار به موقعیت اصلی خود باز می گردد.

دکمه قابل کشیدن اساسی

پیش نمایش اثر

دکمه قابل کشیدن اساسی

رمز کامل

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.material3.Button
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.IntOffset
import com.kevintest.myapplication.ui.theme.MyApplicationTheme
import kotlin.math.roundToInt

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            MyApplicationTheme {
                Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
                    DraggableButtonScreen(
                        modifier = Modifier.padding(innerPadding)
                    )
                }
            }
        }
    }
}

@Composable
fun DraggableButtonScreen(modifier: Modifier) {
    Box(
        contentAlignment = Alignment.Center,
        modifier = modifier
            .fillMaxSize()
            .statusBarsPadding()
            .navigationBarsPadding()
    ) {
        DraggableButton()
    }
}

@Composable
private fun DraggableButton() {
    var offset by remember { mutableStateOf(IntOffset.Zero) }
    val context = LocalContext.current
    Button(
        onClick = {},
        modifier = Modifier
            .offset { offset }
            .pointerInput(Unit) {
                detectDragGestures(
                    onDrag = { change, dragAmount ->
                        val maxOffsetX = (context.resources.displayMetrics.widthPixels - size.width) / 2
                        val maxOffsetY = (context.resources.displayMetrics.heightPixels - size.height) / 2
                        offset = IntOffset(
                            (offset.x + dragAmount.x.roundToInt()).coerceIn(-maxOffsetX, maxOffsetX),
                            (offset.y + dragAmount.y.roundToInt()).coerceIn(-maxOffsetY, maxOffsetY)
                        )
                        change.consume()
                    }
                )
            }
    ) {
        Text("Drag me")
    }
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

تجزیه کد

دکمه اصلی DragGable از روش Jetpack Compose Compose برای انجام عملیات کشیدن استفاده می کند. در اینجا یک توضیح گام به گام در مورد کد آورده شده است:

  1. اولیه سازی حالت: ما استفاده می کنیم remember { mutableStateOf(IntOffset.Zero) } برای اولیه کردن جبران دکمه. با کشیدن دکمه ، این حالت به روز می شود.
  2. تشخیص ژست کشیدن: detectDragGestures از روش برای ردیابی رویدادهای کشیدن استفاده می شود. در داخل این روش:
    • ONDRAG: این پاسخ به تماس ، جبران دکمه را بر اساس مقدار کشیدن به روز می کند. ما استفاده می کنیم coerceIn برای اطمینان از ماندن دکمه در مرزهای صفحه.
    • Change.Consume (): این تماس مانع از انتشار بیشتر رویداد درگ ، اطمینان از تعامل صاف می شود.
  3. مرزهای صفحه: برای جلوگیری از کشیدن دکمه به بیرون از صفحه ، ما بر اساس اندازه صفحه نمایش و ابعاد دکمه MaxoffsetX و MaxoffSety را محاسبه می کنیم.

دکمه قابل کشیدن با اثر ضربه محکم و ناگهانی

پیش نمایش اثر

دکمه قابل کشیدن با اثر ضربه محکم و ناگهانی

رمز کامل

@Composable
private fun DraggableButton() {
    var offset by remember { mutableStateOf(IntOffset.Zero) }
    var isDragging by remember { mutableStateOf(false) }
    val animatedOffset by animateIntOffsetAsState(
        targetValue = if (isDragging) offset else IntOffset.Zero,
        animationSpec = tween(durationMillis = 300),
        label = "offsetAnimation"
    )
    val context = LocalContext.current
    Button(
        onClick = {},
        modifier = Modifier
            .offset { if (isDragging) offset else animatedOffset }
            .pointerInput(Unit) {
                detectDragGestures(
                    onDragStart = { isDragging = true },
                    onDragEnd = {
                        isDragging = false
                        offset = IntOffset.Zero
                    },
                    onDrag = { change, dragAmount ->
                        val maxOffsetX = (context.resources.displayMetrics.widthPixels - size.width) / 2
                        val maxOffsetY = (context.resources.displayMetrics.heightPixels - size.height) / 2
                        offset = IntOffset(
                            (offset.x + dragAmount.x.roundToInt()).coerceIn(-maxOffsetX, maxOffsetX),
                            (offset.y + dragAmount.y.roundToInt()).coerceIn(-maxOffsetY, maxOffsetY)
                        )
                        change.consume()
                    }
                )
            }
    ) {
        Text("Drag me")
    }
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

تجزیه کد

اثر ضربه محکم و ناگهانی یک پیچ و تاب سرگرم کننده را به دکمه DragGable اضافه می کند. هنگامی که دکمه آزاد شد ، به راحتی به موقعیت اصلی خود متحرک می شود. این با استفاده از JetPack Compose حاصل می شود animateIntOffsetAsState روش

  1. اولیه سازی حالت: ما یک متغیر حالت اضافی را معرفی می کنیم isDragging برای ردیابی اینکه آیا دکمه کشیده شده است.
  2. منطق انیمیشن: animateIntOffsetAsState روش جبران دکمه را متحرک می کند. کی isDragging است ، false، دکمه انیمیشن به IntOffset.Zeroبشر
  3. به روزرسانی های ژست را بکشید: onDragStart مجموعه های برگشتی isDragging به true، در حالی که onDragEnd تنظیم مجدد آن به false و دکمه را به موقعیت اصلی خود بازگرداند.

این همه ، متشکرم (= ، =)

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا