کاشی ها می توانند بیشتر از نمایش اطلاعات انجام دهند. آنها همچنین می توانند تعاملی باشند. برای اینکه عنصری مانند textButton()
به ضربه ها پاسخ دهد، یک کنترل کننده کلیک با استفاده از clickable()
ایجاد کنید و آن را با عنصر layout مرتبط کنید.
شما می توانید یک Clickable
برای راه اندازی یک عمل به دو روش اصلی پیکربندی کنید:
- مستقیماً یک اکتیویتی را راه اندازی کنید : برای مواردی که باید فوراً یک اکتیویتی را باز کنید، از
launchAction()
استفاده کنید. - به سرویس کاشی خود واگذار کنید : از
loadAction()
برای فعال کردن منطق درTileService
خود استفاده کنید. این یک رویکرد انعطافپذیرتر است که به شما امکان میدهد محتوای کاشی را بهروزرسانی کنید، وضعیت آن را بهروزرسانی کنید یا فعالیت پیچیدهتری را راهاندازی کنید.
یک فعالیت صادراتی را راه اندازی کنید
اگر کاربر باید فوراً یک فعالیت را راه اندازی کند، از launchAction()
استفاده کنید. یک ComponentName
برای شناسایی فعالیت ارائه دهید. فعالیت باید صادر شود. با این رویکرد، می توانید موارد اضافی Intent
با اکشن عبور دهید. با این حال، تنظیم پرچمهای Intent
سفارشی امکانپذیر نیست.
مثال زیر نحوه ایجاد یک Clickable
برای راه اندازی TileActivity
با دو ویژگی اضافی، name
و age
را نشان می دهد:
textButton( labelContent = { text("launchAction()".layoutString, typography = BODY_LARGE) }, onClick = clickable( action = launchAction( ComponentName( "com.example.wear", "com.example.wear.snippets.m3.tile.TileActivity", ), mapOf( "name" to ActionBuilders.stringExtra("Bartholomew"), "age" to ActionBuilders.intExtra(21), ), ) ), )
در داخل اکتیویتی راه اندازی شده، مقادیر را از اضافات intent بازیابی کنید:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // When this activity is launched from the tile InteractionLaunchAction, // "name" will be "Bartholomew" and "age" will be 21 val name = intent.getStringExtra("name") val age = intent.getStringExtra("age") // ... }
تعاملات را در سرویس کاشی خود مدیریت کنید
برای تعاملات انعطافپذیرتر، از loadAction()
استفاده کنید. وقتی کاربر روی عنصری که با loadAction
پیکربندی شده است ضربه میزند، سیستم مجدداً TileService.onTileRequest()
شما را فراخوانی میکند. این به شما امکان می دهد منطق را در سرویس خود اجرا کنید تا کاشی را به روز کنید، وضعیت آن را تغییر دهید و کارهای پیچیده تری را انجام دهید.
محتوای کاشی را تازه کنید
ساده ترین استفاده از loadAction
، سیگنال دادن به تازه کردن است. loadAction
بدون آرگومان فراخوانی کنید. با ضربه زدن، سیستم onTileRequest()
را فراخوانی می کند و به سرویس شما اجازه می دهد یک طرح بندی جدید با محتوای به روز شده را بازگرداند.
textButton( onClick = clickable(loadAction()), labelContent = { text("Refresh".layoutString) }, )
بین عناصر تعاملی متعدد تمایز قائل شوید
اگر کاشی شما حاوی چندین عنصر تعاملی است، می توانید یک شناسه را با اصلاح کننده Clickable
مرتبط کنید:
textButton( labelContent = { text("Deep Link me!".layoutString, typography = BODY_LARGE) }, onClick = clickable(id = "foo", action = loadAction()), )
در داخل onTileRequest()
میتوانید این شناسه را با استفاده از requestParams.currentState.lastClickableId
بررسی کنید تا تصمیم بگیرید چه اقدامی را انجام دهید.
مثال: راه اندازی یک فعالیت با پیوند عمیق
این الگو برای راه اندازی یک فعالیت با پیوند عمیق ایده آل است. ضربه کاربر کاشی را دوباره بارگیری می کند، سرویس شما شناسه را بررسی می کند و سپس فعالیت جدید را راه اندازی می کند. برای کنترل پشته پشتی، از TaskStackBuilder
استفاده کنید تا تجربه ناوبری بهتری را برای کاربر فراهم کنید. وقتی کاربر روی عنصر ضربه می زند، مستقیماً به صفحه پیوند عمیق (صفحه message_detail/1
از مثال) منتقل می شود. از آنجایی که .addNextIntentWithParentStack()
استفاده شد، فعالیت والد نیز به پشته اضافه می شود. این بدان معناست که اگر کاربر انگشت خود را به عقب بکشد، بهجای خروج فوراً به کاشی، به صفحه اصلی برنامه ( MessageList
در مثال) میرود. کشیدن انگشت به عقب برای بار دوم آنها را به کاشی باز می گرداند.
override fun onTileRequest( requestParams: RequestBuilders.TileRequest ): ListenableFuture<Tile?> { val lastClickableId = requestParams.currentState.lastClickableId if (lastClickableId == "foo") { TaskStackBuilder.create(this) .addNextIntentWithParentStack( Intent( Intent.ACTION_VIEW, "googleandroidsnippets://app/message_detail/1".toUri(), this, TileActivity::class.java, ) ) .startActivities() } // ... User didn't tap a button (either first load or tapped somewhere else) // ... }
سپس، در TileActivity
، پیمایش خود را برای مطابقت با الگوی googleandroidsnippets://app/message_detail/{id}
پیکربندی کنید.
AppScaffold { val navController = rememberSwipeDismissableNavController() SwipeDismissableNavHost( navController = navController, startDestination = "message_list", ) { // ... composable( route = "message_detail/{id}", deepLinks = listOf( navDeepLink { uriPattern = "googleandroidsnippets://app/message_detail/{id}" } ), ) { val id = it.arguments?.getString("id") ?: "0" MessageDetails(details = "message $id") } } }
از TaskStackBuilder
برای ارائه یک تجربه ناوبری بهتر برای کاربر استفاده کنید. وقتی کاربر روی عنصر ضربه می زند، مستقیماً به صفحه پیوند عمیق منتقل می شود - در این مثال، صفحه message_detail/1
است. از آنجایی که .addNextIntentWithParentStack()
استفاده شد، فعالیت والد نیز به پشته اضافه می شود. این بدان معناست که اگر کاربر انگشت خود را به عقب بکشد، بهجای خروج فوری از کاشی، به صفحه اصلی برنامه - MessageList
در مثال - میرود. کشیدن انگشت به عقب برای بار دوم آنها را به کاشی باز می گرداند.
به روز رسانی وضعیت در کاشی
کاشی شما دارای یک شی StateBuilders.State
است که جفتهای کلید-مقدار را ذخیره میکند و در بارگذاریهای مجدد باقی میماند. شما می توانید از loadAction()
برای به روز رسانی این حالت در هنگام تعامل کاربر با کاشی استفاده کنید.
برای انجام این کار، یک DynamicDataMap
به loadAction()
ارسال کنید که حاوی مقادیر جدید حالت است.
textButton( labelContent = { text("loadAction()".layoutString, typography = BODY_LARGE) }, onClick = clickable( action = loadAction( dynamicDataMapOf( stringAppDataKey("name") mapTo "Javier", intAppDataKey("age") mapTo 37, ) ) ), )
هنگامی که onTileRequest()
توسط این عمل فعال می شود، می توانید داده های به روز شده را از requestParams.currentState.stateMap
بخوانید. این برای فعل و انفعالاتی مفید است که مستقیماً دادههای کاشی را تغییر میدهند، مانند افزایش شمارنده یا تغییر تنظیمات.
override fun onTileRequest( requestParams: RequestBuilders.TileRequest ): ListenableFuture<Tile> { // When triggered by loadAction(), "name" will be "Javier", and "age" will // be 37. with(requestParams.currentState.stateMap) { val name = this[stringAppDataKey("name")] val age = this[intAppDataKey("age")] } // ... }