Android studio searchview listener

Android: SearchView with custom suggestions without ContentProvider

In this (hopefully) short tutorial I’m going to provide step-by-step instructions on how to setup a SearchView which retrieves custom suggestions in real time from your back-end server. Reading Android official docs on this topic may seem somewhat confusing, especially if you’re not familiar with ContentProviders . So here I’m posting my solution which doesn’t include ContentProviders and is much simpler.

If you want to skip the details and get straight to the full code feel free to scroll down to the bottom, I’m posting the whole Activity implementation there. Otherwise, let’s begin!

Setup

Dependencies

In this tutorial I’m going to use RxJava2 and Retrofit libraries to handle asynchronous calls to my server. If you’re not yet, I highly recommend using them in your Android development.

Make sure to include support libraries in your project’s gradle file. The latest version at the time of writing is 28:

  • implementation ‘com.android.support:appcompat-v7:28.0.0’
  • implementation ‘com.android.support:support-v4:28.0.0’

Activity

The activity must either implement custom toolbar or use Theme.AppCompat.Light theme or any other theme that has an embedded toolbar.

The process

1. Create action menu file for your toolbar

In the res folder inside your project create a new folder called menu . Inside the folder, create a new xml file called search_menu.xml This file will contain quick action items for your toolbar. Here’s what it looks like: [xml]

  • showAsAction This property is set so that the item will collapse into three dot menu if there’s no enough space in the toolbar
  • actionViewClass this property is important. It specifies the view that will be presented when the item is clicked
  • icon I used a simple vector image for the icon

2. Override onCreateOptionsMenu in your activity

First let me show you the whole method and then I’ll explain it:

  • Line 3 adds action menu items you created earlier to your toolbar.
  • Lines 6 to 13 create references to SearchManager and SearchView components and set up necessary properties, like query hint.
  • Line 14 creates a list of columns used from the result to populate the suggestion list, in this example we’re only going to display user’s username
  • Line 15 creates a list of ids of the views which will be populated with the result rows, in this example we’re using list items provided by the android resource library.
  • Lines 16 and 17 create a CursorAdapter which is used by the SearchView to display the suggestions. We’re using SimpleCursorAdapter provided by the Android.
  • Finally lines 21 and 22 setup listeners which are used to trigger the events.

3. Setup listeners

Now let’s talk about getOnSuggestionClickListener() and getOnQueryTextListener(activity, adapter) methods which return the listeners that are used by the SearchView . I’ll start with getOnQueryTextListener. This is a listener that gets triggered every time the user types something in the SearchView . This is what it looks like:

The method returns a new instance of the SearchView.OnQueryTextListener which implements two methods:

  • onQueryTextSubmit which is triggered when the user clicks on the submit button in the SearchView
  • onQueryTextChange which gets triggered when the user starts typing.

In this example we’re only going to worry about onQueryTextChange to provide the users with the real-time suggestions as they type. onQueryTextChange method uses the RxJava to make an asynchronous call to my back-end server and subscribes to it on the main thread using AndroidSchedulers.mainThread() .

Again if you’re not familiar with RxJava I highly recommend using, I’ve only started using it recently and it already helped me avoid tons of boilerplate code. It’s the best library so far to deal with Android’s rule about not blocking the main thread.

Читайте также:  Как синхронизировать два андроида между собой через блютуз

I don’t know about you but I don’t like long methods. So I created a separate method for getting the Observer which receives the results of the query on the main thread. Here’s what it looks like:

Don’t worry if you’re not familiar with the Observer implementation, it’s a part of RxJava. The important part here is onNext method. This method creates a Cursor and assigns it to the CursorAdapter we created earlier using swapCursor . Calling swapCursor will magically make the SearchView display the result of the query.

Following my principle of splitting long methods I wrote a separate createCursorFromResult(users) method which creates a Cursor object from the users result. Here’s the implementation:

This method creates an array of columns which will be present in the Cursor using static constants provided by the Android. BaseColumns._ID is mandatory in any cursor, the other two are required for our implementation. Then we create a new instance of a MatrixCursor and pass the column array in the constructor. Finally, we iterate over the query result and for each item we insert a new row in the cursor.

The only thing left is getOnSuggestionClickListener() method which returns a listener that gets triggered whenever the user clicks on the suggestions in the SearchView :

This method returns a new instance of SearchView.OnSuggestionListener which is triggered whenever the users clicks on the suggestion. As you can see I left the implementation of the listener methods for you to finish as you see fit.

As promised here’s the full implementation of the Activity :

