## Request search suggestions UI view generator

To get the search suggestions UI view, you should get its generator first by the
following steps:

1. Let your target `Activity` class implement the `GetSearchSuggestionsViewGeneratorCallback` interface or use the anonymous inner class.
2. Override the `GetSearchSuggestionsViewGeneratorCallback` interface's `onSuccess(SearchSuggestionsViewGenerator)` and `onError(String)` methods.
3. Construct the `GetSearchSuggestionsViewOptions` class instance with a list of search contexts. (Optional) This object also takes a `SearchSuggestionsViewOptions` object which provides some options to customize the appearance of the search suggestions UI.
4. Call `SearchInAppsService`'s `getSearchSuggestionsView(GetSearchSuggestionsViewOptions,
   GetSearchSuggestionsViewGeneratorCallback)` function.
5. After you get the UI generator, you can consider storing it in a ViewModel so that you don't need to ask for the generator again when the activity needs to recreate (like when the configuration has changed while the app is running).

Sample code

### Java

    package ...;

    ...
    import androidx.appcompat.app.AppCompatActivity;
    import com.google.android.libraries.searchinapps.GetSearchSuggestionsViewGeneratorCallback;
    import com.google.android.libraries.searchinapps.GetSearchSuggestionsViewOptions;
    import com.google.android.libraries.searchinapps.SearchInAppsService;
    import com.google.android.libraries.searchinapps.SearchSuggestionsViewGenerator;
    import java.util.Arrays;
    import java.util.List;
    ...

    public class MainActivity extends AppCompatActivity implements GetSearchSuggestionsViewGeneratorCallback {
      private SearchInAppsService service;

      @Override
      public void onSuccess(SearchSuggestionsViewGenerator generator) {
        ...
      }

      @Override
      public void onError(String errorMessage) {
        ...
      }

      @Override
      protected void onCreate(Bundle savedInstanceState) {
        ...
        service = SearchInAppsService.create(this);
        // Right now only the first element of this list will be used.
      List<String> searchContext = Arrays.asList(new String[]{"This is a test query, for example."});
        // Uses the default SearchSuggestionsViewOptions.
        service.getSearchSuggestionsView(
          new GetSearchSuggestionsViewOptions().setTextContext(searchContext),this);
        ...
      }

      @Override
      public void onDestroy() {
        service.shutDown();
        super.onDestroy();
      }
    }

### Jetpack Compose

    package ...

    ...
    import android.os.Bundle
    import androidx.activity.compose.setContent
    import androidx.appcompat.app.AppCompatActivity
    import androidx.compose.runtime.Composable
    import androidx.compose.runtime.DisposableEffect
    import androidx.compose.runtime.mutableStateOf
    import androidx.compose.ui.platform.LocalContext
    import com.google.android.libraries.searchinapps.GetSearchSuggestionsViewGeneratorCallback
    import com.google.android.libraries.searchinapps.GetSearchSuggestionsViewOptions
    import com.google.android.libraries.searchinapps.SearchInAppsService
    import com.google.android.libraries.searchinapps.SearchSuggestionsViewGenerator
    ...

    class MainActivity : AppCompatActivity() {
      override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
          SearchSuggestionsUI()
        }
      }

      @Composable
      fun SearchSuggestionsUI() {
        ...
        var service by remember {
          mutableStateOf<SearchInAppsService?>(
            SearchInAppsService.create(LocalContext.current))
        }
        DisposableEffect(Unit) { onDispose { service?.shutDown() } }
        val callback =
                  object : GetSearchSuggestionsViewGeneratorCallback {
                    override fun onSuccess(generator: SearchSuggestionsViewGenerator) {
                      ...
                    }

                  override fun onError(errorMessage: String) {
                    ...
                  }
                }
      var searchContexts: List<String> = listOf<String>("Query")
      // Uses the default SearchSuggestionsViewOptions.
      var options: GetSearchSuggestionsViewOptions =
                GetSearchSuggestionsViewOptions()
                  .setTextContext(searchContexts)
      service?.getSearchSuggestionsView(options, callback)
      ...
     }
    }

### Request location-based search suggestions

The `getSearchSuggestionsView` entry point also supports location-based search
suggestions. Build a `GetSearchSuggestionsViewOptions` object with a list of
`LocationContext` objects following these steps. Then, pass the
`GetSearchSuggestionsViewOptions` to the `getSearchSuggestionsView` function,
following the steps in the previous section.

1. (Required) Build the `LocationContext` object with the `GeographicalRestrictions` object. The `GeographicalRestrictions` object takes a `CircularArea` object which contains the latitude and longitude of the center of the area and the radius of the area.
2. (Optional) Build the `TimeRestrictions` object with the `TimeSegment` object. The `TimeSegment` object takes a string which represents the time segment in the ISO 8601 format.
3. (Optional) Build the `GeoTypeRestrictions` object with the requested geo types. Provided types are used to adjust the ranking and filtering of results returned by the service. The supported values are: "restaurant", "cafe", "bar", "park", "zoo", "museum", "attraction", "atm", "bank", "hair_salon", "real_estate_agency", "bicycle_sharing_location", "car_rental_agency", "shopping_center", "grocery_store" and "hotel".

Sample code

### Java

    package ...;

    ...
    import com.google.android.libraries.searchinapps.GetSearchSuggestionsViewGeneratorCallback;
    import com.google.android.libraries.searchinapps.GetSearchSuggestionsViewOptions;
    import com.google.android.libraries.searchinapps.LocationContext;
    import com.google.android.libraries.searchinapps.LocationContext.CircularArea;
    import com.google.android.libraries.searchinapps.LocationContext.GeoTypeRestrictions;
    import com.google.android.libraries.searchinapps.LocationContext.GeographicalRestrictions;
    import com.google.android.libraries.searchinapps.LocationContext.LatLng;
    import com.google.android.libraries.searchinapps.LocationContext.TimeRestrictions;
    import com.google.android.libraries.searchinapps.LocationContext.TimeSegment;
    import com.google.android.libraries.searchinapps.SearchInAppsService;
    import com.google.android.libraries.searchinapps.SearchSuggestionsViewGenerator;
    ...
    LocationContext locationContext = new LocationContext(
        new GeographicalRestrictions(
            new CircularArea(
                new LatLng(
                    40.7414728,
                    -74.0059622),
                    1000)))
        // Optional. If set, the returned suggestions are categories of which
        // there are several businesses in the requested area that are open at
        // the given time.
        .setTimeRestrictions(
          new TimeRestrictions(
            new TimeSegment("2024-05-18T19:20:30.45+01:00")))
        // Optional. If set, the returned suggestions are subset of the
        // requested categories.
        .setGeoTypeRestrictions(
          new GeoTypeRestrictions("restaurant", "parks"));

    // Uses the default SearchSuggestionsViewOptions.
    service = SearchInAppsService.create(this);
    // Uses the default SearchSuggestionsViewOptions.
    service.getSearchSuggestionsView(
      new GetSearchSuggestionsViewOptions().setLocationContext(Arrays.asList(locationContext)), this);

### Jetpack Compose

    package ...

    ...
    import com.google.android.libraries.searchinapps.GetSearchSuggestionsViewGeneratorCallback
    import com.google.android.libraries.searchinapps.GetSearchSuggestionsViewOptions
    import com.google.android.libraries.searchinapps.LocationContext
    import com.google.android.libraries.searchinapps.LocationContext.CircularArea
    import com.google.android.libraries.searchinapps.LocationContext.GeoTypeRestrictions
    import com.google.android.libraries.searchinapps.LocationContext.GeographicalRestrictions
    import com.google.android.libraries.searchinapps.LocationContext.LatLng
    import com.google.android.libraries.searchinapps.LocationContext.TimeRestrictions
    import com.google.android.libraries.searchinapps.LocationContext.TimeSegment
    import com.google.android.libraries.searchinapps.SearchInAppsService
    import com.google.android.libraries.searchinapps.SearchSuggestionsViewGenerator
    ...

    var locationContext: LocationContext = LocationContext(
      GeographicalRestrictions(
        CircularArea(
          LatLng(40.7414728, -74.0059622),
          1000)))
      // Optional. If set, there are several businesses in the requested area that
      // are open at the given time.
      .setTimeRestrictions(
        TimeRestrictions(
          TimeSegment("2024-05-18T19:20:30.45+01:00")))
      // Optional. If set, the returned suggestions are subset of the requested
      // categories.
      .setGeoTypeRestrictions(
        GeoTypeRestrictions("restaurant", "parks"))

    // Uses the default SearchSuggestionsViewOptions.
    var options: GetSearchSuggestionsViewOptions =
              GetSearchSuggestionsViewOptions()
                .setLocationContext(listOf<LocationContext>(locationContext))
    service.getSearchSuggestionsView(options, callback)
    ...

## Add search suggestions UI view

For `getSearchSuggestionsView`, the final output is a
`SearchSuggestionsViewGenerator` object. You can use this object's
`populateView(Context)` function to generate the UI view and `updateView(View)`
to update the existing view (especially for Jetpack Compose apps).

For Jetpack Compose apps, you should use [AndroidView](https://developer.android.com/jetpack/compose/migrate/interoperability-apis/views-in-compose) to consume the
generated classic view.

Sample code

### Java

    package ...;

    ...
    import androidx.appcompat.app.AppCompatActivity;
    import com.google.android.libraries.searchinapps.GetSearchSuggestionsViewGeneratorCallback;
    import com.google.android.libraries.searchinapps.GetSearchSuggestionsViewOptions;
    import com.google.android.libraries.searchinapps.SearchInAppsService;
    import com.google.android.libraries.searchinapps.SearchSuggestionsViewGenerator;
    import java.util.Arrays;
    import java.util.List;
    ...

    public class MainActivity extends AppCompatActivity implements GetSearchSuggestionsViewGeneratorCallback {
      private SearchInAppsService service;

      @Override
      public void onSuccess(SearchSuggestionsViewGenerator generator) {
        ViewGroup container = findViewById(R.id.[container_id]);
        container.removeAllViews();
        container.addView(generator.populateView(this));
      }

      @Override
      public void onError(String errorMessage) {
        ...
      }

      @Override
      protected void onCreate(Bundle savedInstanceState) {
        ...
        service = SearchInAppsService.create(this);
        List<String> searchContext = Arrays.asList(new String[]{"Query"});
        // Uses the default SearchSuggestionsViewOptions.
        service.getSearchSuggestionsView(
          new GetSearchSuggestionsViewOptions().setTextContext(searchContext),this);
        ...
      }

      @Override
      public void onDestroy() {
        service.shutDown();
        super.onDestroy();
      }
    }

### Jetpack Compose

    package ...

    ...
    import android.os.Bundle
    import androidx.activity.compose.setContent
    import androidx.appcompat.app.AppCompatActivity
    import androidx.compose.runtime.Composable
    import androidx.compose.runtime.DisposableEffect
    import androidx.compose.runtime.MutableState
    import androidx.compose.runtime.mutableStateOf
    import androidx.compose.ui.platform.LocalContext
    import androidx.compose.ui.viewinterop.AndroidView
    import com.google.android.libraries.searchinapps.GetSearchSuggestionsViewGeneratorCallback
    import com.google.android.libraries.searchinapps.GetSearchSuggestionsViewOptions
    import com.google.android.libraries.searchinapps.SearchInAppsService
    import com.google.android.libraries.searchinapps.SearchSuggestionsViewGenerator
    ...

    class MainActivity : AppCompatActivity() {
      override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent { SearchSuggestionsUI() }
      }

      @Composable
      fun SearchSuggestionsUI() {
        ...
        var service by remember {
          mutableStateOf<SearchInAppsService?>(
            SearchInAppsService.create(LocalContext.current))
        }
        var viewGenerator = mutableStateOf<SearchSuggestionsViewGenerator?>(null)
        DisposableEffect(Unit) { onDispose { service?.shutDown() } }
        val callback =
          object : GetSearchSuggestionsViewGeneratorCallback {
            override fun onSuccess(generator: SearchSuggestionsViewGenerator) {
              viewGenerator.value = generator
            }

          override fun onError(errorMessage: String) {}
        }
      var searchContexts: List<String> = listOf<String>("Query")
      // Uses the default SearchSuggestionsViewOptions.
      var options: GetSearchSuggestionsViewOptions =
        GetSearchSuggestionsViewOptions().setTextContext(searchContexts)
      service?.getSearchSuggestionsView(options, callback)
      ChipGroupUI(viewGenerator)
      ...
    }

      @Composable
      fun ChipGroupUI(viewGenerator: MutableState<SearchSuggestionsViewGenerator?>) {
        viewGenerator.value?.let { viewGenerator ->
          var context = LocalContext.current
          AndroidView(
            factory = { context -> viewGenerator.populateView(context) },
            update = { view -> viewGenerator.updateView(view, context) },
          )
        }
      }
    }

[Next: Display search results](https://developers.google.com/search-in-apps/android/display_search_results)