تالیف و کتابخانه های دیگر

می توانید از کتابخانه های مورد علاقه خود در Compose استفاده کنید. این بخش نحوه ترکیب چند مورد از مفیدترین کتابخانه ها را شرح می دهد.

فعالیت

برای استفاده از Compose در یک اکتیویتی، باید از ComponentActivity استفاده کنید، یک زیر کلاس از Activity که LifecycleOwner و اجزای مناسب را برای Compose ارائه می‌کند. همچنین API های اضافی را ارائه می کند که کد شما را از روش های نادیده گرفته شده در کلاس فعالیت شما جدا می کند. Activity Compose این APIها را در معرض مواد composable قرار می‌دهد به طوری که دیگر نیازی به حذف روش‌های خارج از composable‌های شما یا بازیابی یک نمونه Activity صریح نیست. علاوه بر این، این APIها تضمین می‌کنند که فقط یک بار مقداردهی اولیه می‌شوند، از ترکیب مجدد جان سالم به در می‌برند و در صورت حذف شدن ترکیب‌پذیر از ترکیب، به درستی پاک می‌شوند.

نتیجه فعالیت

API rememberLauncherForActivityResult() به شما امکان می دهد از یک فعالیت در composable خود نتیجه بگیرید :

@Composable
fun GetContentExample() {
    var imageUri by remember { mutableStateOf<Uri?>(null) }
    val launcher = rememberLauncherForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? ->
        imageUri = uri
    }
    Column {
        Button(onClick = { launcher.launch("image/*") }) {
            Text(text = "Load Image")
        }
        Image(
            painter = rememberAsyncImagePainter(imageUri),
            contentDescription = "My Image"
        )
    }
}

این مثال یک قرارداد ساده GetContent() را نشان می دهد. با ضربه زدن روی دکمه درخواست اجرا می شود. لامبدای انتهایی برای rememberLauncherForActivityResult() پس از انتخاب تصویر توسط کاربر و بازگشت به فعالیت راه‌اندازی فراخوانی می‌شود. این تصویر انتخاب شده را با استفاده از تابع rememberImagePainter() Coil بارگیری می کند.

هر زیر کلاس ActivityResultContract را می توان به عنوان اولین آرگومان برای rememberLauncherForActivityResult() استفاده کرد. این بدان معنی است که شما می توانید از این تکنیک برای درخواست محتوا از چارچوب و سایر الگوهای رایج استفاده کنید. شما همچنین می توانید قراردادهای سفارشی خود را ایجاد کرده و با این تکنیک از آنها استفاده کنید.

درخواست مجوزهای زمان اجرا

از همان Activity Result API و rememberLauncherForActivityResult() توضیح داده شده در بالا می‌توان برای درخواست مجوزهای زمان اجرا با استفاده از قرارداد RequestPermission برای یک مجوز واحد یا قرارداد RequestMultiplePermissions برای چندین مجوز استفاده کرد.

کتابخانه Accompanist Permissions همچنین می‌تواند یک لایه بالای آن APIها برای ترسیم وضعیت اعطا شده فعلی برای مجوزها به حالتی که UI Compose شما می‌تواند استفاده کند، استفاده شود.

کنترل دکمه بازگشت سیستم

برای ارائه پیمایش برگشت سفارشی و نادیده گرفتن رفتار پیش‌فرض دکمه بازگشت سیستم از داخل composable خود، composable شما می‌تواند BackHandler برای رهگیری آن رویداد استفاده کند:

var backHandlingEnabled by remember { mutableStateOf(true) }
BackHandler(backHandlingEnabled) {
    // Handle back press
}

آرگومان اول کنترل می کند که آیا BackHandler در حال حاضر فعال است یا خیر. شما می توانید از این آرگومان برای غیرفعال کردن موقت کنترلر خود بر اساس وضعیت جزء خود استفاده کنید. اگر کاربر یک رویداد بازگشتی سیستم را راه‌اندازی کند و BackHandler در حال حاضر فعال باشد، لامبدای انتهایی فراخوانی می‌شود.

ViewModel

اگر از کتابخانه ViewModel کامپوننت‌های معماری استفاده می‌کنید، می‌توانید با فراخوانی تابع viewModel() ViewModel از هر composable دسترسی داشته باشید. وابستگی زیر را به فایل Gradle خود اضافه کنید:

شیار

dependencies {
    implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.8.5'
}

کاتلین

dependencies {
    implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.5")
}

سپس می توانید از تابع viewModel() در کد خود استفاده کنید.

class MyViewModel : ViewModel() { /*...*/ }

// import androidx.lifecycle.viewmodel.compose.viewModel
@Composable
fun MyScreen(
    viewModel: MyViewModel = viewModel()
) {
    // use viewModel here
}