That’s the end of this short tutorial. Hopefully you were able to follow along and set up the SearchView in your own app.

Источник

Русские Блоги

Использование SearchView в Android

Уважаемые одноклассники, я снова здесь и готов к вождению. , ,

Я не знаю, что вы обычно используете для прослушивания музыки, мне лично нравится NetEase Cloud Music (Не реклама, но что я делаю?), но теперь NetEase Cloud Music не может остановить песню Джея Чоу, это немного. , , В тот день я неожиданно подумал о MaterialDesign, который я недавно изучал, и о том, как реализована строка заголовка NetEase Cloud Music. Позже я использовал различные Baidus, и мои усилия окупились. Я наконец-то понял это! На самом деле, NetEase Cloud Music использует SearchView, упомянутый в заголовке, который фактически является поисковым. Так как это достигается? Пожалуйста, послушайте разложение в следующий раз!

[Загрузка изображений за пределы сайта . (image-41ace8-1524489658384)]

Шучу, студенты готовы и сразу поехали. , ,

Очки знаний в этой статье

  • Введение в SearchView
  • Реализуйте функцию поиска в NetEase Cloud Music
    • Реализация базовой функции поиска
    • Украшение страницы
    • Некоторые общие проблемы

Позвольте мне кратко объяснить, здесь в основном объясняется, как SearchView реализует строку заголовка NetEase Cloud Music, но все они основаны на Панели инструментов, если вы мало знаете о Панели инструментов и меню!

Пожалуйста, смотрите эти две статьи на моем публичном аккаунте (сильная волна выхода)

Выше подробно объяснено использование и меры предосторожности панели инструментов и меню! ! !

1. Введение в SearchView

SearchView — это элемент управления поиском, который связан с панелью инструментов и задается через меню (я не знаю, можете ли вы понять, как я его обобщил). Кнопка поиска появится в правой части панели инструментов (система поставляется с ней, вы также можете заменить ее). Когда вы нажмете кнопку поиска, появится соответствующее окно редактирования для поиска. При нажатии на крестик этот поиск отменяется, а кнопка поиска восстанавливается.

2. Функция поиска NetEase Cloud Music

2.1 Базовая реализация функции поиска

Вот некоторые изменения в меню, поэтому оно может не совпадать с вашим базовым эффектом, но я опубликую соответствующий контент, чтобы оно было удобно для ленивых больных раком, таких как я, и могло быстро достичь эффекта. В конце концов, когда проект разработки плотный, мне все равно, как его достичь! ! ! Сначала посмотрите на рендеринг основных функций

[Загрузка изображений за пределы сайта . (image-35b1ae-1524489658384)]

Я считаю, что если вы прочтете две предыдущие статьи, вы скоро сможете написать строку заголовка ниже.

  • Код файла меню
  • Код файла макета
  • Код в деятельности

Запустите приведенный выше код, и тогда вы сможете увидеть вышеуказанный контент!

2.1.1 Инициализация и мониторинг кнопки поиска

Потому что, когда вы инициализируете SearcheView, вам нужно работать с соответствующим меню, поэтому оно обычно будет в onCreateOptionsMenu(Menu menu) Получить его в. Конкретный код выглядит следующим образом:

Обратите внимание, что это также может быть использовано при инициализации SearchView MenuItemCompat.getActionView(searchItem); Приобретение только устарело. , , Так что не говорите, что не знаете, видите ли вы это

  • Соответствующий монитор setOnQueryTextListener(OnQueryTextListener listener)

Может ли вышеуказанный контент реализовать простой поиск? На самом деле я лично считаю, что этого мало? Почему ты это сказал? Поскольку вы хотите контролировать переключение фрагментов, нет соответствующей временной точки или нет времени для переключения фрагментов. Я долго думал об этом. Позже, когда я увидел исходный код, я обнаружил, что время проекта Google на самом деле Я уже думал об этом для нас. На самом деле, я думаю, что мы можем думать, инженеры Google поймут это для нас!

  • setOnSearchClickListener (OnClickListener listener) Метод для обратного вызова при нажатии значка поиска.
  • setOnCloseListener (OnCloseListener listener) Метод для обратного вызова при переходе после поиска.
Читайте также:  Удалить страницу с баду с андроида

