عرض التحديثات الدورية في المربّعات
تنظيم صفحاتك في مجموعات
يمكنك حفظ المحتوى وتصنيفه حسب إعداداتك المفضّلة.
أنشئ مربّعات تتضمّن محتوى يتغيّر بمرور الوقت.
العمل مع المخططات الزمنية
يتألف المخطط الزمني من مثيل واحد أو أكثر
TimelineEntry
يحتوي كلّ منها على تنسيق يتم عرضه خلال فاصل زمني معيّن. يجب أن تتضمّن كل مربّعات معلومات مخططًا زمنيًا.

مربّعات الإدخال الواحد
في كثير من الأحيان، يمكن وصف مربّع باستخدام TimelineEntry
واحد. يكون التنسيق
ثابتًا، ولا تتغيّر سوى المعلومات داخل التنسيق. على سبيل المثال، يعرض مربّع الشاشة الذي يعرض مستوى لياقتك البدنية خلال اليوم دائمًا تنسيق مستوى التقدّم نفسه، ولكن يمكنك تعديل هذا التنسيق لعرض قيم مختلفة. في هذه
الحالات، لا يمكنك معرفة متى قد يتغيّر المحتوى مسبقًا.
اطّلِع على المثال التالي لمربّع يتضمّن TimelineEntry
واحدًا:
override fun onTileRequest(
requestParams: RequestBuilders.TileRequest
): ListenableFuture<Tile?> {
val tile =
Tile.Builder()
.setResourcesVersion(RESOURCES_VERSION)
// We add a single timeline entry when our layout is fixed, and
// we don't know in advance when its contents might change.
.setTileTimeline(Timeline.fromLayoutElement(simpleLayout(this)))
.build()
return Futures.immediateFuture(tile)
}
إدخالات المخطط الزمني ذات الصلة بوقت معيّن
يمكن أن يحدِّد TimelineEntry
بشكل اختياري فترة صلاحية، ما يسمح للقرص المميّز
بتغيير تنسيقه في وقت محدّد بدون الحاجة إلى أن يُرسِل التطبيق قرصًا جديدًا.
المثال الأساسي هو مربّع جدول أعمال يحتوي على مخطط زمني يتضمن قائمة بالأحداث القادمة. يحتوي كلّ حدث قادم على فترة صلاحية للإشارة إلى وقت
عرضه.
تسمح واجهة برمجة التطبيقات Tiles API بتداخل فترات الصلاحية، حيث تكون الشاشة التي تتضمن
أقصر فترة زمنية متبقية هي الشاشة المعروضة. يتم عرض حدث واحد فقط في كل
مرة.
يمكن للمطوّرين تقديم إدخال احتياطي تلقائي. على سبيل المثال، يمكن أن يتضمّن مربّع الجدول الزمني
مربّعًا بفترة صلاحية غير محدودة، ويتم استخدامه إذا لم يكن هناك إدخال جدول زمني
آخر صالح، كما هو موضّح في نموذج الرمز البرمجي التالي:
override fun onTileRequest(
requestParams: RequestBuilders.TileRequest
): ListenableFuture<Tile?> {
val timeline = Timeline.Builder()
// Add fallback "no meetings" entry
// Use the version of TimelineEntry that's in androidx.wear.protolayout.
timeline.addTimelineEntry(
TimelineBuilders.TimelineEntry.Builder().setLayout(getNoMeetingsLayout()).build()
)
// Retrieve a list of scheduled meetings
val meetings = MeetingsRepo.getMeetings()
// Add a timeline entry for each meeting
meetings.forEach { meeting ->
timeline.addTimelineEntry(
TimelineBuilders.TimelineEntry.Builder()
.setLayout(getMeetingLayout(meeting))
.setValidity(
// The tile should disappear when the meeting begins
// Use the version of TimeInterval that's in
// androidx.wear.protolayout.
TimelineBuilders.TimeInterval.Builder()
.setEndMillis(meeting.dateTimeMillis)
.build()
)
.build()
)
}
val tile =
Tile.Builder()
.setResourcesVersion(RESOURCES_VERSION)
.setTileTimeline(timeline.build())
.build()
return Futures.immediateFuture(tile)
}
إعادة تحميل مربّع
قد تنتهي صلاحية المعلومات المعروضة على مربّع معلومات بعد مرور بعض الوقت. على سبيل المثال، فإنّ مربّع الطقس الذي يعرض درجة الحرارة نفسها على مدار اليوم ليس دقيقًا.
للتعامل مع البيانات التي تنتهي صلاحيتها، يمكنك ضبط فاصل حداثة في وقت إنشاء ملف التمرير الذي يحدّد مدة صلاحيته. في مثال مربّع الطقس، يمكنك تعديل محتواه كل ساعة، كما هو موضّح في المثال التالي على الرمز البرمجي:
override fun onTileRequest(
requestParams: RequestBuilders.TileRequest
): ListenableFuture<Tile?> =
Futures.immediateFuture(
Tile.Builder()
.setResourcesVersion(RESOURCES_VERSION)
.setFreshnessIntervalMillis(60 * 60 * 1000) // 60 minutes
.setTileTimeline(Timeline.fromLayoutElement(getWeatherLayout()))
.build()
)
عند ضبط فاصل حداثة، يستدعي النظام onTileRequest()
بعد انتهاء الفاصل بوقت قصير. في حال عدم ضبط فاصل حداثة، لن يُطلِق
النظام طلبًا إلى onTileRequest()
.
يمكن أن تنتهي صلاحية مربّع معلومات أيضًا بسبب حدث خارجي. على سبيل المثال، قد يزيل مستخدم
اجتماعًا من تقويمه، وإذا لم يتم إعادة تحميل المربّع، سيظل المربّع يعرض الاجتماع المحذوف. في هذه الحالة، يمكنك طلب إعادة تحميل من
أي موضع في رمز تطبيقك، كما هو موضّح في نموذج الرمز البرمجي التالي:
Kotlin
fun eventDeletedCallback() {
TileService.getUpdater(context)
.requestUpdate(MyTileService::class.java)
}
Java
public void eventDeletedCallback() {
TileService.getUpdater(context)
.requestUpdate(MyTileService.class);
}
اختيار سير عمل التعديل
اتّبِع أفضل الممارسات التالية لتحديد كيفية ضبط تحديثات مربّعات المعلومات:
- إذا كان التعديل متوقّعًا، على سبيل المثال، إذا كان للحدث التالي في
تقويم المستخدم، استخدِم مخططًا زمنيًا.
- عند جلب بيانات المنصة، استخدِم ربط البيانات لكي يعدّل النظام
البيانات تلقائيًا.
إذا كان بالإمكان احتساب التعديل على الجهاز في وقت قصير، مثل تعديل موضع صورة في مربّع شروق الشمس، استخدِم onTileRequest()
.
ويُعدّ هذا الإجراء مفيدًا بشكل خاص عندما تحتاج إلى إنشاء كل الصور مسبقًا. إذا كنت بحاجة إلى إنشاء صورة جديدة في وقت لاحق، يُرجى الاتصال بالرقم
setFreshnessIntervalMillis()
.
إذا كنت تُجري عملًا مكثّفًا في الخلفية بشكل متكرّر، مثل فحص
بيانات الطقس، استخدِم WorkManager
وأرسِل التعديلات إلى مربّع الرموز.
إذا كان التعديل استجابةً لحدث خارجي، مثل إشعال المصابيح
أو تلقّي رسالة إلكترونية أو تعديل ملاحظة، أرسِل رسالة المراسلة عبر السحابة الإلكترونية من
Firebase (FCM) لتنشيط تطبيقك مرة أخرى، ثم أرسِل التعديلات
إلى مربّع المعلومات.
إذا كانت عملية مزامنة بيانات المربّعات قد تكون باهظة التكلفة، عليك اتّباع الخطوات التالية:
- حدِّد موعدًا لمزامنة البيانات.
- ابدأ موقّتًا لمدة ثانية أو ثانيتَين.
- إذا تلقّيت تعديلاً من مصدر بيانات عن بُعد قبل انتهاء الوقت،
أظهِر القيمة المعدَّلة من مزامنة البيانات. بخلاف ذلك، أظهِر قيمة محلية
مخزّنة مؤقتًا.
أفلام مُقترَحة لك
يخضع كل من المحتوى وعيّنات التعليمات البرمجية في هذه الصفحة للتراخيص الموضحّة في ترخيص استخدام المحتوى. إنّ Java وOpenJDK هما علامتان تجاريتان مسجَّلتان لشركة Oracle و/أو الشركات التابعة لها.
تاريخ التعديل الأخير: 2025-08-31 (حسب التوقيت العالمي المتفَّق عليه)
[[["يسهُل فهم المحتوى.","easyToUnderstand","thumb-up"],["ساعَدني المحتوى في حلّ مشكلتي.","solvedMyProblem","thumb-up"],["غير ذلك","otherUp","thumb-up"]],[["لا يحتوي على المعلومات التي أحتاج إليها.","missingTheInformationINeed","thumb-down"],["الخطوات معقدة للغاية / كثيرة جدًا.","tooComplicatedTooManySteps","thumb-down"],["المحتوى قديم.","outOfDate","thumb-down"],["ثمة مشكلة في الترجمة.","translationIssue","thumb-down"],["مشكلة في العيّنات / التعليمات البرمجية","samplesCodeIssue","thumb-down"],["غير ذلك","otherDown","thumb-down"]],["تاريخ التعديل الأخير: 2025-08-31 (حسب التوقيت العالمي المتفَّق عليه)"],[],[],null,["Create tiles with content that changes as time passes.\n\nWork with timelines\n\nA timeline consists of one or more\n[`TimelineEntry`](/reference/androidx/wear/protolayout/TimelineBuilders.TimelineEntry)\ninstances, each of which contain a layout that is displayed during a specific\ntime interval. All tiles need a timeline.\n\nSingle-entry tiles\n\nOften a tile can be described with a single `TimelineEntry`. The layout is\nfixed, and only the information inside the layout changes. For example, a tile\nthat shows your fitness progress of the day always shows the same progress\nlayout, though you might adjust that layout to show different values. In these\ncases, you don't know in advance when the content might change.\n\nSee the following example of a tile with a single `TimelineEntry`: \n\n```kotlin\noverride fun onTileRequest(\n requestParams: RequestBuilders.TileRequest\n): ListenableFuture\u003cTile?\u003e {\n val tile =\n Tile.Builder()\n .setResourcesVersion(RESOURCES_VERSION)\n // We add a single timeline entry when our layout is fixed, and\n // we don't know in advance when its contents might change.\n .setTileTimeline(Timeline.fromLayoutElement(simpleLayout(this)))\n .build()\n return Futures.immediateFuture(tile)\n}https://github.com/android/snippets/blob/f95ab59fad80aeaf5d6a90bab8a01a126f20f44e/wear/src/main/java/com/example/wear/snippets/tile/Tile.kt#L74-L85\n```\n\nTimebound timeline entries\n\nA `TimelineEntry` can optionally define a validity period, allowing a tile to\nchange its layout at a known time without requiring the app to push a new tile.\n\nThe canonical example is an agenda tile whose timeline contains a list of\nupcoming events. Each upcoming event contains a validity period to indicate when\nto show it.\n\nThe tiles API allows for overlapping validity periods, where the screen with the\nshortest period of time left is the one shown. Only one event is displayed at a\ntime.\n\nDevelopers can provide a default fallback entry. For example, the agenda tile\ncould have a tile with an infinite validity period, which is used if no other\ntimeline entry is valid, as shown in the following code sample: \n\n```kotlin\noverride fun onTileRequest(\n requestParams: RequestBuilders.TileRequest\n): ListenableFuture\u003cTile?\u003e {\n val timeline = Timeline.Builder()\n\n // Add fallback \"no meetings\" entry\n // Use the version of TimelineEntry that's in androidx.wear.protolayout.\n timeline.addTimelineEntry(\n TimelineBuilders.TimelineEntry.Builder().setLayout(getNoMeetingsLayout()).build()\n )\n\n // Retrieve a list of scheduled meetings\n val meetings = MeetingsRepo.getMeetings()\n // Add a timeline entry for each meeting\n meetings.forEach { meeting -\u003e\n timeline.addTimelineEntry(\n TimelineBuilders.TimelineEntry.Builder()\n .setLayout(getMeetingLayout(meeting))\n .setValidity(\n // The tile should disappear when the meeting begins\n // Use the version of TimeInterval that's in\n // androidx.wear.protolayout.\n TimelineBuilders.TimeInterval.Builder()\n .setEndMillis(meeting.dateTimeMillis)\n .build()\n )\n .build()\n )\n }\n\n val tile =\n Tile.Builder()\n .setResourcesVersion(RESOURCES_VERSION)\n .setTileTimeline(timeline.build())\n .build()\n return Futures.immediateFuture(tile)\n}https://github.com/android/snippets/blob/f95ab59fad80aeaf5d6a90bab8a01a126f20f44e/wear/src/main/java/com/example/wear/snippets/tile/Tile.kt#L118-L154\n```\n\nRefresh a tile\n\nInformation shown on a tile might expire after some time. For example, a weather\ntile that shows the same temperature throughout the day isn't accurate.\n\nTo deal with expiring data, set a freshness interval at the time of creating a\ntile, which specifies how long the tile is valid. In the example of the weather\ntile, you might update its content every hour, as shown in the following code\nsample: \n\n```kotlin\noverride fun onTileRequest(\n requestParams: RequestBuilders.TileRequest\n): ListenableFuture\u003cTile?\u003e =\n Futures.immediateFuture(\n Tile.Builder()\n .setResourcesVersion(RESOURCES_VERSION)\n .setFreshnessIntervalMillis(60 * 60 * 1000) // 60 minutes\n .setTileTimeline(Timeline.fromLayoutElement(getWeatherLayout()))\n .build()\n )https://github.com/android/snippets/blob/f95ab59fad80aeaf5d6a90bab8a01a126f20f44e/wear/src/main/java/com/example/wear/snippets/tile/Tile.kt#L162-L171\n```\n\nWhen you set a freshness interval, the system calls\n[`onTileRequest()`](/reference/androidx/wear/tiles/TileService#onTileRequest(androidx.wear.tiles.RequestBuilders.TileRequest))\nshortly after the interval finishes. If you don't set a freshness interval, the\nsystem doesn't call `onTileRequest()`.\n\nA tile can also expire because of an external event. For example, a user might\nremove a meeting from their calendar, and if the tile wasn't refreshed, then the\ntile would still show that deleted meeting. In this case, request a refresh from\nany place in your application code, as shown in the following code sample: \n\nKotlin \n\n```kotlin\nfun eventDeletedCallback() {\n TileService.getUpdater(context)\n .requestUpdate(MyTileService::class.java)\n}\n```\n\nJava \n\n```java\npublic void eventDeletedCallback() {\n TileService.getUpdater(context)\n .requestUpdate(MyTileService.class);\n}\n```\n\nChoose an update workflow\n\nUse these best practices to determine how to configure your tile updates:\n\n- If the update is predictable---for example, if it's for the next event in the user's calendar---use a timeline.\n- When you fetch platform data, use data binding so that the system updates the data automatically.\n- If the update can be calculated on-device in a small amount of time---such\n as updating the position of an image on a sunrise tile---use\n [`onTileRequest()`](/reference/androidx/wear/tiles/TileService#onTileRequest(androidx.wear.tiles.RequestBuilders.TileRequest)).\n\n This is particularly useful when you need to generate all images ahead of\n time. If you need to generate a new image at a future time, call\n [`setFreshnessIntervalMillis()`](/reference/androidx/wear/tiles/TileBuilders.Tile.Builder#setFreshnessIntervalMillis(long)).\n- If you're doing more intensive background work repeatedly, such as polling\n for weather data, use [`WorkManager`](/topic/libraries/architecture/workmanager), and push updates to your tile.\n\n- If the update is in response to an external event---such as the lights\n turning on, receiving an email, or updating a note---send a [Firebase Cloud\n Messaging (FCM)](https://firebase.google.com/docs/cloud-messaging) message to make your app active again, then push updates\n to the tile.\n\n- If the tile data sync process might be expensive, do the following:\n\n 1. Schedule a data sync.\n 2. Start a timer for 1-2 seconds.\n 3. If you receive an update from a remote data source before time runs out, show the updated value from the data sync. Otherwise, show a cached local value.\n\nRecommended for you\n\n- Note: link text is displayed when JavaScript is off\n- [Minimize the effect of regular updates](/develop/connectivity/minimize-effect-regular-updates)\n- [Access location in the background](/develop/sensors-and-location/location/background)\n- [Getting started with WorkManager](/develop/background-work/background-tasks/persistent/getting-started)"]]