By default, Custom Tabs launch as a full-window activity. Starting in Chrome 107, you can use partial Custom Tabs to specify a different launch height in portrait mode such that users can multitask by interacting with your app while viewing web content. Users can expand the Custom Tab to full-screen by dragging the toolbar handle up and restore the initial launch height by dragging the handle down.
For large screens or devices in landscape mode, starting with Chrome 120, you can specify, a maximum launch width to show a partial Custom Tab in a side sheet. By setting a break point, you can decide when to launch a partial Custom Tab in a bottom or a side sheet.
Prerequisite
To be able to use partial Custom Tabs you needs to:
start a new browser session using a
CustomTabsServiceConnection
and pass it to the Custom Tabs intent orstart the Custom Tab activity using
startActivityForResult()
.
Combine both approaches if you want a fast startup in case the service connection has not been established yet.
Configuring the bottom sheet
To turn a Custom Tab into a partial Custom Tab, define the initial launch height
in pixels by calling the CustomTabBuilder
class’s
setInitialActivityHeightPx()
method. By default, the partial Custom Tab is resizable, but you can pass
ACTIVITY\_HEIGHT\_FIXED
to disable this behavior:
new CustomTabsBuilder().setInitialActivityHeightPx(
400,
ACTIVITY_HEIGHT_FIXED
);
Configuring the side sheet
To configure the side sheet behavior, define the initial launch width in pixels by
calling the CustomTabBuilder
class’s
setInitialActivityWidthPx()
method.
By default, the partial Custom Tab is resizable, but you can pass
ACTIVITY\_HEIGHT\_FIXED
to disable this behavior:
CustomTabsIntent.Builder intentBuilder = new CustomTabsIntent.Builder(session)
.setInitialActivityHeightPx(400)
.setInitialActivityWidthPx(400);
.setActivitySideSheetBreakpointDp(800);
The Custom Tab will behave as a side sheet if the screen's width is bigger than
the breakpoint value set by
setActivitySideSheetBreakpointDp().
If the screen's width is higher than x
, the Custom Tab will behave as a side
sheet, otherwise it will behave as a bottom sheet. If no breakpoint is
specified, set the browser implementation should set as default value 840dp
.
If x
is set to <600dp
the browser implementation should default it to
600dp
.
Launch a partial Custom Tab with an existing session
CustomTabsSession customTabsSession;
// ...
CustomTabsIntent customTabsIntent = new CustomTabsIntent.Builder(customTabsSession)
.setInitialActivityHeightPx(500)
.setInitialActivityWidthPx(400);
.setActivitySideSheetBreakpointDp(800);
.setCloseButtonPosition(CustomTabsIntent.CLOSE_BUTTON_POSITION_END)
// ...
.build();
customTabsIntent.launchUrl(context, Uri.parse(url))
Launch a partial Custom Tab via startActivityForResult
private ActivityResultLauncher<String> mCustomTabLauncher = registerForActivityResult(new ActivityResultContract<String, Integer>() {
@Override
public Integer parseResult(int statusCode, @Nullable Intent intent) {
return statusCode;
}
@NonNull
@Override
public Intent createIntent(@NonNull Context context, String url) {
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(customTabsSession)
.setInitialActivityHeightPx(500)
.setInitialActivityWidthPx(400);
.setActivitySideSheetBreakpointDp(800);
.setCloseButtonPosition(CustomTabsIntent.CLOSE_BUTTON_POSITION_END)
.setToolbarCornerRadiusDp(10);
Intent customTabsIntent = builder.build().intent;
customTabsIntent.setData(Uri.parse(url));
return customTabsIntent;
}
}, new ActivityResultCallback<Integer>() {
@Override
public void onActivityResult(Integer statusCode) {
// ...
}
});
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
Button selectButton = findViewById(R.id.select_button);
selectButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
mCustomTabLauncher.launch(customTabsIntent.intent);
}
});
}
Next up: learn how to measure user engagement in your Custom Tabs.