Таким образом, есть соответствующий момент времени. Когда вы входите, открываете вещь и вставляете фрагмент (здесь, если вы хотите добавить эффекты анимации, вы можете использовать ViewPager, а затем переключиться, установив метод для отображения этого. На самом деле, вещи тоже Вы можете установить анимацию, это зависит от того, как вы выберете). Когда вы нажимаете закрыть. Просто замените предыдущий фрагмент. Чтобы все лучше поняли, позвольте мне реализовать это в коде! Давайте посмотрим на эффект (виртуальная машина немного глупа!)

  • На самом деле никаких изменений в xml нет, поэтому я не буду публиковать их!
  • Код в Activity является наиболее важным, код выглядит следующим образом:

Здесь важнее всего эти мониторы. Пока вы понимаете мониторы, в принципе проблем не будет.

Таким образом, соответствующий эффект может быть достигнут. как насчет этого? Не плохо, верно! ! !

2.2 Украшение интерфейса

2.2.1 Текст приглашения по умолчанию

Приведенное выше изображение отображается, когда текст подсказки отсутствует. Как добавить текст подсказки?

Вы можете добавить текст запроса поиска через вышеуказанный код.

2.2.2 Кнопка поиска не исчезает

Эта кнопка поиска находится внутри поля ввода.При настройке содержимого кнопка поиска исчезнет. Я чувствую, что то, что я описал, не правильно, что с ним? Пока ты понимаешь. , ,

  • setIconifiedByDefault (boolean iconified) Этот Api в основном контролирует, находится ли кнопка поиска внутри поля ввода, true означает, что она отображается внутри, а false означает, что она отображается снаружи

2.2.3 Кнопка поиска, чтобы отменить проблему закрытия значка

У некоторых менеджеров по продукту всегда есть странные потребности и они хотят убрать крест после поиска. Скажи бесчеловечность. , , Может быть изменено только тихо. , , На самом деле, мое сердце разбито. , ,

  • onActionViewExpanded () устанавливает API, чтобы значок закрытия не отображался

Хотя вы можете отключить этот значок, в этом случае есть проблема: операция отключения и переключения фрагмента, записанного ранее, будет здесь недействительной. Как это решить? Подумав об этом в течение долгого времени, мне нужно иметь дело только с событием возврата, или у меня нет возможности узнать, когда пользователь действительно, когда поиск завершен? Только тогда, когда будет выполнена операция возврата и когда она закончится!

Добавьте этот код, получите onDloseClicked () SearchView через отражение, просто вызовите его

2.2.4 Расширение панели поиска по умолчанию

Продукт снова сказал. Когда вы входите на эту страницу, диалоговое окно поиска должно отображаться по умолчанию. Пользователю требуется на одну операцию меньше и удобство работы. Я сказал в то время. Как насчет пользователя? Продукт говорит, что такой странный пользователь не заботится. , , (Я был в то время! Моя голова была полна черных линий)

  • setIconified (boolean iconify) Установить, будет ли расширено поле ввода поиска, обратите внимание здесь! false означает расширенный, true означает закрытый

2.2.5 Изменить значок поиска или удалить значок

Продукты Laogen не собираются работать! Я посмотрел на значок поиска и подумал, что он маленький, я хочу изменить его! Как это сделать?

В теме Активность на странице, добавьте соответствующийsearchViewStyleСвойство, это свойство может быть установлено самостоятельно.

Изображение здесь зависит от вашей игры. , ,

2.2.6 Изменить цвет текста

Если вы считаете, что текст в поле ввода или текст приглашения выглядят чёрно-черными, вы можете изменить его следующим образом.

Я не знаю, есть ли что-нибудь еще. Я думаю, этого достаточно, чтобы иметь дело с вашими менеджерами по продукту. Вы не можете положить нож на стол или положить QR-код или что-то еще. , ,

Я надеюсь, что моя статья будет полезна для вас! Надеюсь, мы добьемся прогресса вместе. , , увидимся!

Источник

Реализация мгновенного поиска в Android с помощью RxJava

Я работаю над новым приложением, которое, как это обычно и происходит, связывается с бэкенд-сервисом для получения данных через API. В этом примере я буду разрабатывать функцию поиска, одной из особенностей которого будет мгновенный поиск прямо во время ввода текста.

Мгновенный поиск

Ничего сложного, подумаете вы. Нужно просто разместить компонент поиска на странице (скорее всего, в тулбаре), подключить обработчик событий onTextChange и выполнить поиск. Итак, вот что я сделал:

Читайте также:  Как передавать данные с андроида по блютуз

Но вот в чём проблема. Поскольку мне необходимо реализовать поиск прямо во время ввода, то всякий раз, когда срабатывает обработчик события onQueryTextChange() , я обращаюсь к API для получения первого набора результатов. Логи выглядят следующим образом:

