نماذج الشرائح

يقدم هذا المستند تفاصيل حول كيفية استخدام أدوات إنشاء النماذج في Android Jetpack لإنشاء الشرائح

تحديد نموذج Slice

يتم إنشاء الشرائح باستخدام ListBuilder أداة إنشاء القوائم تسمح لك بإضافة أنواع مختلفة من الصفوف التي يتم عرضها في قائمة. هذا النمط كل نوع من أنواع الصفوف هذه وكيفية إنشائها.

تأثير التقطيع

العنصر الأساسي في قالب التقطيع هو SliceAction SliceAction يحتوي على تسمية مع PendingIntent وهي أحد التالي:

  • زر الرمز
  • مفتاح التبديل التلقائي
  • تبديل مخصّص (قابل للرسم مع حالة تفعيل/إيقاف)

يتم استخدام SliceAction من خلال أدوات إنشاء النماذج الموضحة في بقية مواد العرض هذه . يمكن أن يتضمّن SliceAction وضع صورة محدّدًا يحدّد كيفية الصورة التي سيتم عرضها للإجراء:

  • ICON_IMAGE: حجم صغير وقابل للتلوين
  • SMALL_IMAGE: حجم صغير وغير قابل للتلوين
  • LARGE_IMAGE: أكبر حجم وغير قابل للتلوين

أداة إنشاء العناوين

في معظم الحالات، يجب تعيين عنوان للنموذج باستخدام HeaderBuilder يمكن أن يتيح العنوان ما يلي:

  • العنوان
  • العنوان الفرعي
  • العنوان الفرعي للملخّص
  • الإجراء الأساسي

وفي ما يلي بعض أمثلة عمليات ضبط العناوين. لاحظ أن المربعات الرمادية تعرض المواقع المحتملة للرمز والمساحة المتروكة:

عرض العنوان على مساحات عرض مختلفة

عند الحاجة إلى قطعة، يحدد سطح العرض طريقة عرض شريحة. يُرجى العِلم أنّ العرض قد يختلف نوعًا ما بين مساحات العرض المضيفة.

وفي التنسيقات الأصغر، يتم عادةً عرض العنوان فقط، في حال توفّره. في حال حذف حددت ملخصًا للرأس، يتم عرض نص الملخص بدلاً من نص العنوان الفرعي.

إذا لم تكن قد حددت عنوانًا في القالب، فستتم إضافة الصف الأول إلى ويتم عادةً عرض ListBuilder بدلاً من ذلك.

مثال على HeaderBuilder - شريحة قائمة بسيطة بعنوان

Kotlin

fun createSliceWithHeader(sliceUri: Uri) =
    list(context, sliceUri, ListBuilder.INFINITY) {
        setAccentColor(0xff0F9D) // Specify color for tinting icons
        header {
            title = "Get a ride"
            subtitle = "Ride in 4 min"
            summary = "Work in 1 hour 45 min | Home in 12 min"
        }
        row {
            title = "Home"
            subtitle = "12 miles | 12 min | $9.00"
            addEndItem(
                IconCompat.createWithResource(context, R.drawable.ic_home),
                ListBuilder.ICON_IMAGE
            )
        }
    }

Java

public Slice createSliceWithHeader(Uri sliceUri) {
    if (getContext() == null) {
        return null;
    }

    // Construct the parent.
    ListBuilder listBuilder = new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY)
            .setAccentColor(0xff0F9D58) // Specify color for tinting icons.
            .setHeader( // Create the header and add to slice.
                    new HeaderBuilder()
                            .setTitle("Get a ride")
                            .setSubtitle("Ride in 4 min.")
                            .setSummary("Work in 1 hour 45 min | Home in 12 min.")
            ).addRow(new RowBuilder() // Add a row.
                    .setPrimaryAction(
                            createActivityAction()) // A slice always needs a SliceAction.
                    .setTitle("Home")
                    .setSubtitle("12 miles | 12 min | $9.00")
                    .addEndItem(IconCompat.createWithResource(getContext(), R.drawable.ic_home),
                            SliceHints.ICON_IMAGE)
            ); // Add more rows if needed...
    return listBuilder.build();
}

شرائح الإجراءات في العناوين

يمكن أن تعرض عناوين الشرائح أيضًا إجراءات الشرائح:

Kotlin

