@SuppressLint("SetTextI18n")
    private SearchCardView addSearchCardWithField(final int title, final int suggestionIcon, @Nullable @StringRes final Integer recentPostfix, @NonNull final Consumer<String> searchFunction, final Func1<String, String[]> suggestionFunction, final Func0<String[]> historyFunction, final InputFilter inputFilter) {
        return addSearchCard(title, suggestionIcon).addOnClickListener(() -> {
            // show search field
            searchViewItem.setVisible(true);
            searchViewItem.expandActionView();
            searchButtonItem.setVisible(true);
            searchView.setMinWidth(((View) searchView.getParent()).getWidth());
            binding.mostRecent.setVisibility(View.GONE);

            // icon in search field
            final Drawable drw = AppCompatResources.getDrawable(this, suggestionIcon);
            drw.setTint(getResources().getColor(R.color.colorTextActionBar));
            drw.setBounds(0, 0, (int) searchView.getTextSize(), (int) searchView.getTextSize());
            searchView.setCompoundDrawables(drw, null, null, null);
            searchView.setCompoundDrawablePadding(16);
            searchView.setHint(title);

            // Submit function
            searchView.setOnEditorActionListener((v, actionId, event) -> {
                if (actionId == EditorInfo.IME_ACTION_SEARCH && (null == event || event.getAction() == KeyEvent.ACTION_DOWN)) {
                    storeMostRecent(recentPostfix, getSearchFieldInput());
                    searchFunction.accept(getSearchFieldInput());
                    searchPerformed = true;
                    return true;
                }
                return false;
            });
            searchButtonItem.setOnMenuItemClickListener(v -> {
                storeMostRecent(recentPostfix, getSearchFieldInput());
                searchFunction.accept(getSearchFieldInput());
                searchPerformed = true;
                return true;
            });

            // Default value
            searchView.setText("");

            // suggestion handler
            binding.suggestionList.setOnItemClickListener((parent, view, position, id) -> {
                final String searchTerm = (String) parent.getItemAtPosition(position);
                searchFunction.accept(searchTerm);
            });
            binding.suggestionList.setOnItemLongClickListener((parent, view, position, id) -> {
                final String searchTerm = (String) parent.getItemAtPosition(position);
                searchView.setText(searchTerm);
                searchView.setSelection(searchView.getText().length());
                return true;
            });

            if (title == R.string.search_geo) {
                searchView.setText("GC");
                binding.suggestionList.setAdapter(new GeocacheAutoCompleteAdapter.GeocodeAutoCompleteAdapter(searchView.getContext(), suggestionFunction, historyFunction));
                final String clipboardGeocode = getGeocodeFromClipboard();
                if (null != clipboardGeocode) {
                    binding.suggestionList.postDelayed(() -> {
                        binding.clipboardGeocode.setVisibility(View.VISIBLE);
                        ((TextView) binding.clipboardGeocode.findViewById(R.id.text)).setText(clipboardGeocode);
                        ((TextView) binding.clipboardGeocode.findViewById(R.id.info)).setText(R.string.from_clipboard);
                        ((ImageView) binding.clipboardGeocode.findViewById(R.id.icon)).setImageDrawable(AppCompatResources.getDrawable(this, R.drawable.search_clipboard));
                        binding.clipboardGeocode.setOnClickListener(v -> findByGeocodeFn(clipboardGeocode));
                    }, 0);
                }
            } else if (title == R.string.search_kw) {
                binding.suggestionList.setAdapter(new GeocacheAutoCompleteAdapter.KeywordAutoCompleteAdapter(searchView.getContext(), suggestionFunction, historyFunction));
                binding.suggestionList.setOnItemClickListener((parent, view, position, id) -> {
                    final String searchTerm = (String) parent.getItemAtPosition(position);
                    // suggestions are a mix of geocodes and keywords, differentiate them by layout used
                    if (null == view.findViewById(R.id.info)) {
                        findByKeywordFn(searchTerm);
                    } else {
                        findByGeocodeFn(searchTerm);
                    }
                });
            } else {
                binding.suggestionList.setAdapter(new SearchAutoCompleteAdapter(searchView.getContext(), R.layout.search_suggestion, suggestionFunction, suggestionIcon, historyFunction));
            }
            checkMostRecent(recentPostfix);
            updateSuggestions();

            // caps keyboard
            if (inputFilter != null) {
                searchView.setFilters(new InputFilter[] { inputFilter });
            } else {
                searchView.setFilters(new InputFilter[] { });
            }

            // show keyboard and place cursor
            searchView.setSelection(searchView.getText().length());
            Keyboard.show(this, searchView);
        });
    }
try to interpret query as trackable

@param query         Trimmed string to search for
@param keywordSearch Set to true if keyword search should be performed if query isn't GC or TB
@return true if trackable was found
main/src/main/java/cgeo/geocaching/SearchActivity.java