تتخصّص تطبيقات المجموعة المصغّرة في عرض العديد من العناصر من النوع نفسه، مثل مجموعات الصور من تطبيق معرض الصور أو المقالات من تطبيق الأخبار أو الرسائل من تطبيق التواصل. تركّز تطبيقات المجموعة المصغّرة عادةً على حالتي استخدام: تصفّح المجموعة وفتح عنصر من المجموعة لعرض تفاصيله. يمكن الانتقال للأعلى أو للأسفل في تطبيقات مصغّرة للمجموعات.
تستخدم هذه التطبيقات المصغّرة
RemoteViewsService لعرض
المجموعات المستندة إلى بيانات عن بُعد، مثل البيانات الواردة من أداة توفير
المحتوى. تعرض الأداة البيانات باستخدام أحد أنواع طرق العرض التالية، والتي تُعرف باسم طرق عرض المجموعة:
ListView: طريقة عرض تعرض العناصر في قائمة يتم التمرير فيها عموديًا.
GridView: طريقة عرض تعرض العناصر في شبكة تمرير ثنائية الأبعاد.
StackView: عرض البطاقات المكدّسة، وهو يشبه إلى حدّ ما بطاقات الفهرسة، حيث يمكن للمستخدم تمرير البطاقة الأمامية للأعلى أو للأسفل للاطّلاع على البطاقة السابقة أو التالية على التوالي.
AdapterViewFlipper: ViewAnimator مستند إلى محوِّل يعرض صورًا متحركة بين عرضَين أو أكثر. يتم عرض طفل واحد فقط في كل مرة.
بما أنّ طرق العرض هذه تعرض مجموعات مستندة إلى بيانات عن بُعد، فهي تستخدم Adapter لربط واجهة المستخدم بالبيانات. يربط Adapter العناصر الفردية من مجموعة من البيانات
بعناصر View فردية.
وبما أنّ طرق عرض المجموعات هذه تستند إلى المحوّلات، يجب أن يتضمّن إطار عمل Android
بنية إضافية لإتاحة استخدامها في التطبيقات المصغّرة. في سياق التطبيق المصغّر، يتم استبدال Adapter بـ RemoteViewsFactory، وهو برنامج تضمين بسيط لواجهة Adapter. عند طلب عنصر معيّن في المجموعة، ينشئ RemoteViewsFactory العنصر للمجموعة ويعرضه كعنصر RemoteViews. لتضمين
عرض مجموعة في التطبيق المصغّر، عليك تنفيذ RemoteViewsService وRemoteViewsFactory.
RemoteViewsService هي خدمة تتيح لمحوّل عن بُعد طلب
كائنات RemoteViews. RemoteViewsFactory هي واجهة لمحوِّل
بين طريقة عرض مجموعة، مثل ListView وGridView
وStackView، والبيانات الأساسية لطريقة العرض هذه. من نموذج StackWidget، إليك مثال على الرمز البرمجي النموذجي لتنفيذ هذه الخدمة والواجهة:
class StackWidgetService : RemoteViewsService() { override fun onGetViewFactory(intent: Intent): RemoteViewsFactory = StackRemoteViewsFactory(this.applicationContext, intent) } class StackRemoteViewsFactory( private val context: Context, intent: Intent ) : RemoteViewsService.RemoteViewsFactory { // See the RemoteViewsFactory API reference for the full list of methods to implement. }
نموذج تطبيق
تم أيضًا استخراج مقتطفات الرمز في هذا القسم من نموذج StackWidget:
StackWidget.يتكون هذا النموذج من مجموعة من عشر طرق عرض تعرض القيم من صفر إلى تسعة. يتضمّن التطبيق المصغّر النموذجي السلوكيات الأساسية التالية:
يمكن للمستخدم التمرير سريعًا بشكل عمودي في العرض العلوي في التطبيق المصغّر لعرض العرض التالي أو السابق. هذا سلوك مضمَّن في
StackView.بدون أي تفاعل من المستخدم، يتقدّم التطبيق المصغّر تلقائيًا من خلال طرق العرض بالتسلسل، مثل عرض الشرائح. ويرجع ذلك إلى الإعداد
android:autoAdvanceViewId="@id/stack_view"في ملفres/xml/stackwidgetinfo.xml. ينطبق هذا الإعداد على معرّف العرض، والذي يمثّل في هذه الحالة معرّف عرض التكديس.إذا لمس المستخدم العرض من الأعلى، يعرض التطبيق المصغّر الرسالة
Toast"تم لمس العرض n"، حيث n هو فهرس (موضع) العرض الذي تم لمسه. لمزيد من المناقشة حول كيفية تنفيذ السلوكيات، راجِع قسم إضافة سلوك إلى عناصر فردية.
تنفيذ التطبيقات المصغّرة باستخدام المجموعات
لتنفيذ تطبيق مصغّر يتضمّن مجموعات، اتّبِع الإجراء الخاص بتنفيذ أي تطبيق مصغّر، ثم اتّبِع بضع خطوات إضافية: تعديل البيان وإضافة عرض مجموعة إلى تنسيق التطبيق المصغّر وتعديل الفئة الفرعية AppWidgetProvider.
ملف البيان للتطبيقات المصغّرة التي تتضمّن مجموعات
بالإضافة إلى المتطلبات المذكورة في قسم تعريف التطبيق المصغّر في ملف البيان، يجب أن تتيح للتطبيقات المصغّرة التي تحتوي على مجموعات إمكانية الربط بـ RemoteViewsService. يمكنك إجراء ذلك من خلال تحديد
الخدمة في ملف البيان باستخدام الإذن
BIND_REMOTEVIEWS.
يمنع ذلك التطبيقات الأخرى من الوصول بحرية إلى بيانات التطبيق المصغّر.
على سبيل المثال، عند إنشاء تطبيق مصغّر يستخدم RemoteViewsService لتعبئة
عرض المجموعة، قد يبدو إدخال البيان على النحو التالي:
<service android:name="MyWidgetService"
android:permission="android.permission.BIND_REMOTEVIEWS" />
في هذا المثال، يشير android:name="MyWidgetService" إلى الفئة الفرعية من
RemoteViewsService.
تنسيق التطبيقات المصغّرة التي تتضمّن مجموعات
الشرط الرئيسي لملف XML الخاص بتنسيق التطبيق المصغّر هو أن يتضمّن إحدى طرق عرض المجموعة: ListView أو GridView أو StackView أو AdapterViewFlipper. إليك ملف widget_layout.xml لنموذج
StackWidget:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <StackView android:id="@+id/stack_view" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:loopViews="true" /> <TextView android:id="@+id/empty_view" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:background="@drawable/widget_item_background" android:textColor="#ffffff" android:textStyle="bold" android:text="@string/empty_view_text" android:textSize="20sp" /> </FrameLayout>
يُرجى العِلم أنّ طرق العرض الفارغة يجب أن تكون تابعة لطريقة عرض المجموعة التي تمثّل طريقة العرض الفارغة الحالة الفارغة لها.
بالإضافة إلى ملف التنسيق الخاص بالتطبيق المصغّر بالكامل، أنشئ ملف تنسيق آخر يحدّد التنسيق لكل عنصر في المجموعة، على سبيل المثال، تنسيق لكل كتاب في مجموعة من الكتب. يحتوي نموذج StackWidget على ملف تخطيط عنصر واحد فقط، وهو widget_item.xml، لأنّ جميع العناصر تستخدم التخطيط نفسه.
فئة AppWidgetProvider للتطبيقات المصغّرة التي تتضمّن مجموعات
كما هو الحال مع التطبيقات المصغّرة العادية، يتم عادةً إدراج معظم الرمز البرمجي في الفئة الفرعية AppWidgetProvider في onUpdate().
يتمثل الاختلاف الرئيسي في تنفيذك لـ onUpdate() عند إنشاء
تطبيق مصغّر مع مجموعات في أنه يجب عليك استدعاء
setRemoteAdapter().
يخبر هذا طريقة عرض المجموعة من أين تحصل على بياناتها.
يمكن لـ RemoteViewsService بعد ذلك عرض تنفيذك لـ RemoteViewsFactory، ويمكن للتطبيق المصغّر عرض البيانات المناسبة. عند استدعاء هذه الطريقة، يجب تمرير نية تشير إلى تنفيذ RemoteViewsService ورقم تعريف التطبيق المصغّر الذي يحدّد التطبيق المصغّر المطلوب تعديله.
على سبيل المثال، إليك كيفية تنفيذ نموذج StackWidget لطريقة رد الاتصال onUpdate() لضبط RemoteViewsService كمحوّل عن بُعد لمجموعة التطبيقات المصغّرة:
override fun onUpdate( context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray ) { // Update each of the widgets with the remote adapter. appWidgetIds.forEach { appWidgetId -> // Set up the intent that starts the StackViewService, which // provides the views for this collection. val intent = Intent(context, StackWidgetService::class.java).apply { // Add the widget ID to the intent extras. putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId) data = Uri.parse(toUri(Intent.URI_INTENT_SCHEME)) } // Instantiate the RemoteViews object for the widget layout. val views = RemoteViews(context.packageName, R.layout.widget_layout).apply { // Set up the RemoteViews object to use a RemoteViews adapter. // This adapter connects to a RemoteViewsService through the // specified intent. // This is how you populate the data. setRemoteAdapter(R.id.stack_view, intent) // The empty view is displayed when the collection has no items. // It must be in the same layout used to instantiate the // RemoteViews object. setEmptyView(R.id.stack_view, R.id.empty_view) } // Do additional processing specific to this widget. appWidgetManager.updateAppWidget(appWidgetId, views) } super.onUpdate(context, appWidgetManager, appWidgetIds) }
الاحتفاظ بالبيانات
كما هو موضّح في هذه الصفحة، توفّر الفئة الفرعية RemoteViewsService
السمة RemoteViewsFactory المستخدَمة لتعبئة عرض المجموعة عن بُعد.
على وجه التحديد، نفِّذ الخطوات التالية:
الفئة الفرعية
RemoteViewsServiceRemoteViewsServiceهي الخدمة التي يمكن من خلالها لمحوّل عن بُعد طلبRemoteViews.في الفئة الفرعية
RemoteViewsService، أدرِج فئة تنفّذ واجهةRemoteViewsFactory. RemoteViewsFactoryهي واجهة لمحوِّل بين طريقة عرض مجموعة بيانات عن بُعد، مثلListViewأوGridViewأوStackView، والبيانات الأساسية لطريقة العرض هذه. تكون عملية التنفيذ مسؤولة عن إنشاء عنصرRemoteViewsلكل عنصر في مجموعة البيانات. هذه الواجهة هي برنامج تضمين بسيط حولAdapter.
لا يمكنك الاعتماد على مثيل واحد من الخدمة أو أي بيانات يحتوي عليها
للاستمرار. لا تخزِّن البيانات في RemoteViewsService ما لم تكن ثابتة. إذا أردت الاحتفاظ ببيانات التطبيق المصغّر، فإنّ أفضل طريقة هي استخدام ContentProvider تظل بياناته محفوظة بعد انتهاء مراحل نشاط العملية. على سبيل المثال، يمكن لأداة متجر بقالة تخزين حالة كل عنصر في قائمة البقالة في موقع تخزين دائم، مثل قاعدة بيانات SQL.
تتمثّل المحتويات الأساسية لتنفيذ RemoteViewsService في
RemoteViewsFactory، الموضّحة في القسم التالي.
واجهة RemoteViewsFactory
Your custom class that implements the RemoteViewsFactory interface provides
the widget with the data for the items in its collection. لإجراء ذلك، يجمع ملف تخطيط XML لعنصر التطبيق المصغّر مع مصدر البيانات. يمكن أن يكون مصدر البيانات هذا أي شيء من قاعدة بيانات إلى مصفوفة. في نموذج StackWidget، مصدر البيانات هو مصفوفة من WidgetItems. يعمل RemoteViewsFactory كمحوِّل لربط البيانات بعرض المجموعة البعيدة.
أهم طريقتَين يجب تنفيذهما للفئة الفرعية RemoteViewsFactory هما onCreate() وgetViewAt().
يستدعي النظام onCreate() عند إنشاء المصنع لأول مرة.
هنا يمكنك إعداد أي اتصالات أو مؤشرات لمصدر البيانات. على سبيل المثال، يستخدم نموذج StackWidget السمة onCreate() لإعداد مصفوفة من عناصر WidgetItem. عندما تكون الأداة نشطة، يصل النظام إلى هذه
الكائنات باستخدام موضع الفهرس الخاص بها في الصفيف ويعرض النص الذي
تحتويه.
في ما يلي مقتطف من عملية تنفيذ RemoteViewsFactory في نموذج StackWidget يعرض أجزاء من طريقة onCreate():
private const val REMOTE_VIEW_COUNT: Int = 10 class StackRemoteViewsFactory( private val context: Context ) : RemoteViewsService.RemoteViewsFactory { private lateinit var widgetItems: List<WidgetItem> override fun onCreate() { // In onCreate(), set up any connections or cursors to your data // source. Heavy lifting, such as downloading or creating content, // must be deferred to onDataSetChanged() or getViewAt(). Taking // more than 20 seconds on this call results in an ANR. widgetItems = List(REMOTE_VIEW_COUNT) { index -> WidgetItem("$index!") } } }
يعرض الإجراء RemoteViewsFactory getViewAt() عنصر RemoteViews يتوافق مع البيانات في position المحدّد في مجموعة البيانات. في ما يلي مقتطف من تنفيذ RemoteViewsFactory في نموذج StackWidget:
override fun getViewAt(position: Int): RemoteViews { // Construct a remote views item based on the widget item XML file // and set the text based on the position. return RemoteViews(context.packageName, R.layout.widget_item).apply { setTextViewText(R.id.widget_item, widgetItems[position].text) } }
إضافة سلوك إلى عناصر فردية
توضّح الأقسام السابقة كيفية ربط بياناتك بمجموعة التطبيقات المصغّرة. ولكن ماذا لو أردت إضافة سلوك ديناميكي إلى العناصر الفردية في عرض مجموعتك؟
كما هو موضّح في معالجة الأحداث باستخدام فئة onUpdate()، يمكنك عادةً استخدام setOnClickPendingIntent() لضبط سلوك النقر على عنصر، مثل جعل زرّ يشغّل Activity. لكن هذا الأسلوب غير مسموح به لعرض ملف الطفل في عنصر مجموعة فردي.
على سبيل المثال، يمكنك استخدام setOnClickPendingIntent() لإعداد زر عام
في تطبيق Gmail المصغّر الذي يشغّل التطبيق، ولكن ليس على
عناصر القائمة الفردية.
بدلاً من ذلك، لإضافة سلوك النقر إلى عناصر فردية في مجموعة، استخدِم
setOnClickFillInIntent(). يمكنك إعداد نموذج intent مؤجّلة
لطريقة عرض المجموعة وإعداد intent تعبئة لكل عنصر في
المجموعة باستخدام RemoteViewsFactory.
يستخدم هذا القسم نموذج StackWidget لوصف كيفية إضافة سلوك إلى
عناصر فردية. في نموذج StackWidget، إذا لمس المستخدم العرض العلوي،
يعرض التطبيق المصغّر رسالة Toast "تم لمس العرض n"، حيث n هو
فهرس (موضع) العرض الذي تم لمسه. إليك إرشادات:
تنشئ الفئة الفرعية
StackWidgetProvider، وهي فئة فرعية منAppWidgetProvider، intent مؤجّلة مع إجراء مخصّص باسمTOAST_ACTION.عندما يلمس المستخدم طريقة عرض، يتم تنشيط الغرض وبثّ
TOAST_ACTION.يتم اعتراض هذا البث من خلال طريقة
onReceive()في فئةStackWidgetProvider، ويعرض التطبيق المصغّر رسالةToastللعرض الذي تم لمسه. يتم توفير بيانات عناصر المجموعة من قِبلRemoteViewsFactoryمن خلالRemoteViewsService.
إعداد نموذج intent مؤجّلة
يُعدّ StackWidgetProvider (فئة فرعية من AppWidgetProvider)
intent مؤجّلة. لا يمكن للعناصر الفردية في المجموعة إعداد
intent المؤجّلة الخاصة بها. بدلاً من ذلك، تُعدّ المجموعة ككل نموذجًا لـ intent مؤجّلة، وتُعدّ العناصر الفردية intent ملء لإنشاء سلوك فريد على أساس كل عنصر على حدة.
تتلقّى هذه الفئة أيضًا البث الذي يتم إرساله عندما يلمس المستخدم
طريقة عرض. ويعالج هذا الحدث في طريقة onReceive(). إذا كان إجراء الغرض هو TOAST_ACTION، يعرض التطبيق المصغّر رسالة Toast للعرض الحالي.
const val TOAST_ACTION = "com.example.android.stackwidget.TOAST_ACTION" const val EXTRA_ITEM = "com.example.android.stackwidget.EXTRA_ITEM" class StackWidgetProvider : AppWidgetProvider() { // ... // Called when the BroadcastReceiver receives an Intent broadcast. // Checks whether the intent's action is TOAST_ACTION. If it is, the // widget displays a Toast message for the current item. override fun onReceive(context: Context, intent: Intent) { val mgr: AppWidgetManager = AppWidgetManager.getInstance(context) if (intent.action == TOAST_ACTION) { val appWidgetId: Int = intent.getIntExtra( AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID ) // EXTRA_ITEM represents a custom value provided by the Intent // passed to the setOnClickFillInIntent() method to indicate the // position of the clicked item. See StackRemoteViewsFactory in // Set the fill-in Intent for details. val viewIndex: Int = intent.getIntExtra(EXTRA_ITEM, 0) Toast.makeText(context, "Touched view $viewIndex", Toast.LENGTH_SHORT).show() } super.onReceive(context, intent) } override fun onUpdate( context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray ) { // Update each of the widgets with the remote adapter. appWidgetIds.forEach { appWidgetId -> // Sets up the intent that points to the StackViewService that // provides the views for this collection. val intent = Intent(context, StackWidgetService::class.java).apply { putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId) // When intents are compared, the extras are ignored, so embed // the extra sinto the data so that the extras are not ignored. data = Uri.parse(toUri(Intent.URI_INTENT_SCHEME)) } val rv = RemoteViews(context.packageName, R.layout.widget_layout).apply { setRemoteAdapter(R.id.stack_view, intent) // The empty view is displayed when the collection has no items. // It must be a sibling of the collection view. setEmptyView(R.id.stack_view, R.id.empty_view) } // This section makes it possible for items to have individualized // behavior. It does this by setting up a pending intent template. // Individuals items of a collection can't set up their own pending // intents. Instead, the collection as a whole sets up a pending // intent template, and the individual items set a fillInIntent // to create unique behavior on an item-by-item basis. val toastPendingIntent: PendingIntent = Intent( context, StackWidgetProvider::class.java ).run { // Set the action for the intent. // When the user touches a particular view, it has the effect of // broadcasting TOAST_ACTION. action = TOAST_ACTION putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId) data = Uri.parse(toUri(Intent.URI_INTENT_SCHEME)) // The template must be mutable, because each item fills in its // own extras through setOnClickFillInIntent(). PendingIntent.getBroadcast( context, 0, this, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE ) } rv.setPendingIntentTemplate(R.id.stack_view, toastPendingIntent) appWidgetManager.updateAppWidget(appWidgetId, rv) } super.onUpdate(context, appWidgetManager, appWidgetIds) } }
ضبط نية التعبئة
يجب أن يضبط RemoteViewsFactory هدف ملء لكل عنصر في المجموعة. يتيح ذلك تمييز الإجراء الفردي الذي يتم تنفيذه عند النقر على عنصر معيّن. يتم بعد ذلك دمج هدف الملء مع نموذج PendingIntent لتحديد الهدف النهائي الذي يتم تنفيذه عند النقر على العنصر.
private const val REMOTE_VIEW_COUNT: Int = 10 class StackRemoteViewsFactory( private val context: Context, intent: Intent ) : RemoteViewsService.RemoteViewsFactory { private lateinit var widgetItems: List<WidgetItem> private val appWidgetId: Int = intent.getIntExtra( AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID ) override fun onCreate() { // In onCreate(), set up any connections or cursors to your data source. // Heavy lifting, such as downloading or creating content, must be // deferred to onDataSetChanged() or getViewAt(). Taking more than 20 // seconds on this call results in an ANR. widgetItems = List(REMOTE_VIEW_COUNT) { index -> WidgetItem("$index!") } // ... } // ... override fun getViewAt(position: Int): RemoteViews { // Construct a remote views item based on the widget item XML file // and set the text based on the position. return RemoteViews(context.packageName, R.layout.widget_item).apply { setTextViewText(R.id.widget_item, widgetItems[position].text) // Set a fill-intent to fill in the pending intent template. // that is set on the collection view in StackWidgetProvider. val fillInIntent = Intent().apply { Bundle().also { extras -> extras.putInt(EXTRA_ITEM, position) putExtras(extras) } } // Make it possible to distinguish the individual on-click // action of a given item. setOnClickFillInIntent(R.id.widget_item, fillInIntent) // ... } } // ... }
الحفاظ على حداثة بيانات المجموعة
يوضّح الشكل 2 مسار التعديل في تطبيق مصغّر يستخدم المجموعات. ويوضّح كيفية تفاعل رمز التطبيق المصغّر مع RemoteViewsFactory وكيفية تفعيل التحديثات:
RemoteViewsFactory" أثناء التحديثاتيمكن أن توفّر التطبيقات المصغّرة التي تستخدم المجموعات محتوى محدّثًا للمستخدمين. على سبيل المثال، يمنح تطبيق Gmail المصغّر المستخدمين لقطة من البريد الوارد. لتحقيق ذلك، يمكنك تفعيل RemoteViewsFactory وعرض المجموعة لجلب البيانات الجديدة وعرضها.
لإجراء ذلك، استخدِم
AppWidgetManager للاتصال بالرقم
notifyAppWidgetViewDataChanged(). يؤدي هذا الطلب إلى معاودة الاتصال
بطريقة onDataSetChanged() لكائن RemoteViewsFactory،
مما يتيح لك جلب أي بيانات جديدة.
يمكنك إجراء عمليات تتطلّب معالجة مكثّفة بشكل متزامن ضمن دالة الاستدعاء onDataSetChanged(). يتم إكمال هذا الطلب قبل جلب البيانات الوصفية أو بيانات العرض من RemoteViewsFactory. يمكنك
أيضًا تنفيذ عمليات مكثّفة للمعالجة ضمن طريقة
getViewAt(). إذا استغرقت هذه المكالمة وقتًا طويلاً، يتم عرض طريقة عرض التحميل، التي تحدّدها طريقة getLoadingView() للكائن RemoteViewsFactory، في الموضع المقابل لطريقة عرض المجموعة إلى أن يتم عرضها.
استخدام RemoteCollectionItems لتمرير مجموعة مباشرةً
يضيف الإصدار 12 من نظام التشغيل Android (مستوى واجهة برمجة التطبيقات 31) الطريقة setRemoteAdapter(int viewId,
RemoteViews.RemoteCollectionItems
items) التي تتيح لتطبيقك تمرير مجموعة مباشرةً عند تعبئة عرض المجموعة. في حال ضبط المحوّل باستخدام هذه الطريقة، لن تحتاج إلى
تنفيذ RemoteViewsFactory ولن تحتاج إلى طلب
notifyAppWidgetViewDataChanged().
بالإضافة إلى تسهيل تعبئة المحوّل، يزيل هذا الأسلوب أيضًا وقت الاستجابة لتعبئة العناصر الجديدة عندما يتصفّح المستخدمون القائمة للكشف عن عنصر جديد. يُفضَّل استخدام هذه الطريقة لضبط المحوّل طالما أنّ مجموعة عناصر المجموعة صغيرة نسبيًا. ومع ذلك، على سبيل المثال، لا يعمل هذا النهج بشكل جيد إذا كانت مجموعتك تحتوي على العديد من Bitmaps التي يتم تمريرها إلى setImageViewBitmap.
إذا كانت المجموعة لا تستخدم مجموعة ثابتة من التنسيقات، أي إذا كانت بعض العناصر تظهر أحيانًا فقط، استخدِم setViewTypeCount لتحديد الحد الأقصى لعدد التنسيقات الفريدة التي يمكن أن تحتوي عليها المجموعة. يتيح ذلك إعادة استخدام المحوّل في جميع تحديثات التطبيق المصغّر.
في ما يلي مثال على كيفية تنفيذ مجموعات RemoteViews المبسّطة.
val itemLayouts = listOf( R.layout.item_type_1, R.layout.item_type_2, // ... ) remoteView.setRemoteAdapter( R.id.list_view, RemoteViews.RemoteCollectionItems.Builder() .addItem(/* id= */ ID_1, RemoteViews(context.packageName, R.layout.item_type_1)) .addItem(/* id= */ ID_2, RemoteViews(context.packageName, R.layout.item_type_2)) // ... .setViewTypeCount(itemLayouts.count()) .build() )