![Sebastian Benz](https://web.dev/images/authors/sebastianbenz.jpg) Sebastian Benz [GitHub](https://github.com/sebastianbenz) [Mastodon](https://mastodon.cloud/@sebabenz) [Bluesky](https://bsky.app/profile/sebabenz.bsky.social)

<br />

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.
![Screenshot of a bottom sheet Partial Tab](https://developer.chrome.com/static/docs/android/custom-tabs/guide-partial-custom-tabs/image/example-partial-tab-ff19cab6a28dd.png) Partial Custom Tab in a bottom sheet.

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.
![Screenshot of a side sheet Partial Tab](https://developer.chrome.com/static/docs/android/custom-tabs/guide-partial-custom-tabs/image/example-partial-tab-sidesheet.jpg) Partial Custom Tab in a side sheet.

> [!IMPORTANT]
> **Key point:**
>
> - Specifying the initial activity height won't have an effect if the default browser does not support partial Custom Tabs. In this case, the intent extra will be ignored and the Custom Tab will span the complete display height.
> - `CustomTabColorScheme.navigationBarColor` and `CustomTabColorScheme.navigationBarDividerColor` properties don't work when building an intent for a partial Custom Tab. This is because they inherit the host app's color scheme for the user interface properties above. You will be responsible for ensuring visual consistency for these properties before launching a Custom Tab.

## Prerequisite

To be able to use partial Custom Tabs you needs to:

- [start a new browser session using a `CustomTabsServiceConnection`](https://developer.chrome.com/docs/android/custom-tabs/integration-guide#connect-to-the-custom-tabs-service)
  and pass it to the Custom Tabs intent or

- start the Custom Tab activity using
  [`startActivityForResult()`](https://developer.android.com/reference/android/app/Activity#startActivityForResult(android.content.Intent,%20int)).

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()`](https://developer.android.com/reference/androidx/browser/customtabs/CustomTabsIntent.Builder#setInitialActivityHeightPx(int))
method. By default, the partial Custom Tab is resizable, but you can pass
[`ACTIVITY\_HEIGHT\_FIXED`](https://developer.android.com/reference/androidx/browser/customtabs/CustomTabsIntent#ACTIVITY_HEIGHT_FIXED())
to disable this behavior:

```java
new CustomTabsBuilder().setInitialActivityHeightPx(
    400,
    ACTIVITY_HEIGHT_FIXED
);
```

> [!IMPORTANT]
> **Key point:** The minimum partial custom tab height is 50% of the screen height. If the screen height is set to a value less than 50% of the screen height, Chrome automatically adjusts the Custom Tab to 50% of the screen height.

## Configuring the side sheet

To configure the side sheet behavior, define the initial launch width in pixels by
calling the `CustomTabBuilder` class's
[`setInitialActivityWidthPx()`](https://developer.android.com/reference/androidx/browser/customtabs/CustomTabsIntent.Builder#setInitialActivityWidthPx(int))
method.

By default, the partial Custom Tab is resizable, but you can pass
[`ACTIVITY\_HEIGHT\_FIXED`](https://developer.android.com/reference/androidx/browser/customtabs/CustomTabsIntent#ACTIVITY_HEIGHT_FIXED())
to disable this behavior:

```java
  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()](https://developer.android.com/reference/androidx/browser/customtabs/CustomTabsIntent.Builder#setActivitySideSheetBreakpointDp(int)).
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

```java
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

```java
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](https://developer.chrome.com/docs/android/custom-tabs/guide-engagement-signals.md.txt).