الگوهای برش

این سند جزئیاتی درباره نحوه استفاده از سازندگان الگو در Android Jetpack برای ساختن Slices ارائه می‌دهد.

تعریف الگوی Slice

برش‌ها بااستفاده از ListBuilder ساخته می‌شوند. ListBuilder به شما امکان می‌دهد انواع مختلفی از ردیف‌ها را که در فهرست نمایش داده می‌شوند اضافه کنید. این بخش هریک از این انواع ردیف و نحوه ساخت آن‌ها را شرح می‌دهد.

SliceAction

ابتدایی‌ترین عنصر الگوی «برش» SliceAction است. SliceAction حاوی برچسبی به‌همراه PendingIntent است و یکی از موارد زیر است:

  • دکمه نماد
  • کلید پیش‌فرض
  • کلید سفارشی (یک drawable با وضعیت روشن/خاموش)

SliceAction توسط سازندگان الگو که در ادامه این بخش توضیح داده شده است استفاده می‌شود. SliceAction می‌تواند حالت تصویر تعریف‌شده‌ای داشته باشد که تعیین می‌کند تصویر چگونه برای کنش ارائه شود:

  • ‫ICON_IMAGE: اندازه کوچک و قابل‌رنگ‌آمیزی
  • ‫SMALL_IMAGE: اندازه کوچک و غیرقابل‌رنگ‌آمیزی
  • ‫LARGE_IMAGE: بزرگ‌ترین اندازه و غیرقابل‌رنگ‌آمیزی

HeaderBuilder

در بیشتر موارد، باید بااستفاده از HeaderBuilder برای الگوی خود سرایند تنظیم کنید. سرصفحه می‌تواند از موارد زیر پشتیبانی کند:

  • عنوان
  • زیرنویس
  • زیرنویس خلاصه
  • اقدام اصلی

برخی‌از پیکربندی‌های نمونه سرصفحه در زیر نشان داده شده است. توجه داشته باشید که چارگوش‌های خاکستری مکان‌های احتمالی نماد و حاشیه داخلی را نشان می‌دهند:

پرداخت سرصفحه در سطوح مختلف

وقتی به «برش» نیاز باشد، سطح نمایش‌دهنده نحوه ارائه «برش» را تعیین می‌کند. توجه داشته باشید که پردازش ممکن است در سطوح میزبانی مختلف تاحدودی متفاوت باشد.

در قالب‌های کوچک‌تر، معمولاً فقط سرصفحه (درصورت وجود) نمایش داده می‌شود. اگر خلاصه‌ای برای سرصفحه مشخص کرده باشید، نوشتار خلاصه به‌جای نوشتار عنوان فرعی نشان داده می‌شود.

اگر سرصفحه‌ای در الگوی خود مشخص نکرده باشید، معمولاً اولین ردیف اضافه‌شده به ListBuilder به‌جای آن نمایش داده می‌شود.

نمونه HeaderBuilder - «برش» فهرست ساده با سرصفحه

کاتلین

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
            )
        }
    }

جاوا

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();
}

SliceActions در سرصفحه‌ها

سرصفحه‌های «برش» می‌توانند SliceActions را نیز نمایش دهند:

کاتلین

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)
    }
}

جاوا

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

می‌توانید بااستفاده از RowBuilder، ردیفی از محتوا بسازید. یک ردیف می‌تواند از هریک از موارد زیر پشتیبانی کند:

  • عنوان
  • زیرنویس
  • مورد شروع: SliceAction، نماد، یا مُهر زمان
  • موارد پایانی: SliceAction، نماد، یا مُهر زمان
  • اقدام اصلی

می‌توانید محتوای ردیف را به روش‌های مختلفی ترکیب کنید، مشروط به محدودیت‌های زیر:

  • موارد شروع در ردیف اول «برش» نشان داده نخواهد شد
  • موارد پایانی نمی‌توانند ترکیبی از اشیاء SliceAction و اشیاء Icon باشند
  • هر ردیف فقط می‌تواند یک مُهر زمان داشته باشد

