Tài liệu này cung cấp chi tiết về cách sử dụng trình tạo mẫu trong Android Jetpack để tạo Lát cắt.
Xác định mẫu Lát cắt
Lát cắt được tạo bằng cách sử dụng
ListBuilder
. Trình tạo danh sách
cho phép bạn thêm các loại hàng khác nhau được hiển thị trong danh sách. Chiến dịch này
mô tả từng loại hàng trong số đó và cách chúng được tạo.
Hành động cắt
Phần tử cơ bản nhất của mẫu Lát cắt là
SliceAction
. Một SliceAction
chứa nhãn cùng với
PendingIntent
và là một trong những
sau:
- Nút biểu tượng
- Bật/tắt mặc định
- Nút bật/tắt tuỳ chỉnh (một đối tượng có thể vẽ có trạng thái bật/tắt)
SliceAction
được các trình tạo mẫu mô tả trong phần còn lại của tài liệu này sử dụng
. SliceAction
có thể có chế độ hình ảnh được xác định để xác định cách
hình ảnh cho thao tác:
ICON_IMAGE
: kích thước nhỏ và có thể phủ màuSMALL_IMAGE
: kích thước nhỏ và không phủ màuLARGE_IMAGE
: kích thước lớn nhất và không phủ màu
Trình tạo tiêu đề
Trong hầu hết các trường hợp, bạn nên đặt tiêu đề cho mẫu bằng cách sử dụng
HeaderBuilder
.
Tiêu đề có thể hỗ trợ những nội dung sau:
- Tiêu đề
- Phụ đề
- Phụ đề của phần tóm tắt
- Tác vụ chính
Dưới đây là một số ví dụ về cấu hình tiêu đề. Lưu ý rằng hộp màu xám hiển thị vị trí biểu tượng và khoảng đệm tiềm năng:
Hiển thị tiêu đề trên nhiều nền tảng
Khi cần một Lát cắt, giao diện hiển thị sẽ xác định cách kết xuất Lát cắt. Lưu ý rằng việc hiển thị có thể khác nhau đôi chút giữa các nền tảng lưu trữ.
Ở các định dạng nhỏ hơn, thường chỉ có tiêu đề được hiển thị, nếu có. Nếu bạn đã chỉ định nội dung tóm tắt cho tiêu đề, thì văn bản tóm tắt sẽ được hiển thị thay vì văn bản phụ đề.
Nếu bạn chưa chỉ định tiêu đề trong mẫu, hàng đầu tiên sẽ được thêm vào
ListBuilder
thường được hiển thị thay thế.
Ví dụ về HeaderBuilder – Lát cắt danh sách đơn giản có tiêu đề
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(); }
SliceAction trong tiêu đề
Tiêu đề của Lát cắt cũng có thể hiển thị SliceActions:
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(); }
Trình tạo hàng
Bạn có thể xây dựng một hàng nội dung bằng cách sử dụng
RowBuilder
. Một hàng
có thể hỗ trợ bất kỳ nội dung nào sau đây:
- Tiêu đề
- Phụ đề
- Mục bắt đầu: SliceAction, Biểu tượng hoặc dấu thời gian
- Mục kết thúc: SliceAction, Biểu tượng hoặc dấu thời gian
- Tác vụ chính
Bạn có thể kết hợp nội dung hàng theo một số cách, tuỳ thuộc vào hạn chế:
- Các mục bắt đầu sẽ không xuất hiện ở hàng đầu tiên của Lát cắt
- Mục cuối không được kết hợp đối tượng
SliceAction
và đối tượngIcon
- Một hàng chỉ có thể chứa một dấu thời gian
Các hàng nội dung mẫu sẽ xuất hiện trong các hình ảnh sau. Lưu ý rằng hộp màu xám hiển thị vị trí biểu tượng và khoảng đệm tiềm năng:
Ví dụ về RowBuilder – Bật/tắt Wi-Fi
Ví dụ bên dưới minh hoạ một hàng có thao tác chính và nút bật/tắt mặc định.
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(); }
Trình tạo lưới
Bạn có thể xây dựng một lưới nội dung bằng cách sử dụng
GridBuilder
. Một lưới có thể
hỗ trợ các loại hình ảnh sau:
ICON_IMAGE
: kích thước nhỏ và có thể phủ màuSMALL_IMAGE
: kích thước nhỏ và không phủ màuLARGE_IMAGE
: kích thước lớn nhất và không phủ màu
Một ô lưới được xây dựng bằng cách sử dụng
CellBuilder
. Đáp
ô có thể hỗ trợ tối đa hai dòng văn bản và một hình ảnh. Không được để trống ô.
Ví dụ về lưới được thể hiện trong các hình sau:
Ví dụ về GridRowBuilder – Nhà hàng lân cận
Ví dụ bên dưới minh hoạ một hàng lưới chứa hình ảnh và văn bản.
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(); }
Trình tạo phạm vi
Có
RangeBuilder
!
bạn có thể tạo một hàng chứa thanh tiến trình hoặc dải ô nhập, chẳng hạn như
làm thanh trượt.
Ví dụ về tiến trình và thanh trượt được thể hiện trong các hình sau:
Ví dụ về RangeBuilder – Thanh trượt
Ví dụ bên dưới minh hoạ cách tạo một Lát cắt chứa một ổ đĩa
thanh trượt bằng cách sử dụng InputRangeBuilder
. Để tạo một hàng tiến trình, hãy sử dụng
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(); }
Nội dung bị trễ
Bạn nên trả về một Lát cắt nhanh nhất có thể từ
SliceProvider.onBindSlice()
.
Cuộc gọi tốn thời gian có thể dẫn đến các sự cố hiển thị, chẳng hạn như nhấp nháy và đột ngột
đổi kích thước.
Nếu nội dung Lát cắt không thể tải nhanh chóng, bạn có thể tạo
Lát cắt với nội dung giữ chỗ trong khi lưu ý trong trình tạo rằng
đang tải nội dung. Khi nội dung đã sẵn sàng để hiển thị, hãy gọi
getContentResolver().notifyChange(sliceUri, null)
bằng cách sử dụng URI Lát cắt của bạn. Điều này dẫn đến một cuộc gọi khác tới
SliceProvider.onBindSlice()
, nơi bạn có thể tạo lại Lát cắt bằng
nội dung.
Ví dụ về nội dung bị trễ – Đi đến cơ quan
Trong hàng Đi đến nơi làm việc bên dưới, khoảng cách đến cơ quan được xác định tự động và có thể chưa dùng được ngay. Mã ví dụ minh hoạ việc sử dụng làm tiêu đề phụ rỗng trong khi tải nội dung:
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" ); }
Xử lý thao tác cuộn bị vô hiệu hoá trong Lát cắt của bạn
Nền tảng thể hiện mẫu Lát cắt có thể không hỗ trợ cuộn trong mẫu. Trong trường hợp này, một số nội dung của bạn có thể không hiển thị.
Ví dụ: hãy xem xét một Lát cắt hiển thị danh sách các mạng Wi-Fi:
Nếu danh sách Wi-Fi dài và nếu tính năng cuộn bị tắt, bạn có thể thêm
Nút Xem thêm nhằm đảm bảo rằng người dùng có thể xem tất cả các mục trong
danh sách. Bạn có thể thêm nút này bằng cách sử dụng
addSeeMoreAction()
!
như trong ví dụ sau:
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(); }
Thao tác này sẽ hiển thị như trong hình ảnh sau đây:
Thao tác nhấn vào Xem thêm sẽ gửi seeAllNetworksPendingIntent
.
Ngoài ra, nếu bạn muốn cung cấp một hàng hoặc thông điệp tuỳ chỉnh, hãy cân nhắc việc thêm một Trình tạo hàng:
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(); }
Hàng hoặc hành động được thêm thông qua phương pháp này chỉ hiển thị khi một trong các điều kiện sau được đáp ứng:
- Người trình bày trong Lát cắt của bạn đã tắt tính năng cuộn trên khung hiển thị
- Không phải tất cả hàng của bạn đều có thể hiển thị trong không gian có sẵn
Kết hợp các mẫu
Bạn có thể tạo một Lát cắt động và phong phú bằng cách kết hợp nhiều loại hàng. Cho Ví dụ: Lát cắt có thể chứa hàng tiêu đề, lưới chứa một hình ảnh và một lưới gồm hai ô văn bản.
Đây là một Lát cắt có hàng tiêu đề cùng với một lưới chứa 3 ô.