fun createSliceWithActionInHeader(sliceUri: Uri): Slice {
    // Construct our slice actions.
    val noteAction = SliceAction.create(
        takeNoteIntent,
        IconCompat.createWithResource(context, R.drawable.ic_pencil),
        ICON_IMAGE,
        "Take note"
    )

    val voiceNoteAction = SliceAction.create(
        voiceNoteIntent,
        IconCompat.createWithResource(context, R.drawable.ic_mic),
        ICON_IMAGE,
        "Take voice note"
    )

    val cameraNoteAction = SliceAction.create(
        cameraNoteIntent,
        IconCompat.createWithResource(context, R.drawable.ic_camera),
        ICON_IMAGE,
        "Create photo note"
    )

    // Construct the list.
    return list(context, sliceUri, ListBuilder.INFINITY) {
        setAccentColor(0xfff4b4) // Specify color for tinting icons
        header {
            title = "Create new note"
            subtitle = "Easily done with this note taking app"
        }
        addAction(noteAction)
        addAction(voiceNoteAction)
        addAction(cameraNoteAction)
    }
}

Java

public Slice createSliceWithActionInHeader(Uri sliceUri) {
    if (getContext() == null) {
        return null;
    }
    // Construct our slice actions.
    SliceAction noteAction = SliceAction.create(takeNoteIntent,
            IconCompat.createWithResource(getContext(), R.drawable.ic_pencil),
            ListBuilder.ICON_IMAGE, "Take note");

    SliceAction voiceNoteAction = SliceAction.create(voiceNoteIntent,
            IconCompat.createWithResource(getContext(), R.drawable.ic_mic),
            ListBuilder.ICON_IMAGE,
            "Take voice note");

    SliceAction cameraNoteAction = SliceAction.create(cameraNoteIntent,
            IconCompat.createWithResource(getContext(), R.drawable.ic_camera),
            ListBuilder.ICON_IMAGE,
            "Create photo note");


    // Construct the list.
    ListBuilder listBuilder = new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY)
            .setAccentColor(0xfff4b400) // Specify color for tinting icons
            .setHeader(new HeaderBuilder() // Construct the header.
                    .setTitle("Create new note")
                    .setSubtitle("Easily done with this note taking app")
            )
            .addRow(new RowBuilder()
                    .setTitle("Enter app")
                    .setPrimaryAction(createActivityAction())
            )
            // Add the actions to the ListBuilder.
            .addAction(noteAction)
            .addAction(voiceNoteAction)
            .addAction(cameraNoteAction);
    return listBuilder.build();
}

مصمم الصفوف

يمكنك إنشاء صف من المحتوى باستخدام RowBuilder صف A يمكن أن تدعم أيًا مما يلي:

  • العنوان
  • العنوان الفرعي
  • عنصر البداية: SliceAction أو رمز أو طابع زمني
  • عناصر النهاية: SliceAction أو رمز أو طابع زمني
  • الإجراء الأساسي

يمكنك دمج محتوى الصف بعدة طرق، وذلك وفقًا لما يلي: القيود:

  • لن تظهر عناصر البدء في الصف الأول من الشريحة.
  • لا يمكن أن تشمل عناصر النهاية مزيجًا من SliceAction عنصر وIcon.
  • يمكن أن يحتوي الصف على طابع زمني واحد فقط

تظهر أمثلة صفوف المحتوى في الصور التالية. لاحظ أن المربعات الرمادية إظهار المواقع المحتملة للرمز والمساحة المتروكة:

مثال على مصمم الصفوف - تبديل Wi-Fi

يوضِّح المثال أدناه صفًا يتضمّن إجراءً أساسيًا ومفتاح تبديل تلقائي.

Kotlin

fun createActionWithActionInRow(sliceUri: Uri): Slice {
    // Primary action - open wifi settings.
    val wifiAction = SliceAction.create(
        wifiSettingsPendingIntent,
        IconCompat.createWithResource(context, R.drawable.ic_wifi),
        ICON_IMAGE,
        "Wi-Fi Settings"
    )

    // Toggle action - toggle wifi.
    val toggleAction = SliceAction.createToggle(
        wifiTogglePendingIntent,
        "Toggle Wi-Fi",
        isConnected /* isChecked */
    )

    // Create the parent builder.
    return list(context, wifiUri, ListBuilder.INFINITY) {
        setAccentColor(0xff4285) // Specify color for tinting icons / controls.
        row {
            title = "Wi-Fi"
            primaryAction = wifiAction
            addEndItem(toggleAction)
        }
    }
}

Java