ردیف‌های نمونه محتوا در تصاویر زیر نشان داده شده است. توجه داشته باشید که چارگوش‌های خاکستری مکان‌های احتمالی نماد و حاشیه داخلی را نشان می‌دهند:

نمونه RowBuilder - کلید Wi-Fi

نمونه زیر ردیفی با کنش اصلی و کلید پیش‌فرض را نشان می‌دهد.

کاتلین

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)
        }
    }
}

جاوا

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

می‌توانید بااستفاده از GridBuilder، شبکه‌ای از محتوا بسازید. جدول می‌تواند از انواع تصویر زیر پشتیبانی کند:

  • ‫ICON_IMAGE: اندازه کوچک و قابل‌رنگ‌آمیزی
  • ‫SMALL_IMAGE: اندازه کوچک و غیرقابل‌رنگ‌آمیزی
  • ‫LARGE_IMAGE: بزرگ‌ترین اندازه و غیرقابل‌رنگ‌آمیزی

سلول جدولی بااستفاده از CellBuilder ساخته می‌شود. هر سلول می‌تواند حداکثر دو خط نوشتار و یک تصویر داشته باشد. سلول نباید خالی باشد.

نمونه‌های جدول در تصاویر زیر نشان داده شده است:

نمونه GridRowBuilder - رستوران‌های اطراف

مثال زیر ردیف جدولی را نشان می‌دهد که حاوی تصویر و نوشتار است.

کاتلین

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
            }
        }
    }
}

جاوا

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، می‌توانید ردیفی ایجاد کنید که حاوی نوار پیشرفت یا محدوده ورودی، مانند لغزنده، باشد.

نمونه‌های پیشرفت و لغزنده در تصاویر زیر نشان داده شده است:

نمونه RangeBuilder - لغزنده

مثال زیر نشان می‌دهد که چگونه می‌توان بااستفاده از InputRangeBuilder، «برشی» ساخت که حاوی لغزنده میزان صدا باشد. برای ساختن ردیف پیشرفت، از addRange() استفاده کنید.

کاتلین

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

جاوا

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 «برش» خود فراخوانی کنید. این امر منجر به تماس دیگری با SliceProvider.onBindSlice() می‌شود که در آن می‌توانید «برش» را دوباره با محتوای جدید بسازید.

نمونه محتوای تأخیری - سواری تا محل کار

در ردیف «رفتن به محل کار» در زیر، فاصله تا محل کار به‌طور پویا تعیین می‌شود و ممکن است فوراً دردسترس نباشد. کد نمونه استفاده از زیرنویس null را به‌عنوان جای‌بان درحین بار شدن محتوا نشان می‌دهد:

کاتلین

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)
        }
    }
}

جاوا

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 را نشان می‌دهد:

اگر فهرست Wi-Fi طولانی است و پیمایش غیرفعال است، می‌توانید دکمه دیدن موارد بیشتر را اضافه کنید تا مطمئن شوید کاربران راهی برای دیدن همه موارد در فهرست دارند. می‌توانید این دکمه را بااستفاده از addSeeMoreAction() اضافه کنید، همان‌طور که در مثال زیر نشان داده شده است:

کاتلین

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

جاوا

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 ارسال می‌شود.

یا اگر می‌خواهید پیام یا ردیف سفارشی ارائه دهید، RowBuilder را اضافه کنید:

کاتلین

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"
            )
        }
    }

جاوا

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();
}

ردیف یا کنش اضافه‌شده ازطریق این روش فقط زمانی نمایش داده می‌شود که یکی از شرایط زیر برآورده شود:

  • ارائه‌دهنده «برش» شما پیمایش را در نما غیرفعال کرده است
  • همه ردیف‌هایتان را نمی‌توان در فضای دردسترس نمایش داد

ترکیب کردن الگوها

با ترکیب کردن چند نوع ردیف می‌توانید «برش» غنی و پویایی ایجاد کنید. برای مثال، یک «برش» می‌تواند شامل یک ردیف سرصفحه، یک شبکه با یک تصویر، و یک شبکه با دو سلول نوشتار باشد.

در اینجا یک «برش» با ردیف سرصفحه به‌همراه شبکه‌ای که شامل سه سلول است وجود دارد.