viewModel() یک ViewModel موجود را برمی گرداند یا یک مدل جدید ایجاد می کند. به طور پیش‌فرض، ViewModel برگردانده شده در محدوده فعالیت، قطعه یا مقصد ناوبری محصور قرار می‌گیرد و تا زمانی که محدوده فعال است، حفظ می‌شود.

به عنوان مثال، اگر composable در یک اکتیویتی استفاده شود، viewModel() همان نمونه را برمی گرداند تا زمانی که اکتیویتی به پایان برسد یا فرآیند از بین برود.

class MyViewModel : ViewModel() { /*...*/ }
// import androidx.lifecycle.viewmodel.compose.viewModel
@Composable
fun MyScreen(
    // Returns the same instance as long as the activity is alive,
    // just as if you grabbed the instance from an Activity or Fragment
    viewModel: MyViewModel = viewModel()
) { /* ... */ }

@Composable
fun MyScreen2(
    viewModel: MyViewModel = viewModel() // Same instance as in MyScreen
) { /* ... */ }

دستورالعمل های استفاده

شما معمولاً به نمونه های ViewModel در composable های سطح صفحه دسترسی دارید، یعنی نزدیک به یک root composable که از یک فعالیت، قطعه یا مقصد یک نمودار ناوبری فراخوانی می شود. این به این دلیل است که ViewModel ها به طور پیش فرض به آن اشیاء سطح صفحه نمایش داده می شوند. اطلاعات بیشتر در مورد چرخه حیات ViewModel و دامنه را در اینجا بخوانید.

سعی کنید از انتقال نمونه های ViewModel به دیگر composable ها خودداری کنید، زیرا این کار می تواند آزمایش آن ها را دشوارتر کند و پیش نمایش ها را خراب کند. در عوض، فقط داده ها و توابع مورد نیاز آنها را به عنوان پارامتر ارسال کنید.

می‌توانید از نمونه‌های ViewModel برای مدیریت وضعیت برای ترکیب‌پذیرهای سطح زیر صفحه استفاده کنید، با این حال، از چرخه حیات و محدوده ViewModel آگاه باشید. اگر composable مستقل است، ممکن است بخواهید از Hilt برای تزریق ViewModel استفاده کنید تا مجبور نباشید وابستگی‌ها را از composable‌های والد منتقل کنید.

اگر ViewModel شما وابستگی دارد، viewModel() یک ViewModelProvider.Factory اختیاری را به عنوان پارامتر می گیرد.

برای اطلاعات بیشتر درباره ViewModel در Compose و نحوه استفاده از نمونه‌ها با کتابخانه Navigation Compose یا فعالیت‌ها و قطعات، به اسناد قابلیت همکاری مراجعه کنید.

جریان های داده

Compose همراه با برنامه های افزودنی برای محبوب ترین راه حل های مبتنی بر جریان اندروید ارائه می شود. هر یک از این پسوندها توسط یک مصنوع متفاوت ارائه می شود:

این مصنوعات به عنوان یک شنونده ثبت می شوند و ارزش ها را به عنوان یک State نشان می دهند. هر زمان که یک مقدار جدید منتشر می شود، Compose آن قسمت هایی از UI را که در آن state.value استفاده می شود، دوباره ترکیب می کند. به عنوان مثال، در این کد، ShowData هر بار که exampleLiveData یک مقدار جدید منتشر می کند، دوباره ترکیب می کند.

// import androidx.lifecycle.viewmodel.compose.viewModel
@Composable
fun MyScreen(
    viewModel: MyViewModel = viewModel()
) {
    val dataExample = viewModel.exampleLiveData.observeAsState()

    // Because the state is read here,
    // MyScreen recomposes whenever dataExample changes.
    dataExample.value?.let {
        ShowData(dataExample)
    }
}

عملیات ناهمزمان در Compose

Jetpack Compose به شما این امکان را می دهد که عملیات ناهمزمان را با استفاده از کوروتین ها از داخل اجزای سازنده خود اجرا کنید.

برای اطلاعات بیشتر، APIهای LaunchedEffect ، produceState و rememberCoroutineScope را در اسناد عوارض جانبی مشاهده کنید.

مؤلفه Navigation از برنامه های Jetpack Compose پشتیبانی می کند. برای اطلاعات بیشتر به پیمایش با نوشتن و انتقال Jetpack Navigation به Navigation Compose مراجعه کنید.

هیلت

Hilt راه حل پیشنهادی برای تزریق وابستگی در برنامه های اندروید است و با Compose یکپارچه کار می کند.

تابع viewModel() ذکر شده در بخش ViewModel به طور خودکار از ViewModel استفاده می کند که Hilt با حاشیه نویسی @HiltViewModel می سازد. ما اسنادی را با اطلاعاتی در مورد ادغام ViewModel Hilt ارائه کرده‌ایم.