public Slice createActionWithActionInRow(Uri sliceUri) {
    if (getContext() == null) {
        return null;
    }
    // Primary action - open wifi settings.
    SliceAction primaryAction = SliceAction.create(wifiSettingsPendingIntent,
            IconCompat.createWithResource(getContext(), R.drawable.ic_wifi),
            ListBuilder.ICON_IMAGE,
            "Wi-Fi Settings"
    );

    // Toggle action - toggle wifi.
    SliceAction toggleAction = SliceAction.createToggle(wifiTogglePendingIntent,
            "Toggle Wi-Fi", isConnected /* isChecked */);

    // Create the parent builder.
    ListBuilder listBuilder = new ListBuilder(getContext(), wifiUri, ListBuilder.INFINITY)
            // Specify color for tinting icons / controls.
            .setAccentColor(0xff4285f4)
            // Create and add a row.
            .addRow(new RowBuilder()
                    .setTitle("Wi-Fi")
                    .setPrimaryAction(primaryAction)
                    .addEndItem(toggleAction));
    // Build the slice.
    return listBuilder.build();
}

مصمم الشبكة

يمكنك إنشاء شبكة محتوى باستخدام GridBuilder يمكن للشبكة إتاحة أنواع الصور التالية:

  • ICON_IMAGE: حجم صغير وقابل للتلوين
  • SMALL_IMAGE: حجم صغير وغير قابل للتلوين
  • LARGE_IMAGE: أكبر حجم وغير قابل للتلوين

يتم إنشاء خلية شبكة باستخدام CellBuilder حاسمة يمكن أن تدعم الخلية ما يصل إلى سطرين من النص وصورة واحدة. لا يمكن أن تكون الخلية فارغة.

يتم عرض أمثلة الشبكة في الصور التالية:

مثال على GridRowBuilder - المطاعم المجاورة

يوضح المثال أدناه صف شبكة يحتوي على صور ونصوص.

Kotlin

fun createSliceWithGridRow(sliceUri: Uri): Slice {
    // Create the parent builder.
    return list(context, sliceUri, ListBuilder.INFINITY) {
        header {
            title = "Famous restaurants"
            primaryAction = SliceAction.create(
                pendingIntent, icon, ListBuilder.ICON_IMAGE, "Famous restaurants"
            )
        }
        gridRow {
            cell {
                addImage(image1, LARGE_IMAGE)
                addTitleText("Top Restaurant")
                addText("0.3 mil")
                contentIntent = intent1
            }
            cell {
                addImage(image2, LARGE_IMAGE)
                addTitleText("Fast and Casual")
                addText("0.5 mil")
                contentIntent = intent2
            }
            cell {
                addImage(image3, LARGE_IMAGE)
                addTitleText("Casual Diner")
                addText("0.9 mi")
                contentIntent = intent3
            }
            cell {
                addImage(image4, LARGE_IMAGE)
                addTitleText("Ramen Spot")
                addText("1.2 mi")
                contentIntent = intent4
            }
        }
    }
}

Java

public Slice createSliceWithGridRow(Uri sliceUri) {
      if (getContext() == null) {
          return null;
      }
      // Create the parent builder.
      ListBuilder listBuilder = new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY)
              .setHeader(
                      // Create the header.
                      new HeaderBuilder()
                              .setTitle("Famous restaurants")
                              .setPrimaryAction(SliceAction
                                      .create(pendingIntent, icon, ListBuilder.ICON_IMAGE,
                                              "Famous restaurants"))
              )
              // Add a grid row to the list.
              .addGridRow(new GridRowBuilder()
                      // Add cells to the grid row.
                      .addCell(new CellBuilder()
                              .addImage(image1, ListBuilder.LARGE_IMAGE)
                              .addTitleText("Top Restaurant")
                              .addText("0.3 mil")
                              .setContentIntent(intent1)
                      ).addCell(new CellBuilder()
                              .addImage(image2, ListBuilder.LARGE_IMAGE)
                              .addTitleText("Fast and Casual")
                              .addText("0.5 mil")
                              .setContentIntent(intent2)
                      )
                      .addCell(new CellBuilder()
                              .addImage(image3, ListBuilder.LARGE_IMAGE)
                              .addTitleText("Casual Diner")
                              .addText("0.9 mi")
                              .setContentIntent(intent3))
                      .addCell(new CellBuilder()
                              .addImage(image4, ListBuilder.LARGE_IMAGE)
                              .addTitleText("Ramen Spot")
                              .addText("1.2 mi")
                              .setContentIntent(intent4))
                      // Every slice needs a primary action.
                      .setPrimaryAction(createActivityAction())
              );
      return listBuilder.build();
  }

