เทมเพลต Slice

เอกสารนี้มีรายละเอียดเกี่ยวกับวิธีใช้เครื่องมือสร้างเทมเพลตใน Android Jetpack เพื่อสร้าง Slices

กำหนดเทมเพลต Slice

Slice สร้างขึ้นโดยใช้ ListBuilder ตัวสร้างรายการ ให้คุณเพิ่มแถวประเภทต่างๆ ที่แสดงในรายการได้ ช่วงเวลานี้ จะอธิบายแถวแต่ละประเภทและวิธีสร้างแถวเหล่านั้น

SliceAction

องค์ประกอบพื้นฐานที่สุดของเทมเพลต Slice คือ SliceAction SliceAction มีป้ายกำกับพร้อมด้วย PendingIntent และเป็นหนึ่งใน ดังต่อไปนี้:

  • ปุ่มไอคอน
  • ปุ่มสลับเริ่มต้น
  • ปุ่มสลับที่กำหนดเอง (ถอนออกได้ที่มีสถานะเปิด/ปิด)

เครื่องมือสร้างเทมเพลตจะใช้ SliceAction ตามที่อธิบายในส่วนที่เหลือของกระบวนการนี้ SliceAction สามารถกำหนดโหมดรูปภาพซึ่งจะกำหนดวิธี รูปภาพจะปรากฏสำหรับการดำเนินการ:

  • ICON_IMAGE: ขนาดจิ๋วและสีจางได้
  • SMALL_IMAGE: มีขนาดเล็กและใช้งานไม่ได้
  • LARGE_IMAGE: ใหญ่ที่สุดและเก็บไม่ได้

ตัวสร้างส่วนหัว

ในกรณีส่วนใหญ่ คุณควรตั้งค่าส่วนหัวสำหรับเทมเพลตโดยใช้ HeaderBuilder ส่วนหัวสามารถรองรับสิ่งต่างๆ ต่อไปนี้

  • ชื่อ
  • ชื่อรอง
  • คำบรรยายสรุป
  • การทำงานหลัก

ตัวอย่างการกำหนดค่าส่วนหัวมีดังนี้ โปรดทราบว่าช่องสีเทาจะแสดง ตำแหน่งไอคอนและระยะห่างจากขอบที่เป็นไปได้:

การแสดงผลส่วนหัวในแพลตฟอร์มต่างๆ

เมื่อต้องใช้สไลซ์ พื้นที่แสดงจะกำหนดวิธีแสดงผล ส่วนแบ่ง โปรดทราบว่าการแสดงผลอาจแตกต่างกันไปในแต่ละแพลตฟอร์มโฮสติ้ง

ในรูปแบบที่เล็กลง โดยปกติแล้วจะแสดงเฉพาะส่วนหัวเท่านั้น หากมี ถ้า คุณได้ระบุสรุปสำหรับส่วนหัว ข้อความสรุปจะแสดงแทนที่ ข้อความคำบรรยาย

ถ้าคุณไม่ได้ระบุส่วนหัวในเทมเพลต แถวแรกที่เพิ่มลงใน โดยปกติแล้วระบบจะแสดง ListBuilder แทน

ตัวอย่าง HeaderBuilder - ส่วนแบ่งรายการแบบง่ายที่มีส่วนหัว

KotlinJava
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 ด้วย:

KotlinJava
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 แถว สามารถรองรับการดำเนินการต่อไปนี้

  • ชื่อ
  • ชื่อรอง
  • รายการเริ่มต้น: SliceAction, ไอคอน หรือการประทับเวลา
  • รายการที่สิ้นสุด: SliceAction, ไอคอน หรือการประทับเวลา
  • การทำงานหลัก

คุณรวมเนื้อหาแถวได้หลายวิธี โดยขึ้นอยู่กับสิ่งต่อไปนี้ ข้อจำกัด:

  • รายการเริ่มต้นจะไม่แสดงในแถวแรกของ Slice
  • รายการสิ้นสุดต้องใช้ร่วมกับออบเจ็กต์ SliceAction รายการและออบเจ็กต์ Icon รายการไม่ได้
  • แถวหนึ่งมีการประทับเวลาได้เพียงรายการเดียว