@HiltViewModel
class MyViewModel @Inject constructor(
    private val savedStateHandle: SavedStateHandle,
    private val repository: ExampleRepository
) : ViewModel() { /* ... */ }

// import androidx.lifecycle.viewmodel.compose.viewModel
@Composable
fun MyScreen(
    viewModel: MyViewModel = viewModel()
) { /* ... */ }

هیلت و ناوبری

Hilt همچنین با کتابخانه Navigation Compose یکپارچه می شود. وابستگی های اضافی زیر را به فایل Gradle خود اضافه کنید:

شیار

dependencies {
    implementation 'androidx.hilt:hilt-navigation-compose:1.2.0'
}

کاتلین

dependencies {
    implementation("androidx.hilt:hilt-navigation-compose:1.2.0")
}

هنگام استفاده از Navigation Compose، همیشه از تابع composable hiltViewModel برای به دست آوردن یک نمونه از ViewModel @HiltViewModel خود استفاده کنید. این با قطعات یا فعالیت هایی که با @AndroidEntryPoint حاشیه نویسی شده اند کار می کند.

به عنوان مثال، اگر ExampleScreen یک مقصد در یک نمودار ناوبری است، hiltViewModel() فراخوانی کنید تا نمونه ای از ExampleViewModel به مقصد برسد، همانطور که در قطعه کد زیر نشان داده شده است:

// import androidx.hilt.navigation.compose.hiltViewModel

@Composable
fun MyApp() {
    val navController = rememberNavController()
    val startRoute = "example"
    NavHost(navController, startDestination = startRoute) {
        composable("example") { backStackEntry ->
            // Creates a ViewModel from the current BackStackEntry
            // Available in the androidx.hilt:hilt-navigation-compose artifact
            val viewModel = hiltViewModel<MyViewModel>()
            MyScreen(viewModel)
        }
        /* ... */
    }
}

اگر نیاز به بازیابی نمونه ViewModel با محدوده مسیرهای ناوبری یا نمودار ناوبری دارید، از تابع composable hiltViewModel استفاده کنید و backStackEntry مربوطه را به عنوان پارامتر ارسال کنید:

// import androidx.hilt.navigation.compose.hiltViewModel
// import androidx.navigation.compose.getBackStackEntry

@Composable
fun MyApp() {
    val navController = rememberNavController()
    val startRoute = "example"
    val innerStartRoute = "exampleWithRoute"
    NavHost(navController, startDestination = startRoute) {
        navigation(startDestination = innerStartRoute, route = "Parent") {
            // ...
            composable("exampleWithRoute") { backStackEntry ->
                val parentEntry = remember(backStackEntry) {
                    navController.getBackStackEntry("Parent")
                }
                val parentViewModel = hiltViewModel<ParentViewModel>(parentEntry)
                ExampleWithRouteScreen(parentViewModel)
            }
        }
    }
}

صفحه بندی

کتابخانه Paging بارگیری تدریجی داده ها را برای شما آسان می کند و در Compose پشتیبانی می شود. صفحه انتشار صفحه‌بندی حاوی اطلاعاتی درباره وابستگی اضافی paging-compose است که باید به پروژه و نسخه آن اضافه شود.

در اینجا یک نمونه از APIهای Compose کتابخانه Paging آورده شده است:

@Composable
fun MyScreen(flow: Flow<PagingData<String>>) {
    val lazyPagingItems = flow.collectAsLazyPagingItems()
    LazyColumn {
        items(
            lazyPagingItems.itemCount,
            key = lazyPagingItems.itemKey { it }
        ) { index ->
            val item = lazyPagingItems[index]
            Text("Item is $item")
        }
    }
}

برای اطلاعات بیشتر در مورد استفاده از صفحه‌بندی در نوشتن، فهرست‌ها و مستندات شبکه‌ها را بررسی کنید.

نقشه ها

می توانید از کتابخانه Maps Compose برای ارائه Google Maps در برنامه خود استفاده کنید. در اینجا یک مثال استفاده آمده است:

@Composable
fun MapsExample() {
    val singapore = LatLng(1.35, 103.87)
    val cameraPositionState = rememberCameraPositionState {
        position = CameraPosition.fromLatLngZoom(singapore, 10f)
    }
    GoogleMap(
        modifier = Modifier.fillMaxSize(),
        cameraPositionState = cameraPositionState
    ) {
        Marker(
            state = remember { MarkerState(position = singapore) },
            title = "Singapore",
            snippet = "Marker in Singapore"
        )
    }
}

{% کلمه به کلمه %} {% آخر کلمه %} {% کلمه به کلمه %} {% آخر کلمه %}