میتوانید از کتابخانههای دلخواهتان در Compose استفاده کنید. این بخش نحوه ادغام چند مورد از مفیدترین کتابخانهها را شرح میدهد.
فعالیت
برای استفاده از Compose در یک فعالیت، باید از
ComponentActivity،
یک زیرکلاس از Activity که LifecycleOwner و
مؤلفههای مناسب را برای Compose فراهم میکند، استفاده کنید. همچنین میاناهای برنامهسازی کاربردی دیگری ارائه میدهد که کد شما را از روشهای لغو در کلاس فعالیتتان جدا میکند.
Activity Compose
این میاناهای برنامهسازی کاربردی را برای composableها آشکار میکند بهطوریکه دیگر نیازی به روشهای لغو کردن خارج از
composableها یا بازیابی نمونه صریح Activity نیست.
علاوهبراین، این میاناهای برنامهسازی کاربردی تضمین میکنند که فقط یکبار مقداردهی اولیه شوند، از ترکیببندی مجدد جان سالم بهدر ببرند، و اگر ترکیبشدنی از ترکیببندی برداشته شد، بهدرستی پاکسازی شوند.
نتیجه فعالیت
میانای برنامهسازی کاربردی
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 نیز میتواند بهعنوان لایهای بالای آن میاناهای برنامهسازی کاربردی استفاده شود تا وضعیت اعطاشده فعلی برای اجازهها را به «وضعیتی» نگاشت کند که Compose UI شما بتواند از آن استفاده کند.
مدیریت دکمه برگشت سیستم
برای ارائه پیمایش به عقب سفارشی
و لغو رفتار پیشفرض دکمه برگشتن سیستم از داخل
ترکیبپذیرتان، ترکیبپذیرتان میتواند از
BackHandler
برای رهگیری آن رویداد استفاده کند:
var backHandlingEnabled by remember { mutableStateOf(true) } BackHandler(backHandlingEnabled) { // Handle back press }
آرگومان اول کنترل میکند که آیا
BackHandler
درحالحاضر فعال است یا نه؛ میتوانید از این آرگومان برای غیرفعال کردن موقت گرداننده خود
براساس وضعیت مؤلفهتان استفاده کنید. اگر کاربر رویداد برگشت سیستم را راهاندازی کند و
BackHandler
درحالحاضر فعال باشد،
لامبدای دنبالهدار فراخوانده میشود.
ViewModel
اگر از کتابخانه Architecture Components
ViewModel استفاده میکنید، میتوانید با فراخوانی تابع viewModel() از هر composable به ViewModel دسترسی پیدا کنید. وابستگی زیر را به فایل Gradle خود اضافه کنید:
شیک
dependencies { implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.11.0' }
کاتلین
dependencies { implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.11.0") }
سپس میتوانید از تابع 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 در ترکیبپذیرهای سطح صفحهنمایش دسترسی پیدا میکنید، یعنی نزدیک به ترکیبپذیر ریشهای که از فعالیت، قطعه، یا مقصد نمودار «پیمایش» فراخوانی میشود. دلیلش این است که ViewModels
بهطور پیشفرض به آن اشیاء سطح صفحه محدود شدهاند. در اینجا درباره چرخه حیات و دامنه
ViewModel
بیشتر بخوانید.
سعی کنید از انتقال نمونههای ViewModel به سایر composableها خودداری کنید، زیرا این کار میتواند آزمایش آن composableها را دشوارتر کند و ممکن است پیشنمایشها را خراب کند. بهجای آن، فقط دادهها و عملکردهایی را که نیاز دارند بهعنوان پارامتر ارسال کنید.
You can use ViewModel instances to
manage state for sub screen-level composables, however, be aware of the
ViewModel's
lifecycle and scope. اگر
composable مستقل است، میتوانید از Hilt برای
تزریق ViewModel استفاده کنید تا مجبور نباشید وابستگیها را از composableهای
والد ارسال کنید.
اگر ViewModel شما وابستگیهایی داشته باشد، viewModel() یک
ViewModelProvider.Factory
اختیاری را بهعنوان پارامتر میگیرد.
برای اطلاعات بیشتر درباره ViewModel در Compose و نحوه استفاده از نمونهها
با کتابخانه Navigation Compose، یا فعالیتها و قطعهها،
اسناد همکنشپذیری را ببینید.
جریانهای دادهها
Compose با افزونههایی برای پرطرفدارترین راهحلهای مبتنی بر جریان Android ارائه میشود. هرکدام از این افزونهها توسط یک آرتیفکت متفاوت ارائه میشود:
-
LiveData.observeAsState()در مصنوعandroidx.compose.runtime:runtime-livedata:$composeVersionگنجانده شده است. Flow.collectAsState()به وابستگیهای اضافی نیاز ندارد.Observable.subscribeAsState()در خروجی ساختاریافتهandroidx.compose.runtime:runtime-rxjava2:$composeVersionیاandroidx.compose.runtime:runtime-rxjava3:$composeVersionگنجانده شده است.
این آرتیفکتها بهعنوان شنونده ثبت میشوند و مقادیر را بهصورت
State نشان میدهند. هرگاه مقدار جدیدی
منتشر شود، Compose آن بخشهایی از واسط کاربر را که در آن از state.value استفاده شده است
دوباره ترکیببندی میکند. برای مثال، در این کد، هر بار که exampleLiveData مقدار جدیدی را منتشر میکند، ShowData دوباره ترکیب میشود.
// 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 به شما امکان میدهد عملیات ناهمگام را بااستفاده از کوروتینها از داخل composableهایتان اجرا کنید.
برای کسب اطلاعات بیشتر، میاناهای برنامهسازی کاربردی LaunchedEffect، produceState، و rememberCoroutineScope را در اسناد عوارض جانبی ببینید.
پیمایش
مؤلفه پیمایش از برنامههای Jetpack Compose پشتیبانی میکند. برای اطلاعات بیشتر، پیمایش با Compose و انتقال پیمایش Jetpack به Navigation Compose را ببینید.
Hilt
Hilt راهکار توصیهشده برای تزریق وابستگی در برنامههای Android است و بهطور یکپارچه با 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 و پیمایش
Hilt همچنین با کتابخانه Navigation Compose ادغام میشود. وابستگیهای اضافی زیر را به فایل Gradle خود اضافه کنید:
شیک
dependencies { implementation 'androidx.hilt:hilt-navigation-compose:1.4.0' }
کاتلین
dependencies { implementation("androidx.hilt:hilt-navigation-compose:1.4.0") }
هنگام استفاده از Navigation Compose، همیشه از تابع ترکیبپذیر 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 را که به
مسیرهای پیمایش یا نمودار
پیمایش محدود شده است بازیابی کنید،
بهجای آن از تابع ترکیبپذیر 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 اضافی است که باید
به پروژه و نسخه آن اضافه شود.
در اینجا مثالی از میاناهای برنامهسازی کاربردی 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") } } }
برای اطلاعات بیشتر درباره استفاده از «صفحهبندی» در Compose، اسناد فهرستها و شبکهها را بررسی کنید.
Maps
میتوانید از کتابخانه 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" ) } }
توصیهشده برای شما
- توجه: وقتی جاوا اسکریپت خاموش باشد، نوشتار پیوند نمایش داده میشود
- عوارض جانبی در Compose
- حالت و Jetpack Compose
- ذخیره کردن وضعیت میانای کاربر در Compose