├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── app ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── br │ │ └── com │ │ └── mauker │ │ ├── MsvAuthority.kt │ │ └── materialsearchview │ │ └── app │ │ └── MainActivity.kt │ └── res │ ├── layout │ └── activity_main.xml │ ├── menu │ └── menu_main.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── values-pt-rBR │ └── strings.xml │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── library ├── build.gradle ├── proguard-android.txt └── src │ ├── androidTest │ └── java │ │ └── br │ │ └── com │ │ └── mauker │ │ └── materialsearchview │ │ └── HistoryProviderTest.kt │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── br │ │ └── com │ │ └── mauker │ │ └── materialsearchview │ │ ├── MaterialSearchView.kt │ │ ├── adapters │ │ └── CursorSearchAdapter.kt │ │ ├── db │ │ ├── HistoryContract.kt │ │ ├── HistoryDbHelper.kt │ │ └── HistoryProvider.kt │ │ └── utils │ │ └── AnimationUtils.kt │ └── res │ ├── drawable │ ├── ic_action_navigation_arrow_back.xml │ ├── ic_action_navigation_close.xml │ ├── ic_action_search_white.xml │ ├── ic_action_voice_search.xml │ └── ic_history_white.xml │ ├── layout │ ├── list_item.xml │ └── search_view.xml │ ├── values-bs │ └── strings.xml │ ├── values-es │ └── strings.xml │ ├── values-fr │ └── strings.xml │ ├── values-hr │ └── strings.xml │ ├── values-it │ └── strings.xml │ ├── values-nl │ └── strings.xml │ ├── values-pt-rBR │ └── strings.xml │ ├── values-sr │ └── strings.xml │ └── values │ ├── attrs.xml │ ├── colors.xml │ ├── dimens.xml │ └── strings.xml └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io/api/android,osx,windows,linux,intellij,java 2 | 3 | ### Android ### 4 | # Built application files 5 | *.apk 6 | *.ap_ 7 | 8 | # Files for the Dalvik VM 9 | *.dex 10 | 11 | # Java class files 12 | *.class 13 | 14 | # Generated files 15 | bin/ 16 | gen/ 17 | 18 | # Gradle files 19 | .gradle/ 20 | build/ 21 | gradlew 22 | gradlew.bat 23 | gradle/wrapper/gradle-wrapper.properties 24 | 25 | # Local configuration file (sdk path, etc) 26 | local.properties 27 | 28 | # Proguard folder generated by Eclipse 29 | proguard/ 30 | 31 | # Log Files 32 | *.log 33 | 34 | # Android Studio Navigation editor temp files 35 | .navigation/ 36 | 37 | ### Android Patch ### 38 | gen-external-apklibs 39 | 40 | 41 | ### OSX ### 42 | .DS_Store 43 | .AppleDouble 44 | .LSOverride 45 | 46 | # Icon must end with two \r 47 | Icon 48 | 49 | 50 | # Thumbnails 51 | ._* 52 | 53 | # Files that might appear in the root of a volume 54 | .DocumentRevisions-V100 55 | .fseventsd 56 | .Spotlight-V100 57 | .TemporaryItems 58 | .Trashes 59 | .VolumeIcon.icns 60 | 61 | # Directories potentially created on remote AFP share 62 | .AppleDB 63 | .AppleDesktop 64 | Network Trash Folder 65 | Temporary Items 66 | .apdisk 67 | 68 | 69 | ### Windows ### 70 | # Windows image file caches 71 | Thumbs.db 72 | ehthumbs.db 73 | 74 | # Folder config file 75 | Desktop.ini 76 | 77 | # Recycle Bin used on file shares 78 | $RECYCLE.BIN/ 79 | 80 | # Windows Installer files 81 | *.cab 82 | *.msi 83 | *.msm 84 | *.msp 85 | 86 | # Windows shortcuts 87 | *.lnk 88 | 89 | 90 | ### Linux ### 91 | *~ 92 | 93 | # KDE directory preferences 94 | .directory 95 | 96 | # Linux trash folder which might appear on any partition or disk 97 | .Trash-* 98 | 99 | 100 | ### Intellij ### 101 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio 102 | 103 | *.iml 104 | 105 | ## Directory-based project format: 106 | .idea/ 107 | # if you remove the above rule, at least ignore the following: 108 | 109 | # User-specific stuff: 110 | # .idea/workspace.xml 111 | # .idea/tasks.xml 112 | # .idea/dictionaries 113 | 114 | # Sensitive or high-churn files: 115 | # .idea/dataSources.ids 116 | # .idea/dataSources.xml 117 | # .idea/sqlDataSources.xml 118 | # .idea/dynamic.xml 119 | # .idea/uiDesigner.xml 120 | 121 | # Gradle: 122 | # .idea/gradle.xml 123 | # .idea/libraries 124 | 125 | # Mongo Explorer plugin: 126 | # .idea/mongoSettings.xml 127 | 128 | ## File-based project format: 129 | *.ipr 130 | *.iws 131 | 132 | ## Plugin-specific files: 133 | 134 | # IntelliJ 135 | /out/ 136 | 137 | # mpeltonen/sbt-idea plugin 138 | .idea_modules/ 139 | 140 | # JIRA plugin 141 | atlassian-ide-plugin.xml 142 | 143 | # Crashlytics plugin (for Android Studio and IntelliJ) 144 | com_crashlytics_export_strings.xml 145 | crashlytics.properties 146 | crashlytics-build.properties 147 | 148 | 149 | ### Java ### 150 | *.class 151 | 152 | # Mobile Tools for Java (J2ME) 153 | .mtj.tmp/ 154 | 155 | # Package Files # 156 | *.jar 157 | *.war 158 | *.ear 159 | 160 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 161 | hs_err_pid* 162 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: android 2 | 3 | before_install: 4 | - yes | sdkmanager "platforms;android-30" 5 | 6 | android: 7 | components: 8 | - tools 9 | - platform-tools 10 | - build-tools-30.0.2 11 | - extra-android-m2repository 12 | - extra-android-support 13 | - android-30 14 | 15 | jdk: 16 | - oraclejdk8 17 | 18 | script: 19 | - chmod +x gradlew 20 | - ./gradlew clean build --stacktrace --info 21 | 22 | 23 | notifications: 24 | email: false 25 | 26 | sudo: false 27 | 28 | cache: 29 | directories: 30 | - $HOME/.gradle 31 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | Change Log 2 | ========== 3 | 4 | ## Version 1.2.1 5 | 6 | _2017-03-20_ 7 | 8 | * Fixed a bug where MSV was crashing on devices with Kitkat or older due to the use of Vector Drawables. For more info on this issue, check [issue #92](https://github.com/Mauker1/MaterialSearchView/issues/92). 9 | 10 | ## Version 1.2.1 11 | 12 | _2017-03-16_ 13 | 14 | * You can now get the default adapter by calling `MaterialSearchView#getAdapter()` and have more control over it; 15 | * Added the `getCurrentQuery()` method, making it possible to get the query anywhere in the application; 16 | * Added the `setCloseOnTintClick(boolean)` method. If you set it to `true`, a touch outside the result list will close the `MaterialSearchView`, it'll remain open otherwise; 17 | * Added the `setSearchBarColor(int color)` method, where you can change specifically the search bar color; 18 | * The `saveQueryToDb()` method is now public, giving the programmer more control over when to save the queries; 19 | * The `setTintBackground(int color)` method is now private. It's been replaced by the public method `setBackgroundColor(int color)`; 20 | * Added French, Dutch, Bosnian, Croatian and Serbian translations. 21 | 22 | ## Version 1.2.0 23 | 24 | _2016-10-27_ 25 | 26 | * Suggestions can now be inserted and removed one by one; 27 | * It's now possible to change the voice hint prompt and the searchBarHeight; 28 | * MSV now have RTL support; 29 | * MSV now is correctly displayed with transparent status bar; 30 | * `CoordinatorLayout` was dropped. Now `FrameLayout` is the new root for MSV; 31 | * Added italian translation; 32 | * Bunch of bug fixes (See [this link](https://github.com/Mauker1/MaterialSearchView/milestone/2) for more information). 33 | 34 | ## Version 1.1.3 35 | 36 | _2016-08-14_ 37 | 38 | * Fixed a bug where `onQueryTextChanged` interface method was called multiple times; 39 | * Added `OnItemLongClickListener` on history/suggestion list; 40 | * Implemented an `OnClickListener` to the voice search icon, so it's possible to change the click behavior. 41 | 42 | ## Version 1.1.2 43 | 44 | _2016-07-19_ 45 | 46 | * Now it's possible to change the Search View input type. 47 | * Added the `getItemAtPosition()` method to simplify how you get the list item String. 48 | 49 | **e.g.:** `search_view.setInputType(InputType.TYPE_CLASS_TEXT);` 50 | 51 | ## Version 1.1.1 52 | 53 | _2016-06-23_ 54 | 55 | * Just some bug fixes. 56 | 57 | ## Version 1.1.0 58 | 59 | _2016-05-08_ 60 | 61 | * Solved the issue with the Content Provider authority, now it's possible to install multiple instances of this lib (Fix #7). 62 | * Added support for a transparent suggestion list. 63 | * Added support for styles, so now it's possible to change some of the look and feel of the Search View. 64 | * Now it's possible to change how many search history results the view will show. 65 | 66 | **Note:** To get the library to work, now you have to implement a class 67 | named `MsvAuthority` inside the `br.com.mauker` package, and it should 68 | have a public static String variable called `CONTENT_AUTHORITY`. 69 | Give it the value you want and don't forget to add the same name on your 70 | manifest file. 71 | 72 | More information, on [this link](http://stackoverflow.com/a/14592121/4070469). 73 | 74 | ## Version 1.0.3 75 | 76 | _2016-04-21_ 77 | 78 | Initial release. 79 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2016 Maurício Pessoa 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MaterialSearchView 2 | Android SearchView based on Material Design guidelines. The MaterialSearchView will overlay a Toolbar or ActionBar as well as display a ListView for the user to show suggested or recent searches. 3 | 4 | Stable: [![Download](https://img.shields.io/badge/download-1.3.0_rc02-blue.svg)](https://bintray.com/mauker/maven/MaterialSearchView/1.3.0-rc02) 5 | Beta: [![Download](https://img.shields.io/badge/download-2.0.0_beta02-blue.svg)](https://bintray.com/mauker/maven/MaterialSearchView/_latestVersion) 6 | 7 | [![Build Status](https://travis-ci.org/Mauker1/MaterialSearchView.svg?branch=master)](https://travis-ci.org/Mauker1/MaterialSearchView) 8 | ![APK size](https://img.shields.io/badge/Size-94KB-e91e63.svg) 9 | 10 | 11 | 12 | [![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-MaterialSearchView-green.svg?style=true)](https://android-arsenal.com/details/1/3469) 13 | [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/Mauker1/MaterialSearchView/blob/master/LICENSE) 14 | 15 | Buy Me a Coffee at ko-fi.com 16 | 17 | ## Download 18 | To add the MaterialSearchView library to your Android Studio project, simply add the following gradle dependency: 19 | ```java 20 | implementation 'br.com.mauker.materialsearchview:materialsearchview:1.3.0-rc02' 21 | ``` 22 | 23 | This library is supported with a min SDK of 14. 24 | 25 | **Important note:** If you're still using version 1.0.3, it's recommended to upgrade to the latest version as soon as possible. For more information, please see [this issue](https://github.com/Mauker1/MaterialSearchView/issues/7). 26 | 27 | **New version note**: MSV 2.0 is now on beta stage, if you wish to test it, get it by using: 28 | 29 | ```java 30 | implementation 'br.com.mauker.materialsearchview:materialsearchview:2.0.0-beta02' 31 | ``` 32 | 33 | **Version 2.0 doesn't require the Content Provider setup** and had some API changes which will be added to the documentation later on. For more details please take a look at the [V_2.0 branch](https://github.com/Mauker1/MaterialSearchView/tree/milestone/2_0). 34 | 35 | **Important note on V 2.0:** Since I'm using Coroutine Actors, which is marked as obsolete, you'll get a lint warning on each class that uses MSV, to get rid of those add this to your app `build.gradle` file: 36 | 37 | ``` 38 | kotlinOptions.freeCompilerArgs += [ 39 | "-Xuse-experimental=kotlinx.coroutines.ExperimentalCoroutinesApi", 40 | "-Xuse-experimental=kotlinx.coroutines.ObsoleteCoroutinesApi" 41 | ] 42 | ``` 43 | 44 | Once the Actors methods are updated, I'll update the lib as well. 45 | 46 | ## Setup 47 | 48 | Before you can use this lib, you have to implement a class named `MsvAuthority` inside the `br.com.mauker` package on your app module, and it should have a public static String variable called `CONTENT_AUTHORITY`. Give it the value you want and **don't forget** to add the same name on your manifest file. The lib will use this file to set the Content Provider authority. 49 | 50 | **Example:** 51 | 52 | **MsvAuthority.java** 53 | 54 | ```java 55 | package br.com.mauker; 56 | 57 | public class MsvAuthority { 58 | public static final String CONTENT_AUTHORITY = "br.com.mauker.materialsearchview.searchhistorydatabase"; 59 | } 60 | ``` 61 | 62 | Or if you're using Kotlin: 63 | 64 | **MsvAuthority.kt** 65 | ```Kotlin 66 | package br.com.mauker 67 | 68 | object MsvAuthority { 69 | const val CONTENT_AUTHORITY: String = "br.com.mauker.materialsearchview.searchhistorydatabase" 70 | } 71 | ``` 72 | 73 | **AndroidManifest.xml** 74 | 75 | ```xml 76 | 77 | 78 | 79 | 80 | 86 | 87 | 88 | 89 | ``` 90 | 91 | **Proguard note:** Some of you might experience some problems with Proguard deleting the authority class, to solve those problems, add the following lines on your proguard file: 92 | 93 | ``` 94 | -keep class br.com.mauker.MsvAuthority 95 | -keepclassmembers class br.com.mauker.** { *; } 96 | ``` 97 | 98 | ## Usage 99 | 100 | To open the search view on your app, add the following code **to the end of your layout**: 101 | 102 | ```xml 103 | 107 | ``` 108 | 109 | Then, inside your `Activity` get the reference: 110 | 111 | ```kotlin 112 | // Activity: 113 | val searchView: MaterialSearchView = findViewById(R.id.search_view) 114 | ``` 115 | 116 | - To open the search view, simply call the `searchView.openSearch()` method. 117 | 118 | - To close the search view, call the `searchView.closeSearch()` method. 119 | 120 | - You can check if the view is open by using the `searchView.isOpen()` method. 121 | 122 | - As from Version 1.2.1 it's also possible to get the query anytime by using the `searchView.getCurrentQuery()` method. 123 | 124 | - To close the search view using the back button, put the following code on your `Activity`: 125 | 126 | ```kotlin 127 | override fun onBackPressed() { 128 | if (searchView.isOpen) { 129 | // Close the search on the back button press. 130 | searchView.closeSearch() 131 | } else { 132 | super.onBackPressed() 133 | } 134 | } 135 | ``` 136 | 137 | For more examples on how to use this lib, [check the sample app code here](https://github.com/Mauker1/MaterialSearchView/blob/master/app/src/main/java/br/com/mauker/materialsearchview/app/MainActivity.kt). 138 | 139 | ## Search history and suggestions 140 | 141 | You can provide search suggestions by using the following methods: 142 | 143 | - `addSuggestions(suggestions: Array)` 144 | - `addSuggestions(suggestions: List)` 145 | 146 | It's also possible to add a single suggestion using the following method: 147 | 148 | - `addSuggestion(suggestion: String?)` 149 | 150 | To remove all the search suggestions use: 151 | 152 | - `clearSuggestions()` 153 | 154 | And to remove a single suggestion, use the following method: 155 | 156 | - `removeSuggestion(suggestion: String?)` 157 | 158 | The search history is automatically handled by the view, and it can be cleared by using: 159 | 160 | - `clearHistory()` 161 | 162 | You can also remove both by using the method below: 163 | 164 | - `clearAll()` 165 | 166 | ## Modifying the suggestion list behavior 167 | 168 | The suggestion list is based on a `ListView`, and as such you can define the behavior of the item click by using the `MaterialSearchView#setOnItemClickListener()` method. 169 | 170 | If you want to submit the query from the selected suggestion, you can use the snippet below: 171 | 172 | ```kotlin 173 | searchView.setOnItemClickListener { _, _, position, _ -> 174 | // Do something when the suggestion list is clicked. 175 | val suggestion = searchView.getSuggestionAtPosition(position) 176 | searchView.setQuery(suggestion, false) 177 | } 178 | ``` 179 | 180 | If you just want to set the text on the search view text field when the user selects the suggestion, change the second argument from the `searchView#setQuery()` from `true` to `false`. 181 | 182 | ## Styling the View 183 | 184 | You can change how your MaterialSearchView looks like. To achieve that effect, try to add the following lines to your styles.xml: 185 | 186 | ```xml 187 | 204 | 205 | ``` 206 | 207 | Alternatively, you can also style the Search View programmatically by calling the methods: 208 | 209 | - `setBackgroundColor(int color);` 210 | - `setTintAlpha(int alpha);` 211 | - `setSearchBarColor(int color);` 212 | - `setSearchBarHeight(int height);` 213 | - `setTextColor(int color);` 214 | - `setHintTextColor(int color);` 215 | - `setHint(String hint);` 216 | - `setVoiceHintPrompt(String voiceHint);` 217 | - `setVoiceIcon(DrawableRes int resourceId);` 218 | - `setClearIcon(DrawableRes int resourceId);` 219 | - `setBackIcon(DrawableRes int resourceId);` 220 | - `setSuggestionBackground(DrawableRes int resourceId);` 221 | - `setHistoryIcon(@DrawableRes int resourceId);` 222 | - `setSuggestionIcon(@DrawableRes int resourceId);` 223 | - `setListTextColor(int color);` 224 | 225 | And add this line on your `br.com.mauker.materialsearchview.MaterialSearchView` tag: 226 | 227 | ```xml 228 | style="@style/MaterialSearchViewStyle" 229 | ``` 230 | 231 | So it'll look like: 232 | 233 | ```xml 234 | 239 | ``` 240 | 241 | ## Interfaces 242 | Currently there are two interfaces that you can use to instantiate listeners for: 243 | 244 | - `OnQueryTextListener`: Use this interface to handle QueryTextChange or QueryTextSubmit events inside the MaterialSearchView. 245 | - `SearchViewListener`: You can use this interface to listen and handle the open or close events of the MaterialSearchView. 246 | 247 | 248 | ## Languages 249 | 250 | The MaterialSearchView supports the following languages: 251 | 252 | - English (en_US); 253 | - Brazillian Portuguese (pt_BR); 254 | - Italian (Thanks to [Francesco Donzello](https://github.com/wideawake)); 255 | - French (Thanks to [Robin](https://github.com/RobinPetit)); 256 | - Bosnian, Croatian and Serbian (Thanks to [Luke](https://github.com/luq-0)); 257 | - Spanish (Thanks to [Gloix](https://github.com/Gloix)). 258 | 259 | ## Sample GIF 260 | 261 | 262 | ## More Info 263 | 264 | For more use cases, and some examples, you can [check the sample app](https://github.com/Mauker1/MaterialSearchView/tree/master/app/src/main/java/br/com/mauker/materialsearchview/app). 265 | 266 | ## Credits 267 | This library was created by Maurício Pessoa with contributions from: 268 | - [Adam McNeilly](http://adammcneilly.com) 269 | - [Pier Betos](https://github.com/peterbetos) 270 | 271 | JCenter version was made possible with help from: 272 | 273 | - [Eric Cugota](https://github.com/tryadelion) 274 | 275 | This project was inspired by the [MaterialSearchView](https://github.com/krishnakapil/MaterialSeachView) library by krishnakapil. 276 | 277 | ## License 278 | The MaterialSearchView library is available under the [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0). 279 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'kotlin-android' 3 | 4 | android { 5 | def globalConfiguration = rootProject.extensions.getByName("ext") 6 | 7 | compileSdkVersion globalConfiguration["androidCompileSdkVersion"] 8 | buildToolsVersion globalConfiguration["androidBuildToolsVersion"] 9 | 10 | defaultConfig { 11 | // vectorDrawables.useSupportLibrary = true 12 | applicationId "br.com.mauker.materialsearchview.app" 13 | minSdkVersion globalConfiguration["androidMinSdkVersion"] 14 | targetSdkVersion globalConfiguration["androidTargetSdkVersion"] 15 | versionCode 4 16 | versionName "1.0" 17 | } 18 | buildTypes { 19 | release { 20 | minifyEnabled false 21 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 22 | } 23 | } 24 | 25 | compileOptions { 26 | sourceCompatibility JavaVersion.VERSION_1_8 27 | targetCompatibility JavaVersion.VERSION_1_8 28 | } 29 | 30 | useLibrary 'android.test.base' 31 | } 32 | 33 | dependencies { 34 | implementation fileTree(dir: 'libs', include: ['*.jar']) 35 | implementation "androidx.constraintlayout:constraintlayout:$constraintLayoutVersion" 36 | implementation "androidx.appcompat:appcompat:$appCompatVersion" 37 | implementation project(':library') 38 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 39 | } 40 | repositories { 41 | mavenCentral() 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 28 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /app/src/main/java/br/com/mauker/MsvAuthority.kt: -------------------------------------------------------------------------------- 1 | package br.com.mauker 2 | 3 | /** 4 | * Class used to setup the MaterialSearchView history database. 5 | */ 6 | object MsvAuthority { 7 | const val CONTENT_AUTHORITY: String = "br.com.mauker.materialsearchview.searchhistorydatabase" 8 | } -------------------------------------------------------------------------------- /app/src/main/java/br/com/mauker/materialsearchview/app/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package br.com.mauker.materialsearchview.app 2 | 3 | import android.content.Context 4 | import android.content.Intent 5 | import android.os.Bundle 6 | import android.speech.RecognizerIntent 7 | import android.text.TextUtils 8 | import android.view.Menu 9 | import android.view.MenuItem 10 | import android.widget.Button 11 | import android.widget.Toast 12 | import androidx.appcompat.app.AppCompatActivity 13 | import androidx.appcompat.widget.Toolbar 14 | import br.com.mauker.materialsearchview.MaterialSearchView 15 | import br.com.mauker.materialsearchview.MaterialSearchView.SearchViewListener 16 | 17 | class MainActivity : AppCompatActivity() { 18 | private lateinit var searchView: MaterialSearchView 19 | private lateinit var btClearHistory: Button 20 | private lateinit var btClearSuggestions: Button 21 | private lateinit var btClearAll: Button 22 | 23 | override fun onCreate(savedInstanceState: Bundle?) { 24 | super.onCreate(savedInstanceState) 25 | setContentView(R.layout.activity_main) 26 | 27 | val toolbar: Toolbar = findViewById(R.id.toolbar) 28 | setSupportActionBar(toolbar) 29 | 30 | searchView = findViewById(R.id.search_view) 31 | btClearHistory = findViewById(R.id.bt_clearHistory) 32 | btClearSuggestions = findViewById(R.id.bt_clearSuggestions) 33 | btClearAll = findViewById(R.id.bt_clearAll) 34 | 35 | searchView.setOnQueryTextListener(object : MaterialSearchView.OnQueryTextListener { 36 | override fun onQueryTextSubmit(query: String): Boolean { 37 | return false 38 | } 39 | 40 | override fun onQueryTextChange(newText: String): Boolean { 41 | return false 42 | } 43 | }) 44 | 45 | searchView.setSearchViewListener(object : SearchViewListener { 46 | override fun onSearchViewOpened() { 47 | // Do something once the view is open. 48 | } 49 | 50 | override fun onSearchViewClosed() { 51 | // Do something once the view is closed. 52 | } 53 | }) 54 | searchView.setOnItemClickListener { _, _, position, _ -> // Do something when the suggestion list is clicked. 55 | val suggestion = searchView.getSuggestionAtPosition(position) 56 | searchView.setQuery(suggestion, false) 57 | } 58 | searchView.setOnClearClickListener { 59 | Toast.makeText(this, "Clear clicked!", Toast.LENGTH_LONG).show() 60 | } 61 | btClearHistory.setOnClickListener { clearHistory() } 62 | btClearSuggestions.setOnClickListener { clearSuggestions() } 63 | btClearAll.setOnClickListener { clearAll() } 64 | 65 | searchView.adjustTintAlpha(0.8f) 66 | val context: Context = this 67 | searchView.setOnItemLongClickListener { _, _, i, _ -> 68 | Toast.makeText(context, "Long clicked position: $i", Toast.LENGTH_SHORT).show() 69 | true 70 | } 71 | // This will override the default audio action. 72 | searchView.setOnVoiceClickedListener { Toast.makeText(context, "Voice clicked!", Toast.LENGTH_SHORT).show() } 73 | } 74 | 75 | override fun onCreateOptionsMenu(menu: Menu): Boolean { 76 | // Inflate the menu; this adds items to the action bar if it is present. 77 | menuInflater.inflate(R.menu.menu_main, menu) 78 | return true 79 | } 80 | 81 | override fun onOptionsItemSelected(item: MenuItem): Boolean { 82 | // Handle toolbar item clicks here. It'll 83 | // automatically handle clicks on the Home/Up button, so long 84 | // as you specify a parent activity in AndroidManifest.xml. 85 | when (item.itemId) { 86 | R.id.action_search -> { 87 | // Open the search view on the menu item click. 88 | searchView.openSearch() 89 | return true 90 | } 91 | } 92 | return super.onOptionsItemSelected(item) 93 | } 94 | 95 | override fun onBackPressed() { 96 | if (searchView.isOpen) { 97 | // Close the search on the back button press. 98 | searchView.closeSearch() 99 | } else { 100 | super.onBackPressed() 101 | } 102 | } 103 | 104 | override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { 105 | if (requestCode == MaterialSearchView.REQUEST_VOICE && resultCode == RESULT_OK) { 106 | val matches = data!!.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS) 107 | if (matches != null && matches.size > 0) { 108 | val searchWrd = matches[0] 109 | if (!TextUtils.isEmpty(searchWrd)) { 110 | searchView.setQuery(searchWrd, false) 111 | } 112 | } 113 | return 114 | } 115 | super.onActivityResult(requestCode, resultCode, data) 116 | } 117 | 118 | override fun onPause() { 119 | super.onPause() 120 | searchView.clearSuggestions() 121 | } 122 | 123 | override fun onResume() { 124 | super.onResume() 125 | searchView.activityResumed() 126 | val arr = resources.getStringArray(R.array.suggestions) 127 | searchView.addSuggestions(arr) 128 | } 129 | 130 | private fun clearHistory() { 131 | searchView.clearHistory() 132 | } 133 | 134 | private fun clearSuggestions() { 135 | searchView.clearSuggestions() 136 | } 137 | 138 | private fun clearAll() { 139 | searchView.clearAll() 140 | } 141 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 19 | 20 |