قالب های برش

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

قالب Slice خود را تعریف کنید

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

SliceAction

اساسی ترین عنصر یک قالب Slice یک SliceAction است. یک SliceAction حاوی یک برچسب به همراه PendingIntent است و یکی از موارد زیر است:

  • دکمه آیکون
  • تعویض پیش فرض
  • تغییر حالت سفارشی (قابل ترسیم با حالت روشن/خاموش)

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

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

HeaderBuilder

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

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

برخی از نمونه تنظیمات هدر در زیر نشان داده شده است. توجه داشته باشید که جعبه‌های خاکستری مکان‌های بالقوه نماد و پد را نشان می‌دهند:

رندر هدر در سطوح مختلف

هنگامی که یک Slice مورد نیاز است، سطح نمایشگر نحوه ارائه Slice را تعیین می کند. توجه داشته باشید که رندر ممکن است بین سطوح میزبان تا حدودی متفاوت باشد.

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

اگر سرصفحه ای در قالب خود تعیین نکرده اید، معمولاً اولین ردیف اضافه شده به 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 در هدرها

هدرهای Slice همچنین می توانند 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، نماد، یا مهر زمانی
  • اقدام اولیه

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

  • موارد شروع در ردیف اول یک Slice نشان داده نمی شوند
  • موارد پایانی نمی توانند ترکیبی از اشیاء 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 - Slider

مثال زیر نشان می دهد که چگونه می توان با استفاده از InputRangeBuilder یک Slice حاوی یک نوار لغزنده حجم ساخت. برای ساخت ردیف پیشرفت، از 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();
}

مطالب با تاخیر

شما باید یک Slice را در اسرع وقت از SliceProvider.onBindSlice() برگردانید. تماس‌های وقت‌گیر می‌توانند منجر به مشکلات نمایش مانند سوسو زدن و تغییر اندازه ناگهانی شوند.

اگر محتوای Slice دارید که نمی‌توانید به سرعت بارگیری کنید، می‌توانید Slice خود را با محتوای متغیرهایی بسازید و در سازنده به بارگیری محتوا توجه کنید. هنگامی که محتوا برای نمایش آماده شد، با استفاده از Slice URI خود getContentResolver().notifyChange(sliceUri, null) را فراخوانی کنید. این منجر به فراخوانی دیگری به SliceProvider.onBindSlice() می شود، جایی که می توانید Slice را دوباره با محتوای تازه بسازید.

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

در ردیف سوار شدن به محل کار زیر، فاصله تا محل کار به صورت پویا تعیین می شود و ممکن است فوراً در دسترس نباشد. کد مثال نشان می دهد که از یک زیرنویس تهی به عنوان مکان نگهدار در حین بارگیری محتوا استفاده می کند:

کاتلین

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

پیمایش غیرفعال را در Slice خود مدیریت کنید

سطحی که الگوی Slice شما را ارائه می‌کند ممکن است از پیمایش درون الگو پشتیبانی نکند. در این صورت ممکن است برخی از مطالب شما نمایش داده نشود.

به عنوان مثال، یک Slice را در نظر بگیرید که لیستی از شبکه های WiFi را نشان می دهد:

اگر لیست WiFi طولانی است، و اگر پیمایش غیرفعال است، می‌توانید دکمه See more را اضافه کنید تا مطمئن شوید که کاربران راهی برای دیدن همه موارد در لیست دارند. می توانید این دکمه را با استفاده از 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();
}

همانطور که در تصویر زیر نشان داده شده است:

با ضربه زدن روی See more ، 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();
}

سطر یا عملکرد اضافه شده از طریق این روش تنها زمانی نمایش داده می شود که یکی از شرایط زیر برآورده شود:

  • ارائه دهنده Slice شما پیمایش در نما را غیرفعال کرده است
  • همه ردیف های شما را نمی توان در فضای موجود نمایش داد

قالب ها را با هم ترکیب کنید

شما می توانید با ترکیب انواع سطر، یک Slice غنی ​​و پویا ایجاد کنید. به عنوان مثال، یک Slice می تواند شامل یک ردیف سرصفحه، یک شبکه با یک تصویر واحد و یک شبکه با دو خانه متن باشد.

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