جهاز بناء النطاقات

مع RangeBuilder، يمكنك إنشاء صف يحتوي إما على شريط تقدم أو نطاق إدخال، مثل كشريط تمرير.

يتم عرض أمثلة التقدم وشريط التمرير في الصور التالية:

مثال على RangeBuilder - شريط التمرير

يوضح المثال أدناه كيفية إنشاء شريحة تحتوي على حجم شريط التمرير باستخدام InputRangeBuilder. لإنشاء صف مستوى تقدّم، استخدِم addRange()

Kotlin

fun createSliceWithRange(sliceUri: Uri): Slice {
    return list(context, sliceUri, ListBuilder.INFINITY) {
        inputRange {
            title = "Ring Volume"
            inputAction = volumeChangedPendingIntent
            max = 100
            value = 30
        }
    }
}

Java

public Slice createSliceWithRange(Uri sliceUri) {
    if (getContext() == null) {
        return null;
    }
    // Construct the parent.
    ListBuilder listBuilder = new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY)
            .addRow(new RowBuilder() // Every slice needs a row.
                    .setTitle("Enter app")
                      // Every slice needs a primary action.
                    .setPrimaryAction(createActivityAction())
            )
            .addInputRange(new InputRangeBuilder() // Create the input row.
                    .setTitle("Ring Volume")
                    .setInputAction(volumeChangedPendingIntent)
                    .setMax(100)
                    .setValue(30)
            );
    return listBuilder.build();
}

محتوى متأخر

يجب عليك إرجاع شريحة في أسرع وقت ممكن من SliceProvider.onBindSlice() قد تؤدي المكالمات التي تستغرق وقتًا طويلاً إلى حدوث مشاكل في العرض، مثل الوميض أو المفاجئة. وتغيير الحجم.

إذا كان لديك محتوى "شرائح" لا يمكن تحميله بسرعة، يمكنك إنشاء يمكنك التقسيم باستخدام محتوى العنصر النائب مع ملاحظة في أداة الإنشاء أن جارٍ تحميل المحتوى عندما يصبح المحتوى جاهزًا للعرض، اتصل getContentResolver().notifyChange(sliceUri, null) باستخدام معرّف الموارد المنتظم (URI) الخاص بتطبيق Slice. وينتج عن ذلك استدعاء آخر SliceProvider.onBindSlice()، حيث يمكنك إنشاء الشريحة مجددًا باستخدام وصفات جديدة المحتوى.

مثال على محتوى متأخر - الانطلاق إلى العمل

في صف "الركوب إلى العمل" أدناه، يتم تحديد المسافة إلى العمل ديناميكيًا وقد لا تكون متاحة على الفور. يوضح مثال التعليمة البرمجية استخدام عنوان فرعي فارغ كعنصر نائب أثناء تحميل المحتوى:

Kotlin

fun createSliceShowingLoading(sliceUri: Uri): Slice {
    // We’re waiting to load the time to work so indicate that on the slice by
    // setting the subtitle with the overloaded method and indicate true.
    return list(context, sliceUri, ListBuilder.INFINITY) {
        row {
            title = "Ride to work"
            setSubtitle(null, true)
            addEndItem(IconCompat.createWithResource(context, R.drawable.ic_work), ICON_IMAGE)
        }
    }
}

Java

public Slice createSliceShowingLoading(Uri sliceUri) {
    if (getContext() == null) {
        return null;
    }
    // Construct the parent.
    ListBuilder listBuilder = new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY)
            // Construct the row.
            .addRow(new RowBuilder()
                    .setPrimaryAction(createActivityAction())
                    .setTitle("Ride to work")
                    // We’re waiting to load the time to work so indicate that on the slice by
                    // setting the subtitle with the overloaded method and indicate true.
                    .setSubtitle(null, true)
                    .addEndItem(IconCompat.createWithResource(getContext(), R.drawable.ic_work),
                            ListBuilder.ICON_IMAGE)
            );
    return listBuilder.build();
}

private SliceAction createActivityAction() {
    return SliceAction.create(
            PendingIntent.getActivity(
                    getContext(),
                    0,
                    new Intent(getContext(), MainActivity.class),
                    0
            ),
            IconCompat.createWithResource(getContext(), R.drawable.ic_home),
            ListBuilder.ICON_IMAGE,
            "Enter app"
    );
}