ตัวอย่างแถวเนื้อหาจะแสดงในรูปภาพต่อไปนี้ โปรดทราบว่าช่องสีเทา แสดงตำแหน่งไอคอนและระยะห่างจากขอบที่เป็นไปได้:

ตัวอย่าง RowBuilder - สลับ Wi-Fi

ตัวอย่างด้านล่างแสดงแถวที่มีการดำเนินการหลักและปุ่มสลับเริ่มต้น

KotlinJava
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 กระป๋องตารางกริด รองรับรูปภาพประเภทต่อไปนี้

  • ICON_IMAGE: ขนาดจิ๋วและสีจางได้
  • SMALL_IMAGE: มีขนาดเล็กและใช้งานไม่ได้
  • LARGE_IMAGE: ใหญ่ที่สุดและเก็บไม่ได้

เซลล์ตารางกริดสร้างขึ้นโดยใช้ CellBuilder ต เซลล์สามารถรองรับข้อความได้สูงสุด 2 บรรทัดและรูปภาพ 1 รูป ต้องระบุเซลล์

ตัวอย่างตารางกริดดังในรูปภาพต่อไปนี้

ตัวอย่าง GridRowBuilder - ร้านอาหารใกล้เคียง

ตัวอย่างด้านล่างแสดงแถวตารางกริดที่มีรูปภาพและข้อความ

KotlinJava
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()

KotlinJava
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() การโทรที่ใช้เวลามากอาจทำให้เกิดปัญหาในการแสดงผล เช่น ภาพกะพริบหรือปรากฏขึ้นอย่างฉับพลัน การปรับขนาด

หากคุณมีเนื้อหา Slice ที่ไม่สามารถโหลดได้อย่างรวดเร็ว คุณสามารถสร้าง ส่วนแบ่งกับเนื้อหาตัวยึดตำแหน่งขณะระบุในเครื่องมือสร้างว่า กำลังโหลดเนื้อหา เมื่อเนื้อหาพร้อมที่จะแสดง ให้โทร getContentResolver().notifyChange(sliceUri, null) โดยใช้ URI ของ Slice ซึ่งส่งผลให้มีการเรียก SliceProvider.onBindSlice() ซึ่งคุณสามารถสร้าง Slice อีกครั้งได้ด้วย เนื้อหา

ตัวอย่างเนื้อหาล่าช้า - รถไปทำงาน

ในแถว "นั่งไปทำงาน" ด้านล่าง ระยะทางไปที่ทำงานจะกำหนดแบบไดนามิก และอาจไม่พร้อมใช้งานในทันที โค้ดตัวอย่างสาธิตการใช้ ชื่อรองที่เป็นค่าว่างเป็นตัวยึดตำแหน่งขณะที่เนื้อหาโหลด:

KotlinJava
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 ของคุณอาจไม่รองรับการเลื่อนภายใน เทมเพลต ในกรณีนี้ เนื้อหาบางส่วนของคุณอาจไม่แสดง

ตัวอย่างเช่น ลองพิจารณาส่วนแบ่งที่แสดงรายการเครือข่าย Wi-Fi ดังนี้

หากรายการ Wi-Fi ยาวเกินไป และหากการเลื่อนถูกปิดใช้งาน คุณสามารถเพิ่ม ปุ่มดูเพิ่มเติมเพื่อให้ผู้ใช้สามารถดูรายการทั้งหมดใน รายการ คุณสามารถเพิ่มปุ่มนี้โดยใช้ addSeeMoreAction() ดังที่ปรากฏในตัวอย่างต่อไปนี้

KotlinJava
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

หรือถ้าต้องการระบุข้อความหรือแถวที่กำหนดเอง ให้พิจารณาเพิ่ม ตัวสร้างแถว:

KotlinJava
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 อาจมีแถวส่วนหัว ตารางกริดที่มีรูปภาพเดียว และ ตารางกริดที่มีข้อความ 2 เซลล์

นี่คือสไลซ์ที่มีแถวส่วนหัวพร้อมด้วยตารางกริดที่มี 3 เซลล์