diff --git a/docs/components/Search.md b/docs/components/Search.md new file mode 100644 index 00000000000..35e507eb023 --- /dev/null +++ b/docs/components/Search.md @@ -0,0 +1,352 @@ + + +# Search Bar + +Search is a navigation pattern that leverages Google's most iconic feature, +search. This floating search field is a product-specific element that also +provides a surface for additional navigation icons. + +![search bar light](assets/search/search-bar-light.png) + +**Contents** + +* [Using search components](#using-search-components) +* [Search Bar](#search-bar) +* [Search View](#search-view) +* [Putting it all together](#putting-it-all-together) + +## Using search components + +Before you can use the Material Search components, you need to add a dependency to +the Material Components for Android library. For more information, go to the +[Getting started](https://github.com/material-components/material-components-android/tree/master/docs/getting-started.md) +page. +### Making Search Components accessible + +You should set a content description on a search bar and search view components +via the `android:contentDescription` attribute or `setContentDescription` method +so that screen readers such as TalkBack are able to announce their purpose or +action. Text rendered in these components are automatically provided to +accessibility services, so additional content labels are usually unnecessary. + +## Search Bar + +The `SearchBar` component provides an implementation of the floating search +field. It extends `Toolbar`, so it supports a navigation icon, menu items, and +any other `Toolbar` APIs. Additionally, the `SearchBar` comes with a hint +`TextView` and supports nesting a centered branding element. + +Since `SearchBar` extends `Toolbar`, you can set up your `SearchBar` as an +`ActionBar` via [`AppCompatActivity#setSupportActionBar`](https://developer.android.com/reference/kotlin/androidx/appcompat/app/AppCompatActivity#setSupportActionBar(androidx.appcompat.widget.Toolbar)), and inflate a menu by +overriding the `onCreateOptionsMenu` method. However, if using the default +magnifying glass `navigationIcon`, you may need to set +`app:forceDefaultNavigationOnClickListener="true"` on your `SearchBar` so that +the search icon doesn't act as a back button due to the Activity's `ActionBar` +setup flow. + +Alternatively, you can choose to not set up your `SearchBar` as an `ActionBar`, +and instead just use `Toolbar`'s `inflateMenu` and `setOnMenuItemClickListener` +methods: + +```java +searchBar.inflateMenu(R.menu.searchbar_menu); +searchBar.setOnMenuItemClickListener( + menuItem -> { + // Handle menuItem click. + return true; + }); +``` + +Note: `SearchBar` aims to provide a consistent search bar across all apps, so +it does not support setting a custom background via `android:background`. + +### Anatomy and key properties + +The following is an anatomy diagram for the search bar: + +![Search bar anatomy diagram](assets/search/search-bar-anatomy.png) + +1. Container +2. Leading icon button +3. Input text Supporting text +4. Avatar (optional) +5. Supporting text +6. Trailing icon button (optional) + +### Attributes + +The following attributes can be changed for `SearchBar`: + +Element | Attribute | Related method(s) | Default value +--------- | --------------- | ----------------------------------------- | ------------- +**Min height** | `android:minHeight` | `setMinHeight`
`getMinHeight` | `@dimen/m3_searchbar_height` +**Search text appearance** | `android:textAppearance` | `setTextAppearance`
`getTextAppearance` | `@style/TextAppearance.Material3.SearchBar` +**Search text** | `android:text` | `setText`
`getText` | `null` +**Search hint** | `android:hint` | `setHint`
`getHint` | `null` +**Flag for default margins** | `app:defaultMarginsEnabled` | -- | `true` +**Flag for navigation icon** | `app:hideNavigationIcon` | -- | `false` + +## Styles + +Element | Style +----------------- | ------------------------------------------------ +**Search Bar Default style** | `Widget.Material3.SearchBar` + +Default search bar style theme attribute: `?attr/searchBarStyle`. + +### Scrolling Behavior + +The `SearchBar` can either be used as a fixed or scroll-away search field. + +#### Fixed Mode + +To set up the fixed mode, simply position the `SearchBar` on top of the rest of +your layout's contents and do not set up any scrolling behaviors. It will remain +in place as the content is scrolled beneath it. + +#### Scroll-away Mode + +To set up the scroll-away mode, use a top-level `CoordinatorLayout` and place +the `SearchBar` within an `AppBarLayout`. Then, place the `AppBarLayout` below +the scrolling view (usually a `RecyclerView` or `NestedScrollView`) in the +`CoordinatorLayout`, and set +`app:layout_behavior="@string/searchbar_scrolling_view_behavior"` on the +scrolling view. This scrolling behavior makes the `AppBarLayout` transparent and +not elevated so there are no undesirable shadows. It also adjusts the scrolling +child so that the `SearchBar` will overlap the rest of your content and appear +to be floating above it. See the [XML usage](#usage) section below for an +example of how to set up this behavior. + +### Toolbar Transitions + +The `SearchBar` component also provides transitions to and from a `Toolbar`, +e.g., for a contextual multi-select flow. These transitions are implemented as +expand and collapse animations, and can be started by calling `SearchBar#expand` +and `SearchBar#collapse`, respectively. Additionally, if you are using an +`AppBarLayout` in conjunction with the `SearchBar`, you may pass in a reference +to your `AppBarLayout` to these methods so that its visibility and offset can be +taken into account for the animations. + +Lastly, make sure to add the following to your back pressed handling method, in +order to collapse the contextual `Toolbar` into the `SearchBar` when the user +presses the system back button: + +```java +if (searchBar.collapse(contextualToolbar, appBarLayout)) { + // Clear selection. + return; +} +``` + +## API and source code + +* [Class definition](https://developer.android.com/reference/com/google/android/material/search/SearchBar) +* [Class source](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/search/SearchBar.java) + +## Search View + +The `SearchView` component provides an implementation of a full-screen search +view which can be used to display back navigation, a search hint and text, menu +items, and search suggestions and results. It also comes with a clear text +button that shows and hides depending on whether the user has entered text. + +To set up a menu for your `SearchView`, you can use the `inflateMenu` and +`setOnMenuItemClickListener` methods: + +```java +searchView.inflateMenu(R.menu.search_view_menu); +searchView.setOnMenuItemClickListener( + menuItem -> { + // Handle menuItem click. + return true; + }); +``` + +Additionally, here is an example of how you can carry over the search text to +the `SearchBar`, as well as hide the `SearchView` when the user finishes typing +and presses enter: + +```java +searchView + .getEditText() + .setOnEditorActionListener( + (v, actionId, event) -> { + searchBar.setText(searchView.getText()); + searchView.hide(); + return false; + }); +``` + +### Anatomy and key properties + +The following is an anatomy diagram for the search view: + +![Search view anatomy diagram](assets/search/search-view-anatomy.png) + +1. Container +2. Header +3. Leading icon button +4. Supporting text +5. Trailing icon button +6. Input text +7. Divider + +### Attributes + +The following attributes can be changed for `SearchView`: + +Element | Attribute | Related method(s) | Default value +--------- | --------------- | ----------------------------------------- | ------------- +**Search text appearance** | `android:textAppearance` | `setTextAppearance`
`getTextAppearance` | `@style/TextAppearance.Material3.SearchBar` +**Search text** | `android:text` | `setText`
`getText` | `null` +**Search hint** | `android:hint` | `setHint`
`getHint` | `null` +**Flag for navigation icon** | `app:hideNavigationIcon` | -- | `true` +**Flag for `DrawerArrowDrawable`** | `app:useDrawerArrowDrawable` | -- | `false` +**Flag for soft keyboard** | `app:autoShowKeyboard` | -- | `true` + +## Styles + +Element | Style +----------------- | ------------------------------------------------ +**Search View Default style** | `Widget.Material3.SearchView` + +Default search view style theme attribute: `?attr/searchViewStyle`. + +### Expand and Collapse Animations + +One of the biggest advantages of using the `SearchView` in conjunction with an +`SearchBar` is that you will get the expand and collapse animations for free. If +you are just using a standalone `SearchView` without an `SearchBar`, then +showing or hiding the `SearchView` will result in slide up and slide down +transitions. + +### Transition Listeners + +If you want to get callbacks for when the `SearchView` transitions between its +different animation states, you can add an `SearchView.TransitionListener` via +the `SearchView#addTransitionListener` method. E.g.: + +```java +searchView.addTransitionListener( + (searchView, previousState, newState) -> { + if (newState == TransitionState.SHOWING) { + // Handle search view opened. + } + }); +``` + +### Soft Input Modes + +The recommended `windowSoftInputMode` when using an `SearchBar` and an +`SearchView` is `adjustNothing`. There are a couple reasons for this: + +1. The `adjustResize` mode causes the screen to resize when the keyboard is + shown, which can cause glitchiness during the expand and collapse + animations. `SearchView` does address this by staggering the showing and + hiding of the keyboard with the animations; however, the preferred approach + is to use `adjustNothing` so the keyboard can be shown and hidden + immediately. +2. Resizing the screen is not usually helpful to the user during search. The + user can either keep typing to see more results or start scrolling, in which + case the `SearchView` will automatically dismiss the keyboard to show the + rest of the screen. + +On initial render, the `SearchView` will get the soft input mode from the +`Window`, so that it can set up the above behavior. If you change the soft input +mode at runtime, make sure to also invoke the `SearchView#setSoftInputMode` +method so that the `SearchView` can adjust its behavior accordingly. + +Lastly, if you don't want the soft keyboard to show automatically when the +`SearchView` is shown, you can set `app:autoShowKeyboard="false"` on your +`SearchView`. + +### Translucent Status Bar + +`SearchBar` and `SearchView` come with support for a translucent status bar. + +To make sure that the `SearchBar` doesn't appear underneath the translucent +status bar, you can wrap it in a `FrameLayout` which has the +`android:fitsSystemWindows` attribute set to `true`. For an example of how to +set this up in XML, take a look at the +[Search Bar Maps demo][search-bar-usage-maps]. + +Additionally, you should not set the `android:fitsSystemWindows` attribute on +the `SearchView`. If you are using either `FLAG_TRANSLUCENT_STATUS` +(`android:windowTranslucentStatus`) or `FLAG_LAYOUT_NO_LIMITS`, then the +`SearchView` will automatically add an extra spacer surface so that it fills the +space underneath the translucent status bar. + +### Menu to Back Arrow Animation + +If you are using the `SearchBar` with a `NavigationDrawer`, you can set the +`app:useDrawerArrowDrawable` attribute to `true` on your `SearchView` to enable +the "hamburger" menu to back arrow icon animation. This animation will happen +during the expand and collapse of the `SearchView`. + +### Search Prefix + +If you would like to show some prefix text before the main search `EditText`, +you can make use of the `app:searchPrefixText` attribute. For example, setting +`app:searchPrefixText="To:"` on your `SearchView` will result in the fixed text +label, "To:", being shown before the search `EditText`. + +Additionally, with this pattern it is common to hide the back button to reduce +clutter, as navigation can be handled outside of the search view. This can be +accomplished by setting `app:hideNavigationIcon="true"` on your `SearchView`. + +## Putting it all together + +Putting it all together and using the scroll-away mode, the `SearchBar` and +`SearchView` widgets can be used in your layout as such: + +```xml + + + + + + + + + + + + + + + +``` + +By placing the `SearchBar` and `SearchView` within a `CoordinatorLayout` and +using the `app:layout_anchor` tag, they will get automatically hooked up. This +sets up the behavior of showing the `SearchView` when the `SearchBar` is tapped, +as well as the expand and collapse animations. If you can't use a +`CoordinatorLayout`, instead you can call the `SearchView#setUpWithSearchBar` +method to achieve the same result. + +## API and source code + +* [Class definition](https://developer.android.com/reference/com/google/android/material/search/SearchView) +* [Class source](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/search/SearchView.java)