التعامل مع المشكلة التي أدت إلى إيقاف التمرير في الشريحة

قد لا يتيح السطح الذي يعرض نموذج "الشرائح" إمكانية الانتقال للأسفل أو للأعلى. القالب. وفي هذه الحالة، قد لا يتم عرض بعض المحتوى الخاص بك.

كمثال، ضع في الاعتبار شريحة تعرض قائمة بشبكات Wi-Fi:

إذا كانت قائمة WiFi طويلة، وإذا تم تعطيل التمرير، يمكنك إضافة عرض المزيد لضمان إتاحة طريقة للمستخدمين للاطّلاع على جميع العناصر في الحالية. يمكنك إضافة هذا الزر باستخدام addSeeMoreAction()، كما هو موضح في المثال التالي:

Kotlin

fun seeMoreActionSlice(sliceUri: Uri) =
    list(context, sliceUri, ListBuilder.INFINITY) {
        // [START_EXCLUDE]
        // [END_EXCLUDE]
        setSeeMoreAction(seeAllNetworksPendingIntent)
        // [START_EXCLUDE]
        // [END_EXCLUDE]
    }

Java

public Slice seeMoreActionSlice(Uri sliceUri) {
    if (getContext() == null) {
        return null;
    }
    ListBuilder listBuilder = new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY);
    // [START_EXCLUDE]
    listBuilder.addRow(new RowBuilder()
            .setTitle("Hello")
            .setPrimaryAction(createActivityAction())
    );
    // [END_EXCLUDE]
    listBuilder.setSeeMoreAction(seeAllNetworksPendingIntent);
    // [START_EXCLUDE]
    // [END_EXCLUDE]
    return listBuilder.build();
}

يظهر هذا كما هو موضح في الصورة التالية:

يؤدي النقر على عرض المزيد إلى إرسال seeAllNetworksPendingIntent.

بدلاً من ذلك، إذا كنت تريد توفير صف أو رسالة مخصّصة، يمكنك إضافة مصمم الصفوف:

Kotlin

fun seeMoreRowSlice(sliceUri: Uri) =
    list(context, sliceUri, ListBuilder.INFINITY) {
        // [START_EXCLUDE]
        // [END_EXCLUDE]
        seeMoreRow {
            title = "See all available networks"
            addEndItem(
                IconCompat.createWithResource(context, R.drawable.ic_right_caret), ICON_IMAGE
            )
            primaryAction = SliceAction.create(
                seeAllNetworksPendingIntent,
                IconCompat.createWithResource(context, R.drawable.ic_wifi),
                ListBuilder.ICON_IMAGE,
                "Wi-Fi Networks"
            )
        }
    }

Java

public Slice seeMoreRowSlice(Uri sliceUri) {
    if (getContext() == null) {
        return null;
    }
    ListBuilder listBuilder = new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY)
            // [START_EXCLUDE]
            .addRow(new RowBuilder()
                    .setTitle("Hello")
                    .setPrimaryAction(createActivityAction())
            )
            // [END_EXCLUDE]
            .setSeeMoreRow(new RowBuilder()
                    .setTitle("See all available networks")
                    .addEndItem(IconCompat
                                    .createWithResource(getContext(), R.drawable
                                            .ic_right_caret),
                            ListBuilder.ICON_IMAGE)
                    .setPrimaryAction(SliceAction.create(seeAllNetworksPendingIntent,
                            IconCompat.createWithResource(getContext(), R.drawable.ic_wifi),
                            ListBuilder.ICON_IMAGE,
                            "Wi-Fi Networks"))
            );
    // [START_EXCLUDE]
    // [END_EXCLUDE]
    return listBuilder.build();
}

لا يتم عرض الصف أو الإجراء المضاف بهذه الطريقة إلا عند وجود أحد الشروط التالية تحقق:

  • أوقف مقدّم الشريحة الخاصة بك إمكانية التنقّل في العرض.
  • لا يمكن عرض جميع صفوفك في المساحة المتاحة.

دمج النماذج

يمكنك إنشاء شريحة غنية وديناميكية من خلال الجمع بين أنواع صفوف متعدّدة. بالنسبة على سبيل المثال، يمكن أن تحتوي الشريحة على صف عنوان وشبكة بها صورة واحدة شبكة بها خليتين من النص.

إليك شريحة تحتوي على صف عنوان مع شبكة تحتوي على ثلاث خلايا.