An Interest In:
Web News this Week
- September 9, 2024
- September 8, 2024
- September 7, 2024
- September 6, 2024
- September 5, 2024
- September 4, 2024
- September 3, 2024
Code Your First Android Slice and Keep Users Engaged
The hard work isn’t over just because your app has racked up a ton of downloads and positive reviews on the Google Play store. Your typical mobile user has dozens of apps installed on their device, and with new apps being released all the time, you’ll need to work hard to hold your audience’s interest!
Keeping users coming back to your app is crucial to creating a stable, loyal user base. Plus, if you've monetized your app, then the amount of time people spend in your application directly affects how much money you make—think of every additional second as another opportunity to display an advert or tempt the user into splashing out on an in-app purchase!
At this year’s I/O, Google introduced slices, a new feature that promises to drive users back to your app by getting your app’s features and content in front of them at the exact moment when they're needed the most.
With slices shaping up to be an important tool for retaining your audience, now’s the perfect time to get some hands-on experience with this up-and-coming Android feature. By the end of this article, you’ll have created a range of slices, from a simple slice that launches an Activity when tapped through to more complex slices consisting of icons, images, grids, and multiple SliceActions
.
Slices: More Ways for Users to Enjoy Your App
Similar to widgets, slices are snippets of content that appear outside of the application context, increasing your app’s visibility and providing you with more opportunities to engage your audience.
Slices have the potential to greatly increase your app’s visibility, with Google promising to add support for slices to the areas where many Android users spend significant amounts of time, including Google search and the Google Assistant. Since they're part of Android Jetpack, slices are compatible with Android 4.4 and higher, which means your slices have the potential to reach 95% of all Android users.
So slices have a lot to offer—but how do they work?
Currently, if you perform a search in the Google app then Google might suggest a relevant application that’s installed on your device. For example, if you’ve installed Facebook for Mobile, then typing facebook will bring up a direct link to the Facebook app.
Slices take this app linking one step further, by focusing on specific tasks the user might want to perform within the applications they’ve already installed.
Let’s look at an example: imagine you’ve installed a Book A Hotel app that lets you search for a hotel and reserve a room. When you type London hotels into Google, you encounter the usual search results, plus a slice from the Book A Hotel application. This slice recommends a hotel in London and displays information such as the hotel’s name and address, plus a SliceAction
, in the form of a button that lets you reserve a room directly from the slice’s user interface (UI).
For the user, this slice has provided easy access to the information and features they needed at that particular moment. For the developer, this slice has enabled them to get their application in front of a user at the exact point when they stood the greatest chance of successfully re-engaging them.
How Do I Create My First Slice?
Let’s start by creating a simple slice that, when tapped, will launch our application’s MainActivity
.
This simple technique makes it possible to start any task, directly from a slice’s UI. In our Book A Hotel example, we could just link the button to the related app’s BookRoomActivity
, which would be a simple but effective way to reduce the number of screens the user has to navigate in order to complete this particular task.
To get started, create a new Android project. You can use whatever settings you want, but make sure you select the Include Kotlin support checkbox when prompted.
Once you’ve created your project, open its build.gradle file and add the slice-core
and slice-builder
dependencies:
dependencies {
implementation 'androidx.appcompat:appcompat:1.0.0-alpha3'
implementation 'androidx.slice:slice-core:1.0.0-alpha3'
implementation 'androidx.slice:slice-builders:1.0.0-alpha3'
implementation 'androidx.constraintlayout:constraintlayout:1.1.0'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
Displaying Your App’s Content in Google Search, With Slice Providers
Next, we need to create a slice provider, which is the component responsible for displaying your app’s content outside of the application context.
You create a slice provider by using Android Studio’s slice provider template:
- Select New > Other > Slice Provider from the Android Studio toolbar.
- Enter the name MySliceProvider.
- Set the Source language to Kotlin.
- Click Finish.
- Open the
MySliceProvider
class, and you should see the following automatically generated code:
import android.content.ContentResolver
import android.content.Intent
import android.net.Uri
import androidx.slice.Slice
import androidx.slice.SliceProvider
import androidx.slice.builders.ListBuilder
class MySliceProvider : SliceProvider() {
override fun onCreateSliceProvider(): Boolean {
return true
}
override fun onMapIntentToUri(intent: Intent?): Uri {
var uriBuilder: Uri.Builder = Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
if (intent == null) return uriBuilder.build()
val data = intent.data
if (data != null && data.path != null) {
val path = data.path.replace("/", "")
uriBuilder = uriBuilder.path(path)
}
val context = context
if (context != null) {
uriBuilder = uriBuilder.authority(context.getPackageName())
}
return uriBuilder.build()
}
//Construct the slice//
override fun onBindSlice(sliceUri: Uri): Slice? {
val context = getContext() ?: return null
return if (sliceUri.path == "/") {
//Customise the Slice//
ListBuilder(context, sliceUri)
.addRow { it.setTitle("URI found.") }
.build()
} else {
ListBuilder(context, sliceUri)
.addRow { it.setTitle("URI not found.") }
.build()
}
}
//Subscribe to a data source, if necessary//
override fun onSlicePinned(sliceUri: Uri?) {
}
//Avoid memory leaks by unsubscribing from the data source and removing any observers//
override fun onSliceUnpinned(sliceUri: Uri?) {
}
}
If you create your slice provider using New > Other > Slice Provider, then Android Studio will also add the necessary provider to your Manifest:
<provider
android:name=".MySliceProvider"
android:authorities="com.jessicathornsby.kotlinslices"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.app.slice.category.SLICE" />
<data
android:host="jessicathornsby.com"
android:pathPrefix="/"
android:scheme="http" />
</intent-filter>
</provider>
</application>
This entry ensures that your slice can be discovered by other applications.
Has Your Gradle Project Sync Failed?
So far, we’ve only used code that Android Studio has generated automatically, but your project may already be refusing to compile!
Bugs, missing functionality and all-around strange behaviour are just part of the fun of working with early releases. At the time of writing, generating a slice provider would sometimes inexplicably add a new set of dependencies to your project’s build.gradle file.
implementation 'androidx.slice:slices-core:1.0.0-alpha1'
implementation 'androidx.slice:slices-builders:1.0.0-alpha1'
Not only are these dependencies unnecessary—they’re wrong. Although it’s easy to miss, compare:
implementation 'androidx.slice:slices-core:1.0.0-alpha3'
With the correct:
implementation 'androidx.slice:slice-core:1.0.0-alpha1'
A single s can mean the difference between a functioning application and a project that refuses to compile. Chances are this bug will be addressed before the official release of slices, but if Android Studio starts complaining about unresolved dependencies then check your build.gradle file to see whether this has happened in your project.
Building a Slice: URIs, SliceActions
, and Slice Layouts
To turn the slice provider’s boilerplate code into a functioning slice, we need to make several changes:
1. Define a URI
Each slice has a unique URI, and it’s the slice provider’s job to provide the mapping between this URI and the corresponding slice.
Apps that are capable of displaying a slice are known as host applications. Every time a host needs to display a slice, it sends a binding request to the slice provider with the URI of the slice that it’s looking for. Your slice provider will then check the URI and return the appropriate slice.
In the following snippet, the onBindSlice
method is checking for the /myURI
path and returning a slice that displays a Hello World message.
class MySliceProvider : SliceProvider() {
override fun onCreateSliceProvider(): Boolean {
return true
}
override fun onBindSlice(sliceUri: Uri): Slice? {
return if (sliceUri.path == "/myURI") {
ListBuilder(context, sliceUri, ListBuilder.INFINITY)
.addRow { it.setTitle("Hello World") }
.build()
} else {
...
...
...
}
}
}
2. Make Your Slice Interactive
While you could create a slice that simply displays some information, if you want your slice to be interactive then you’ll need to create one or more SliceActions
.
A SliceAction
can consist of a title, an icon, and a PendingIntent
. You can also mark SliceActions
as primary actions, which trigger whenever the user taps anywhere on that slice’s row.
3. Build the Slice’s UI
You define a slice’s layout by implementing a ListBuilder
, adding a row, and then adding items to that row. For example, here I’m using ListBuilder
and addRow
to create a slice that consists of a title and a subtitle:
import android.net.Uri
import androidx.slice.Slice
import androidx.slice.SliceProvider
import androidx.slice.builders.ListBuilder
import androidx.slice.builders.ListBuilder.INFINITY
class MySliceProvider : SliceProvider() {
override fun onCreateSliceProvider(): Boolean {
return true
}
override fun onBindSlice(sliceUri: Uri): Slice? {
val path = sliceUri.path
when (path) {
"/launchMainActivity" -> return createSlice(sliceUri)
}
return null
}
fun createSlice(sliceUri: Uri): Slice {
return ListBuilder(context, sliceUri, INFINITY)
.addRow {
it.apply {
setTitle("This is a title")
setSubtitle("This is a subtitle")
}
}.build()
}
}
You can display a mixture of different content types in the same row, such as text, actions, and icons.
Build Your First Fully Functioning Android Slice
Now let’s apply all of this to our project and create a slice that launches our application’s MainActivity
when tapped.
Open the MySliceProvider
class, and add the following:
import android.app.PendingIntent
import android.content.Intent
import android.net.Uri
import androidx.core.graphics.drawable.IconCompat
import androidx.slice.Slice
import androidx.slice.SliceProvider
import androidx.slice.builders.ListBuilder
import androidx.slice.builders.SliceAction
//Extend from SliceProvider//
class MySliceProvider : SliceProvider() {
//Initialise your slice provider//
override fun onCreateSliceProvider(): Boolean {
return true
}
//Build the slice//
override fun onBindSlice(sliceUri: Uri): Slice? {
//Check the URI path//
val path = sliceUri.path
when (path) {
//Define the slice’s URI; I’m using ‘launchMainActivity’//
"/launchMainActivity" -> return createSlice(sliceUri)
}
return null
}
fun createSlice(sliceUri: Uri): Slice {
val activityAction = createActivityAction()
//Create the ListBuilder, which we’ll use to add rows to our slice//
val listBuilder = ListBuilder(context!!, sliceUri, ListBuilder.INFINITY)
//Construct the rows using RowBuilder//
val rowBuilder = ListBuilder.RowBuilder(listBuilder)
//Set the title text//
.setTitle("Open MainActivity.")
//Set the row’s primary action//
.setPrimaryAction(activityAction)
//Add the row to the ListBuilder//
listBuilder.addRow(rowBuilder)
//Build the list//
return listBuilder.build()
}
fun createActivityAction(): SliceAction {
val intent = Intent(context, MainActivity::class.java)
return SliceAction(PendingIntent.getActivity(context, 0, intent, 0),
IconCompat.createWithResource(context!!, R.drawable.ic_home),
"Open MainActivity")
}
}
Testing Your Slices: Installing Slice Viewer
If you’re going to put your slices to the test, then you’ll need at least one application that’s capable of displaying slices.
Slices will reportedly be making their debut in Google search later this year, but at the time of writing, this feature had yet to be rolled out. Currently, the only way to test slices is to install Google’s Slice Viewer app, which is designed to emulate how slices will eventually appear in Google search.
To install Slice Viewer on an Android Virtual Device (AVD):
Download Google’s Slice Viewer application.- Make sure your AVD is up and running.
- Find the Slice Viewer APK file, and drag and drop it onto your AVD.
To install Slice Viewer on a physical smartphone or tablet:
- Download Slice Viewer.
- Make sure your smartphone or tablet is attached to your development machine.
- Move the Slice Viewer APK to your computer’s Android/sdk/platform-tools folder.
- Open a Command Prompt (Windows) or Terminal (Mac) window.
- Change directory (
cd
) so that the Command Prompt or Terminal is pointing at your Android/sdk/platform-tools folder—for example, here's my command:
cd /Users/jessicathornsby/Library/Android/sdk/platform-tools
- Run the command, by pressing the Enter key on your keyboard.
- Use the
adb install
command to push the APK to your Android device:
./adb install slice-viewer.apk
Creating a URI Run Configuration
Next, you’ll need to create a run configuration that passes your slice’s unique URI to your AVD or Android device.
- Select Run > Edit Configurations… from the Android Studio toolbar.
- Click the + button and then select Android App.
- Give your run configuration a name. I’m using sliceConfig.
- Open the Module dropdown, and then select app.
- Open the Launch dropdown, and then select URL.
- Enter your slice’s URL, in the format slice-content://package-name/slice-URL. For example, my slice’s URL is: slice-content://com.jessicathornsby.kotlinslices/launchMainActivity.
- Click OK.
- Select Run > Run sliceConfig from the Android Studio toolbar, and then select your Android device.
The first time Slice Viewer tries to display your slice, it’ll request permission to access your slice’s unique URI. Tap Allow and navigate the permissions dialogue, and your slice should appear onscreen.
To interact with the SliceAction
, click the Open MainActivity button, and the slice will respond by launching your application’s MainActivity
.
Getting More Out of Your Slices: Adding a Second SliceAction
Why limit yourself to one SliceAction
, when you can have multiple SliceActions
? In this section, we’re going to implement two SliceActions
, where each action launches a different Activity
. I’m also going to introduce a few new UI elements, by adding a subtitle and some end items to our slice.
Create a SecondActivity
Let’s get the setup out of the way and create a second Activity
that our second SliceAction
can link to.
First, select New > Kotlin File / Class from the Android Studio toolbar. In the new file dialog, open the Kind dropdown and select Class. Name this class SecondActivity
, and then click OK.
Now open your SecondActivity
class and add the following:
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
class SecondActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second)
}
}
Next, select New > Android Resource File from the Android Studio toolbar. In the subsequent window, open the Resource type dropdown, and select Layout. Name this file activity_second
, and click OK.
Now open this layout file and add the following code:
<?xml version="1.0" encoding="utf-8"?>
https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Second Activity"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Open your project’s Manifest, and declare this SecondActivity
:
<activity android:name=".SecondActivity">
Building More Complex UIs: Slice End Items
End items can either be a timestamp, an image, or a SliceAction
, but as the name suggests, they always appear at the end of a row. You can add multiple end items to a single row, although depending on the available space there’s no guarantee that all of your end items will be displayed to the user.
We’ll be creating our SliceActions
as icons, so you’ll need to add two new drawables to your project:
- Select New > Image Asset from the Android Studio toolbar.
- Click the little Clip art button (this displays a picture of an Android by default).
- Select the icon that you want to use for your Launch MainActivity end item. I'm using the Home icon.
- Give this icon the name ic_home, and then click Next.
- Read the onscreen information, and if you’re happy to proceed then click Finish.
Repeat the above steps to create an icon for your Launch SecondActivity slice action. For my second end item, I'm using the call icon and naming it ic_call.
Creating the Second SliceAction
We’re now ready to add a second SliceAction
to the MySliceProvider
class:
import android.app.PendingIntent
import android.content.Intent
import android.net.Uri
import androidx.core.graphics.drawable.IconCompat
import androidx.slice.Slice
import androidx.slice.SliceProvider
import androidx.slice.builders.ListBuilder
import androidx.slice.builders.SliceAction
class MySliceProvider : SliceProvider() {
override fun onCreateSliceProvider(): Boolean {
return true
}
override fun onBindSlice(sliceUri: Uri): Slice? {
val path = sliceUri.path
when (path) {
"/launchMainActivity" -> return createSlice(sliceUri)
}
return null
}
fun createSlice(sliceUri: Uri): Slice {
val activityAction = createActivityAction()
IconCompat.createWithResource(context!!, R.drawable.ic_home).toIcon()
val activityAction2 = createSecondActivityAction()
IconCompat.createWithResource(context!!, R.drawable.ic_call).toIcon()
//Construct the parent builder//
val listBuilder = ListBuilder(context!!, sliceUri)
//Construct the builder for the row//
val myRow = ListBuilder.RowBuilder(listBuilder)
.setTitle("Launch MainActivity.")
.setSubtitle("This is a subtitle")
//Add the actions that we'll be using as end items//
myRow.addEndItem(activityAction)
myRow.addEndItem(activityAction2)
//Add the row to the parent builder//
listBuilder.addRow(myRow)
//Build the slice//
return listBuilder.build()
}
fun createActivityAction(): SliceAction {
val intent = Intent(context, MainActivity::class.java)
return SliceAction(PendingIntent.getActivity(context, 0, intent, 0),
IconCompat.createWithResource(context!!, R.drawable.ic_home).toIcon(),
"Launch MainActivity")
}
fun createSecondActivityAction(): SliceAction {
val intent = Intent(context, SecondActivity::class.java)
return SliceAction(PendingIntent.getActivity(context, 0, intent, 0),
IconCompat.createWithResource(context!!, R.drawable.ic_call).toIcon(),
"Launch SecondActivity")
}
}
Since we haven’t changed the URI, we don’t need to create a new run configuration, which means that testing this slice is as simple as selecting Run > sliceConfig from the Android Studio toolbar.
You can download this project from the tutorial GitHub repo.
Multimedia Slices: Creating Grid Layouts
Up to this point, we’ve constructed all of our slices using rows only, but you can also build slices using grid rows and cells.
In this final section, we’re going to create a slice consisting of a title, a subtitle, and a single row divided into three cells. Each cell will have its own title, some body text, and an image, and each one will perform a unique action when tapped.
To lay out your slice in a grid, you need to:
- Implement a
ListBuilder
. - Add a grid row to the
ListBuilder
, usingaddGridRow
. - Add cells to the row, using
addCell
. Each row can display a maximum of five cells.
You can then add content to each cell, such as:
- A title, which you add using
addTitleText
. - Body text, using
addText
. - Images, which you create using
addImage
. Each cell image must have one of the following attributes:LARGE_IMAGE
,SMALL_IMAGE
, orICON_IMAGE
. - A content intent, which is roughly equivalent to a
SliceAction
. To help keep this example straightforward, tapping each cell will simply load an article in the device’s default browser, but if you’d prefer a more authentic slices experience then you can change thesetContentIntent
code.
I’m going to include some images in my grid, so you’ll need to add at least one drawable to your project. I’m using the Kotlin logo, but you can grab any image and drop it into your project’s Drawable folder.
Now, you’re ready to open the MySliceProvider
class and build your grid:
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.net.Uri
import androidx.core.graphics.drawable.IconCompat
import androidx.slice.Slice
import androidx.slice.SliceProvider
import androidx.slice.builders.ListBuilder
class MySliceProvider : SliceProvider() {
override fun onCreateSliceProvider(): Boolean {
return true
}
override fun onBindSlice(sliceUri: Uri): Slice? {
val path = sliceUri.path
when (path) {
"/launchMainActivity" -> return createSliceWithGridRow(sliceUri)
}
return null
}
fun createSliceWithGridRow(sliceUri: Uri): Slice {
return ListBuilder(context, sliceUri, ListBuilder.INFINITY)
.setHeader {
it.apply {
setTitle("Want to start learning Kotlin for Android?")
setSubtitle("Check out these articles!")
}
}
//Add a grid row to the list builder//
.addGridRow {
it.apply {
//Add a cell to the row//
addCell {
it.apply {
//Add content to your cell//
addTitleText("Java vs. Kotlin")
addText("Part 1")
addImage(IconCompat.createWithResource(context, R.drawable.kotlin), ListBuilder.LARGE_IMAGE)
//Specify the intent that should trigger whenever the user interacts with this cell//
.setContentIntent(
loadArticlePendingIntent(
context,
"https://code.tutsplus.com/articles/java-vs-kotlin-should-you-be-using-kotlin-for-android-development...)
}
}
addCell {
it.apply {
addTitleText("Coding in Kotlin")
addText("Part 2")
addImage(IconCompat.createWithResource(context, R.drawable.kotlin), ListBuilder.LARGE_IMAGE)
.setContentIntent(
loadArticlePendingIntent(
context,
"https://code.tutsplus.com/tutorials/start-developing-android-apps-with-kotlin-part-1--cms-27827?_ga=...)
}
}
addCell {
it.apply {
addTitleText("Lambdas & NPE")
addText("Part 3")
addImage(IconCompat.createWithResource(context, R.drawable.kotlin), ListBuilder.LARGE_IMAGE)
.setContentIntent(
loadArticlePendingIntent(
context,
"https://code.tutsplus.com/articles/coding-functional-android-apps-in-kotlin-lambdas-null-safety-more...)
}
}
}
}
.build()
}
private fun loadArticlePendingIntent(context: Context, url: String) =
PendingIntent.getActivity(
context,
0,
Intent(Intent.ACTION_VIEW).apply { data = Uri.parse(url) },
0
)
}
You can find the complete code for this project in our GitHub repo.
Run this app in your AVD or physical Android device, and try interacting with each item in the grid. Each cell should link to a different article.
Ensure Your Slice Looks Good, Regardless of the Host Application
The way your slice’s content is displayed can vary, depending on the mode the host application is configured for. To ensure your slices look good and function correctly regardless of the hosting application, you’ll need to test your slices across all the different slice modes.
Since our grid slice has significantly more content than the previous slices, it’s the best candidate to illustrate the differences between these various slice modes.
To put your slice to the test, click the little icon in the Slice Viewer’s upper-right corner, and then cycle through the following modes:
1. Large
In this format, Android displays as many rows as possible in the space available. This is the mode that Slice Viewer uses by default.
2. Shortcut
In this mode, your slice is represented by an icon and a label.
If there’s a primary header associated with your SliceAction
, then this will be used as your slice’s icon. If there’s no icon available, then Android will instead display the primary action associated with your slice’s first row, which in this instance is our Kotlin drawable.
To change the icon that’s displayed in shortcut mode, add a second drawable to your project, and then update the following section of the slice provider:
.addGridRow {
it.apply {
addCell {
it.apply {
addTitleText("Java vs. Kotlin")
addText("Part 1")
//Reference the new drawable//
addImage(IconCompat.createWithResource(context, R.drawable.androidlogo), ListBuilder.LARGE_IMAGE)
3. Small
Small mode has a restricted height and will either display a single SliceItem
or a limited collection of items as a single row of content. If your slice has a header, then this will be displayed, which is exactly what’s happening with our slice.
Changing either the title or the subtitle will affect the content that’s displayed in small mode.
fun createSliceWithGridRow(sliceUri: Uri): Slice {
return ListBuilder(context, sliceUri, ListBuilder.INFINITY)
.setHeader {
it.apply {
setTitle("This is the title")
setSubtitle("This is the subtitle")
}
}
If your slice doesn’t contain a header, then the slice’s first row will be displayed instead.
Cut Down Code, With Slice Builders KTX
Once you’ve learned how to implement a new feature, the next step is learning how to deliver the same results, with less code!
Android KTX is a collection of modules consisting of extensions that optimize the Android platform for Kotlin. Android KTX’s Slice Builders KTX module wraps the builder pattern in a Kotlin-friendly DSL that helps you create your slices in a more concise, human-readable way. To get started with Slice Builders KTX, replace the following dependency:
implementation 'androidx.slice:slice-builders:1.0.0-alpha3'
With:
implementation 'androidx.slice:slice-builders-ktx:1.0.0-alpha3'
You can then modify your createSlice
method to use this DSL. For example, here’s a simple slice that displays a title and a subtitle:
import android.net.Uri
import androidx.slice.Slice
import androidx.slice.SliceProvider
import androidx.slice.builders.ListBuilder
import androidx.slice.builders.ListBuilder.INFINITY
class MySliceProvider : SliceProvider() {
override fun onCreateSliceProvider(): Boolean {
return true
}
override fun onBindSlice(sliceUri: Uri): Slice? {
val path = sliceUri.path
when (path) {
"/launchMainActivity" -> return createSlice(sliceUri)
}
return null
}
fun createSlice(sliceUri: Uri): Slice {
return ListBuilder(context, sliceUri, INFINITY)
.addRow {
it.apply {
setTitle("This is a title")
setSubtitle("This is a subtitle")
}
}.build()
}
}
Using the DSL, this becomes:
import android.net.Uri
import androidx.slice.Slice
import androidx.slice.SliceProvider
import androidx.slice.builders.ListBuilder
import androidx.slice.builders.list
import androidx.slice.builders.row
class MySliceProvider : SliceProvider() {
override fun onCreateSliceProvider(): Boolean {
return true
}
override fun onBindSlice(sliceUri: Uri): Slice? {
val path = sliceUri.path
when (path) {
"/launchMainActivity" -> return createSlice(sliceUri)
}
return null
}
fun createSlice(sliceUri: Uri): Slice {
//Instantiate a ListBuilder and call build when the lambda has finished running//
return list(context, sliceUri, ListBuilder.INFINITY) {
//Instantiate row and add it to the ListBuilder//
row {
//setTitle and setSubtitle are both inside the row lambda//
setTitle("This is a title")
setSubtitle("This is a subtitle")
}
}
}
}
Conclusion
In this article, we got some hands-on experience with Android’s up-and-coming slices feature. We saw how to create a simple slice that can provide direct access to any part of your application, before moving on to creating more complex slices consisting of end items, images, additional text, and multiple SliceActions
.
You can learn more about slices in the official Android docs.
Original Link:
TutsPlus - Code
Tuts+ is a site aimed at web developers and designers offering tutorials and articles on technologies, skills and techniques to improve how you design and build websites.More About this Source Visit TutsPlus - Code