Несмотря на то, что я просто печатаю свой запрос, происходит пять вызовов API, каждый из которых выполняет поиск. Например, в облаке вам необходимо платить за каждое обращение к API. Таким образом, когда я ввожу свой запрос, мне нужна небольшая задержка перед его отправлением, чтобы в итоге состоялось только одно обращение к API.

Теперь, предположим, я хочу найти что-нибудь ещё. Я удаляю TEST и ввожу другие символы:

Происходит 20 вызовов API! Небольшая задержка сократит количество этих вызовов. Я также хочу избавиться от дубликатов, чтобы обрезанный текст не приводил к повторным запросам. Ещё я, вероятно, захочу отфильтровать некоторые элементы. Например, нужна ли возможность поиска без введённых символов или поиска по одному символу?

Реактивное программирование

Есть несколько вариантов дальнейших действий, но прямо сейчас я хочу сосредоточиться на технике, которая широко известна как реактивное программирование и библиотека RxJava. Когда я впервые столкнулся с реактивным программированием, то увидел следующее описание:

ReactiveX — это API, который работает с асинхронными структурами и манипулирует потоками данных или событиями, используя сочетания паттернов Observer и Iterator, а также особенности функционального программирования.

Это определение не полностью объясняет сущность и сильные стороны ReactiveX. А если и объясняет, то только тем, кто уже знаком с принципами работы этого фреймворка. Я также видел такие диаграммы:

Диаграмма объясняет роль оператора, но не позволяет полностью разобраться в сути. Итак, давайте посмотрим, смогу ли я понятнее объяснить данную диаграмму на простом примере.

Давайте сначала подготовим наш проект. Вам понадобится новая библиотека в файле build.gradle вашего приложения:

Не забудьте синхронизировать зависимости проекта, чтобы загрузить библиотеку.

Теперь давайте рассмотрим новое решение. Используя старый метод, я обращался к API при вводе каждого нового символа. C помощью нового способа я собираюсь создать Observable :

Этот код выполняет абсолютно то же самое, что и старый код. Логи выглядят следующим образом:

Тем не менее, ключевое отличие использования нового приёма заключается в наличии реактивного потока — Observable . Обработчик текста (или обработчик запроса в данном случае) отправляет элементы в поток, используя метод onNext() . А у Observable есть подписчики, которые и обрабатывают эти элементы.

Мы можем создать цепочку методов перед подпиской, чтобы уменьшить список строк для обработки. Начнём с того, что отправленный текст всегда будет находиться в нижнем регистре и в нём не будет пробелов в начале и конце строки:

Я сократил методы, чтобы показать наиболее значимую часть. Теперь те же логи выглядит следующим образом:

Теперь давайте применим задержку на 250мс, ожидая большего количества контента:

И, наконец, удалим дубликаты потока, чтобы только первый уникальный запрос был обработан. Последующие идентичные запросы будут игнорироваться:

Прим. перев. В данном случае разумнее использовать оператор distinctUntilChanged() , потому что иначе в случае повторного поиска по какой-либо строке запрос просто проигнорируется. А при реализации такого поиска разумно обращать внимание только на последний успешный запрос и игнорировать новый в случае его идентичности с предыдущим.

В конце отфильтруем пустые запросы:

На этом этапе вы заметите, что выводится только одно (или, может быть, два) сообщение в логах, что говорит о меньшем количестве вызовов API. При этом приложение будет продолжать адекватно работать. Более того, случаи, когда вы вводите что-либо, но затем удаляете и вводите снова, также приведут к меньшему количеству обращений к API.

Существует ещё много различных операторов, которые вы можете добавить в этот пайплайн в зависимости от ваших целей. Я считаю, что они весьма полезны для работы с полями ввода, которые взаимодействуют с API. Полный код выглядит следующим образом:

Теперь я могу заменить сообщение логов обращением ко ViewModel, чтобы инициировать вызов API. Однако это уже тема для другой статьи.

Заключение

С помощью этой простой техники обёртывания текстовых элементов в Observable и использования RxJava вы можете сократить количество вызовов API, которые необходимы для выполнения операций с сервером, а также улучшить отзывчивость вашего приложения. В этой статье мы затронули лишь малую часть целого мира RxJava, поэтому я оставляю вам ссылки для дополнительного чтения на эту тему:

  • Grokking RxJava от Дэна Лью (это сайт, который помог меня двигаться в правильном направлении).
  • Сайт ReactiveX (я часто ссылаюсь на этот сайт при построении пайплайнов).

Источник

Оцените статью