├── .gitignore
├── LICENSE.txt
├── README.md
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── images
├── 0_height.png
├── 14zhou.gif
├── 150696.gif
├── 1506tq.gif
├── 1508kn.gif
├── 150sde.gif
├── 150sg9.gif
├── 150sox.gif
├── device-2015-12-06-215814.png
├── device-2015-12-08-123103.png
├── full_height.png
├── inaction.gif
├── intermediate.png
├── search_bar.png
├── style_dark.png
├── style_light.png
├── suggestions.png
├── vf2c2.gif
├── vf2ii.gif
├── vf2lz.gif
├── vf2oi.gif
├── vf353.gif
├── vf91i.gif
└── vf9cp.gif
├── library-rxbinding-kotlin
├── build.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ └── kotlin
│ └── com
│ └── arlib
│ └── floatingsearchview
│ └── rxbinding
│ └── RxFloatingSearchView.kt
├── library-rxbinding
├── build.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ └── java
│ └── com
│ └── arlib
│ └── floatingsearchbiew
│ └── rxbinding
│ ├── QueryObservable.java
│ └── RxFloatingSearchView.java
├── library
├── .gitignore
├── build.gradle
├── consumer-proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── arlib
│ │ └── floatingsearchview
│ │ └── ApplicationTest.java
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── arlib
│ │ └── floatingsearchview
│ │ ├── FloatingSearchView.java
│ │ ├── suggestions
│ │ ├── SearchSuggestionsAdapter.java
│ │ └── model
│ │ │ └── SearchSuggestion.java
│ │ └── util
│ │ ├── MenuPopupHelper.java
│ │ ├── Util.java
│ │ ├── adapter
│ │ ├── GestureDetectorListenerAdapter.java
│ │ ├── OnItemTouchListenerAdapter.java
│ │ └── TextWatcherAdapter.java
│ │ └── view
│ │ ├── MenuView.java
│ │ └── SearchInputView.java
│ └── res
│ ├── drawable-hdpi
│ ├── ic_arrow_back_black_24dp.png
│ ├── ic_clear_black_24dp.png
│ ├── ic_history_black_24dp.png
│ ├── ic_invert_colors_black_24dp.png
│ ├── ic_mic_black_24dp.png
│ ├── ic_more_vert_black_24dp.png
│ └── ic_search_black_24dp.png
│ ├── drawable-mdpi
│ ├── ic_arrow_back_black_24dp.png
│ ├── ic_clear_black_24dp.png
│ ├── ic_history_black_24dp.png
│ ├── ic_invert_colors_black_24dp.png
│ ├── ic_mic_black_24dp.png
│ ├── ic_more_vert_black_24dp.png
│ └── ic_search_black_24dp.png
│ ├── drawable-v21
│ ├── oval_btn_selector.xml
│ ├── rect_btn_selector.xml
│ └── suggestion_item_background.xml
│ ├── drawable-xhdpi
│ ├── ic_arrow_back_black_24dp.png
│ ├── ic_clear_black_24dp.png
│ ├── ic_history_black_24dp.png
│ ├── ic_invert_colors_black_24dp.png
│ ├── ic_mic_black_24dp.png
│ ├── ic_more_vert_black_24dp.png
│ └── ic_search_black_24dp.png
│ ├── drawable-xxhdpi
│ ├── ic_arrow_back_black_24dp.png
│ ├── ic_clear_black_24dp.png
│ ├── ic_history_black_24dp.png
│ ├── ic_invert_colors_black_24dp.png
│ ├── ic_mic_black_24dp.png
│ ├── ic_more_vert_black_24dp.png
│ └── ic_search_black_24dp.png
│ ├── drawable-xxxhdpi
│ ├── ic_arrow_back_black_24dp.png
│ ├── ic_clear_black_24dp.png
│ ├── ic_history_black_24dp.png
│ ├── ic_invert_colors_black_24dp.png
│ ├── ic_mic_black_24dp.png
│ ├── ic_more_vert_black_24dp.png
│ └── ic_search_black_24dp.png
│ ├── drawable
│ ├── divider_background.xml
│ ├── oval_btn_selector.xml
│ └── suggestion_item_background.xml
│ ├── layout
│ ├── action_item_layout.xml
│ ├── floating_search_layout.xml
│ ├── overflow_action_item_layout.xml
│ ├── search_query_section.xml
│ ├── search_suggestion_item.xml
│ └── search_suggestions_section.xml
│ └── values
│ ├── attrs.xml
│ ├── colors.xml
│ └── dimens.xml
├── sample
├── .gitignore
├── build.gradle
├── libs
│ └── gson-2.4.jar
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── arlib
│ │ └── floatingsearchviewdemo
│ │ └── ApplicationTest.java
│ └── main
│ ├── AndroidManifest.xml
│ ├── assets
│ └── colors.json
│ ├── java
│ └── com
│ │ └── arlib
│ │ └── floatingsearchviewdemo
│ │ ├── MainActivity.java
│ │ ├── adapter
│ │ └── SearchResultsListAdapter.java
│ │ ├── data
│ │ ├── ColorSuggestion.java
│ │ ├── ColorWrapper.java
│ │ └── DataHelper.java
│ │ └── fragment
│ │ ├── BaseExampleFragment.java
│ │ ├── ScrollingSearchExampleFragment.java
│ │ ├── SlidingSearchResultsExampleFragment.java
│ │ └── SlidingSearchViewExampleFragment.java
│ └── res
│ ├── drawable-hdpi
│ ├── ic_invert_colors_black_24dp.png
│ ├── ic_keyboard_voice_black_24dp.png
│ ├── ic_lightbulb_outline_black_24dp.png
│ ├── ic_local_taxi_black_24dp.png
│ ├── ic_my_location_black_24dp.png
│ └── ic_restaurant_menu_black_24dp.png
│ ├── drawable-mdpi
│ ├── ic_invert_colors_black_24dp.png
│ ├── ic_keyboard_voice_black_24dp.png
│ ├── ic_lightbulb_outline_black_24dp.png
│ ├── ic_local_taxi_black_24dp.png
│ ├── ic_my_location_black_24dp.png
│ └── ic_restaurant_menu_black_24dp.png
│ ├── drawable-xhdpi
│ ├── ic_invert_colors_black_24dp.png
│ ├── ic_keyboard_voice_black_24dp.png
│ ├── ic_lightbulb_outline_black_24dp.png
│ ├── ic_local_taxi_black_24dp.png
│ ├── ic_my_location_black_24dp.png
│ └── ic_restaurant_menu_black_24dp.png
│ ├── drawable-xxhdpi
│ ├── ic_invert_colors_black_24dp.png
│ ├── ic_keyboard_voice_black_24dp.png
│ ├── ic_lightbulb_outline_black_24dp.png
│ ├── ic_local_taxi_black_24dp.png
│ ├── ic_my_location_black_24dp.png
│ └── ic_restaurant_menu_black_24dp.png
│ ├── drawable-xxxhdpi
│ ├── ic_invert_colors_black_24dp.png
│ ├── ic_keyboard_voice_black_24dp.png
│ ├── ic_lightbulb_outline_black_24dp.png
│ ├── ic_local_taxi_black_24dp.png
│ ├── ic_my_location_black_24dp.png
│ └── ic_restaurant_menu_black_24dp.png
│ ├── drawable
│ └── circle_background.xml
│ ├── layout
│ ├── activity_main.xml
│ ├── fragment_scrolling_search_example.xml
│ ├── fragment_sliding_search_example.xml
│ ├── fragment_sliding_search_results_example_fragment.xml
│ └── search_results_list_item.xml
│ ├── menu
│ ├── menu_app.xml
│ └── menu_search_view.xml
│ ├── mipmap-hdpi
│ └── ic_launcher.png
│ ├── mipmap-mdpi
│ └── ic_launcher.png
│ ├── mipmap-xhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxhdpi
│ └── ic_launcher.png
│ ├── values-v21
│ └── styles.xml
│ └── values
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | .idea
3 | .gradle
4 | /local.properties
5 | /.idea/workspace.xml
6 | /.idea/libraries
7 | .DS_Store
8 | /build
9 | /captures
10 | /notes
11 | *.iml
12 | **/build
13 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Floating Search View [](https://android-arsenal.com/details/1/2842)
2 | =============
3 |
4 | An implementation of a floating search box with search suggestions, also called persistent search bar.
5 |
6 | 
7 | 
8 | 
9 |
10 |
11 | Note
12 | -----
13 |
14 | This project is not being actively maintained. Have a look [here](https://github.com/arimorty/floatingsearchview/wiki) for information
15 | that might help you make changes to your own copy of the code base.
16 |
17 |
18 | ...
19 |
20 |
21 | Usage
22 | -----
23 |
24 | 1. In your dependencies, add
25 | ```
26 | compile 'com.github.arimorty:floatingsearchview:2.1.1'
27 | ```
28 | 2. Add a FloatingSearchView to your view hierarchy, and make sure that it takes
29 | up the full width and height of the screen
30 | 3. Listen to query changes and provide suggestion items that implement SearchSuggestion
31 |
32 | **Example:**
33 |
34 | ```xml
35 |
48 | ```
49 |
50 | ```
51 | mSearchView.setOnQueryChangeListener(new FloatingSearchView.OnQueryChangeListener() {
52 | @Override
53 | public void onSearchTextChanged(String oldQuery, final String newQuery) {
54 |
55 | //get suggestions based on newQuery
56 |
57 | //pass them on to the search view
58 | mSearchView.swapSuggestions(newSuggestions);
59 | }
60 | });
61 | ```
62 |
63 |
64 | **Left action mode:**
65 |
66 | The left action can be configured as follows:
67 |
68 | Add
69 | ```xml
70 | app:floatingSearch_leftActionMode="[insert one of the options from table below]"
71 | ```
72 |
73 |
74 |
75 | showHamburger |
76 |  |
77 |
78 |
79 | showSearch |
80 |  |
81 |
82 | showHome |
83 |  |
84 |
85 |
86 | noLeftAction |
87 |  |
88 |
89 |
90 |
91 | Listen to *hamburger* button clicks:
92 | ```
93 | mSearchView.setOnLeftMenuClickListener(
94 | new FloatingSearchView.OnLeftMenuClickListener() { ...} );
95 | ```
96 |
97 | To quickly connect your **NavigationDrawer** to the *hamburger* button:
98 | ```
99 | mSearchView.attachNavigationDrawerToMenuButton(mDrawerLayout);
100 | ```
101 |
102 | Listen to home (back arrow) button clicks:
103 | ```
104 | mSearchView.setOnHomeActionClickListener(
105 | new FloatingSearchView.OnHomeActionClickListener() { ... });
106 | ```
107 |
108 |
109 |
110 | **Configure menu items:**
111 |
112 | 
113 |
114 | Add a menu resource
115 | ```xml
116 | app:floatingSearch_menu="@menu/menu_main"
117 | ```
118 |
119 | In the menu resource, set items' ```app:showAsAction="[insert one of the options described in the table below]"```
120 |
121 |
122 |
123 | never |
124 | Puts the menu item in the overflow options popup |
125 |
126 |
127 | ifRoom |
128 | Shows an action icon for the menu if the following conditions are met:
129 | 1. The search is not focused.
130 | 2. There is enough room for it.
131 | |
132 |
133 |
134 | always |
135 | Shows an action icon for the menu if there is room, regardless of whether the search is focused or not. |
136 |
137 |
138 |
139 | Listen for item selections
140 | ```
141 | mSearchView.setOnMenuItemClickListener(new FloatingSearchView.OnMenuItemClickListener() {
142 | @Override
143 | public void onMenuItemSelected(MenuItem item) {
144 |
145 | }
146 | });
147 | ```
148 |
149 |
150 |
151 |
152 | **Configure suggestion item:**
153 |
154 | First, implement [SearchSuggestion](https://github.com/arimorty/floatingsearchview/blob/master/library/src/main/java/com/arlib/floatingsearchview/suggestions/model/SearchSuggestion.java)
155 |
156 | *Optional*:
157 |
158 | Set a callback for when a given suggestion is bound to the suggestion list.
159 |
160 | For the history icons to show, you would need to implement this. Refer to the sample app for an [example implementation](https://github.com/arimorty/floatingsearchview/blob/master/sample/src/main/java/com/arlib/floatingsearchviewdemo/fragment/ScrollingSearchExampleFragment.java#L222).
161 | ```
162 | mSearchView.setOnBindSuggestionCallback(new SearchSuggestionsAdapter.OnBindSuggestionCallback() {
163 | @Override
164 | public void onBindSuggestion(View suggestionView, ImageView leftIcon, TextView textView, SearchSuggestion item, int itemPosition) {
165 |
166 | //here you can set some attributes for the suggestion's left icon and text. For example,
167 | //you can choose your favorite image-loading library for setting the left icon's image.
168 | }
169 |
170 | });
171 | ```
172 |
173 |
174 |
175 | **Styling:**
176 |
177 |
178 |
179 |
180 | Available styling:
181 |
182 | ```xml
183 |
195 | ```
196 | ### RxBinding Extension
197 | The RxBinding library allows you to listen for query changes using RxJava Obervables.
198 |
199 | ```java
200 | Observable queryObservable = RxFloatingSearchView.queryChanges(view);
201 | queryObservable.doOnNext { query -> Toast.makeText(this, "Query is %s".format(query), Toast.LENGTH_LONG).show() }.subscribe();
202 | ```
203 |
204 | ### The Kotlin Extension
205 | The Kotlin extension adds an extension function to the view for more goodness.
206 |
207 | ```kotlin
208 | view.queryChanges(5).doOnNext { query -> Toast.makeText(this, "Query is %s".format(query), Toast.LENGTH_LONG).show() }.subscribe()
209 | ```
210 |
211 |
212 | License
213 | =======
214 |
215 | Copyright (C) 2015 Ari C.
216 |
217 | Licensed under the Apache License, Version 2.0 (the "License");
218 | you may not use this file except in compliance with the License.
219 | You may obtain a copy of the License at
220 |
221 | http://www.apache.org/licenses/LICENSE-2.0
222 |
223 | Unless required by applicable law or agreed to in writing, software
224 | distributed under the License is distributed on an "AS IS" BASIS,
225 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
226 | See the License for the specific language governing permissions and
227 | limitations under the License.
228 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.3.0'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | mavenCentral()
18 | jcenter()
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sun Apr 16 14:28:23 EDT 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/images/0_height.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/images/0_height.png
--------------------------------------------------------------------------------
/images/14zhou.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/images/14zhou.gif
--------------------------------------------------------------------------------
/images/150696.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/images/150696.gif
--------------------------------------------------------------------------------
/images/1506tq.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/images/1506tq.gif
--------------------------------------------------------------------------------
/images/1508kn.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/images/1508kn.gif
--------------------------------------------------------------------------------
/images/150sde.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/images/150sde.gif
--------------------------------------------------------------------------------
/images/150sg9.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/images/150sg9.gif
--------------------------------------------------------------------------------
/images/150sox.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/images/150sox.gif
--------------------------------------------------------------------------------
/images/device-2015-12-06-215814.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/images/device-2015-12-06-215814.png
--------------------------------------------------------------------------------
/images/device-2015-12-08-123103.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/images/device-2015-12-08-123103.png
--------------------------------------------------------------------------------
/images/full_height.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/images/full_height.png
--------------------------------------------------------------------------------
/images/inaction.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/images/inaction.gif
--------------------------------------------------------------------------------
/images/intermediate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/images/intermediate.png
--------------------------------------------------------------------------------
/images/search_bar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/images/search_bar.png
--------------------------------------------------------------------------------
/images/style_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/images/style_dark.png
--------------------------------------------------------------------------------
/images/style_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/images/style_light.png
--------------------------------------------------------------------------------
/images/suggestions.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/images/suggestions.png
--------------------------------------------------------------------------------
/images/vf2c2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/images/vf2c2.gif
--------------------------------------------------------------------------------
/images/vf2ii.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/images/vf2ii.gif
--------------------------------------------------------------------------------
/images/vf2lz.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/images/vf2lz.gif
--------------------------------------------------------------------------------
/images/vf2oi.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/images/vf2oi.gif
--------------------------------------------------------------------------------
/images/vf353.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/images/vf353.gif
--------------------------------------------------------------------------------
/images/vf91i.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/images/vf91i.gif
--------------------------------------------------------------------------------
/images/vf9cp.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/images/vf9cp.gif
--------------------------------------------------------------------------------
/library-rxbinding-kotlin/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.1.2-3'
3 | repositories {
4 | mavenCentral()
5 | }
6 | dependencies {
7 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
8 | }
9 | }
10 |
11 | apply plugin: 'com.android.library'
12 | apply plugin: 'kotlin-android'
13 |
14 | android {
15 | compileSdkVersion 25
16 | buildToolsVersion '25.0.3'
17 |
18 | defaultConfig {
19 | minSdkVersion 14
20 | targetSdkVersion 25
21 | versionCode 11
22 | versionName "2.0.4"
23 | }
24 | sourceSets{
25 | main.java.srcDirs += 'src/main/kotlin'
26 | }
27 | }
28 |
29 | dependencies {
30 | compile project(path: ':library-rxbinding')
31 | compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
32 | }
33 |
34 | sourceCompatibility = "1.7"
35 | targetCompatibility = "1.7"
36 |
--------------------------------------------------------------------------------
/library-rxbinding-kotlin/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/library-rxbinding-kotlin/src/main/kotlin/com/arlib/floatingsearchview/rxbinding/RxFloatingSearchView.kt:
--------------------------------------------------------------------------------
1 | package com.arlib.floatingsearchview.rxbinding
2 |
3 | import com.arlib.floatingsearchbiew.rxbinding.RxFloatingSearchView
4 | import com.arlib.floatingsearchview.FloatingSearchView
5 | import com.jakewharton.rxbinding2.InitialValueObservable
6 |
7 | inline fun FloatingSearchView.queryChanges(minQueryLimit: Int = 1): InitialValueObservable = RxFloatingSearchView.queryChanges(this, minQueryLimit)
--------------------------------------------------------------------------------
/library-rxbinding/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'maven-publish'
3 |
4 | android {
5 | compileSdkVersion 25
6 | buildToolsVersion '25.0.3'
7 |
8 | defaultConfig {
9 | minSdkVersion 14
10 | targetSdkVersion 25
11 | versionCode 11
12 | versionName "2.0.4"
13 | }
14 | }
15 |
16 | dependencies {
17 | compile 'com.android.support:support-annotations:25.3.1'
18 | compile 'com.jakewharton.rxbinding2:rxbinding:2.0.0'
19 | compile project(path: ':library')
20 | }
21 |
22 | sourceCompatibility = "1.7"
23 | targetCompatibility = "1.7"
24 |
--------------------------------------------------------------------------------
/library-rxbinding/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/library-rxbinding/src/main/java/com/arlib/floatingsearchbiew/rxbinding/QueryObservable.java:
--------------------------------------------------------------------------------
1 | package com.arlib.floatingsearchbiew.rxbinding;
2 |
3 | import com.arlib.floatingsearchview.FloatingSearchView;
4 | import com.jakewharton.rxbinding2.InitialValueObservable;
5 |
6 | import io.reactivex.Observer;
7 | import io.reactivex.android.MainThreadDisposable;
8 |
9 | final public class QueryObservable extends InitialValueObservable {
10 |
11 | private final FloatingSearchView view;
12 |
13 | private final int minQueryLength;
14 |
15 | public QueryObservable(FloatingSearchView view) {
16 | this(view, 1);
17 | }
18 |
19 | public QueryObservable(FloatingSearchView view, int minQueryLength) {
20 | this.view = view;
21 | this.minQueryLength = minQueryLength;
22 | }
23 |
24 | @Override
25 | protected void subscribeListener(Observer super CharSequence> observer) {
26 | Listener listener = new Listener(view, observer, minQueryLength);
27 | observer.onSubscribe(listener);
28 | view.setOnQueryChangeListener(listener);
29 | }
30 |
31 | @Override
32 | protected CharSequence getInitialValue() {
33 | return view.getQuery();
34 | }
35 |
36 | final static class Listener extends MainThreadDisposable implements FloatingSearchView.OnQueryChangeListener {
37 |
38 | private final FloatingSearchView view;
39 | private final Observer super CharSequence> observer;
40 | private final int minQueryLength;
41 |
42 | public Listener(FloatingSearchView view, Observer super CharSequence> observer, int minQueryLength) {
43 | this.view = view;
44 | this.observer = observer;
45 | this.minQueryLength = minQueryLength;
46 | }
47 |
48 | @Override
49 | public void onSearchTextChanged(String oldQuery, String newQuery) {
50 | if(!isDisposed() && newQuery != null && newQuery.length() >= minQueryLength) {
51 | observer.onNext(newQuery);
52 | }
53 | }
54 |
55 | @Override
56 | protected void onDispose() {
57 | view.setOnQueryChangeListener(null);
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/library-rxbinding/src/main/java/com/arlib/floatingsearchbiew/rxbinding/RxFloatingSearchView.java:
--------------------------------------------------------------------------------
1 | package com.arlib.floatingsearchbiew.rxbinding;
2 |
3 | import android.support.annotation.CheckResult;
4 | import android.support.annotation.NonNull;
5 |
6 | import com.arlib.floatingsearchview.FloatingSearchView;
7 | import com.jakewharton.rxbinding2.InitialValueObservable;
8 |
9 | public final class RxFloatingSearchView {
10 |
11 | @CheckResult
12 | @NonNull
13 | public static InitialValueObservable queryChanges(
14 | @NonNull FloatingSearchView view) {
15 | return queryChanges(view, 1);
16 | }
17 |
18 | @CheckResult
19 | @NonNull
20 | public static InitialValueObservable queryChanges(
21 | @NonNull FloatingSearchView view, int characterLimit) {
22 | checkNotNull(view, "view == null");
23 | return new QueryObservable(view, characterLimit);
24 | }
25 |
26 | public static void checkNotNull(Object value, String message) {
27 | if (value == null) {
28 | throw new NullPointerException(message);
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/library/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | gradle.properties
3 | maven-push.gradle
4 | .idea
5 | *.iml
--------------------------------------------------------------------------------
/library/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 25
5 | buildToolsVersion '25.0.3'
6 |
7 | defaultConfig {
8 | minSdkVersion 14
9 | targetSdkVersion 25
10 | versionCode 13
11 | versionName "2.1.1"
12 | //consumerProguardFiles 'consumer-proguard-rules.txt'
13 | }
14 | }
15 |
16 | dependencies {
17 | compile fileTree(dir: 'libs', include: ['*.jar'])
18 | compile 'com.android.support:appcompat-v7:25.3.1'
19 | compile 'com.android.support:recyclerview-v7:25.3.1'
20 | compile 'com.android.support:design:25.3.1'
21 | compile 'com.android.support:cardview-v7:25.3.1'
22 | compile 'com.bartoszlipinski:viewpropertyobjectanimator:1.2.0'
23 | }
24 |
25 | //enable when uploading lib// apply from: 'maven-push.gradle'
--------------------------------------------------------------------------------
/library/consumer-proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in C:\Users\ari\AppData\Local\Android\sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | # Support libs
20 | -dontwarn android.support.v7.**
21 | -keep class android.support.v7.** { *; }
22 | -keep interface android.support.v7.** { *; }
23 |
24 | -keep class com.bartoszlipinski.** { *; }
25 | -keep interface com.bartoszlipinski.** { *; }
26 |
27 | # Keep all floatingsearchview classes
28 | -keep class com.arlib.** { *; }
--------------------------------------------------------------------------------
/library/src/androidTest/java/com/arlib/floatingsearchview/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.arlib.floatingsearchview;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/library/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/library/src/main/java/com/arlib/floatingsearchview/suggestions/SearchSuggestionsAdapter.java:
--------------------------------------------------------------------------------
1 | package com.arlib.floatingsearchview.suggestions;
2 |
3 | /**
4 | * Copyright (C) 2015 Ari C.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.content.Context;
20 | import android.graphics.drawable.Drawable;
21 | import android.support.v4.graphics.drawable.DrawableCompat;
22 | import android.support.v7.widget.RecyclerView;
23 | import android.util.TypedValue;
24 | import android.view.LayoutInflater;
25 | import android.view.View;
26 | import android.view.ViewGroup;
27 | import android.widget.ImageView;
28 | import android.widget.TextView;
29 |
30 | import com.arlib.floatingsearchview.R;
31 | import com.arlib.floatingsearchview.suggestions.model.SearchSuggestion;
32 | import com.arlib.floatingsearchview.util.Util;
33 |
34 | import java.util.ArrayList;
35 | import java.util.Collections;
36 | import java.util.List;
37 |
38 | public class SearchSuggestionsAdapter extends RecyclerView.Adapter {
39 |
40 | private static final String TAG = "SearchSuggestionsAdapter";
41 |
42 | private List extends SearchSuggestion> mSearchSuggestions = new ArrayList<>();
43 |
44 | private Listener mListener;
45 |
46 | private Context mContext;
47 |
48 | private Drawable mRightIconDrawable;
49 | private boolean mShowRightMoveUpBtn = false;
50 | private int mBodyTextSizePx;
51 | private int mTextColor = -1;
52 | private int mRightIconColor = -1;
53 |
54 | public interface OnBindSuggestionCallback {
55 |
56 | void onBindSuggestion(View suggestionView, ImageView leftIcon, TextView textView,
57 | SearchSuggestion item, int itemPosition);
58 | }
59 |
60 | private OnBindSuggestionCallback mOnBindSuggestionCallback;
61 |
62 | public interface Listener {
63 |
64 | void onItemSelected(SearchSuggestion item);
65 |
66 | void onMoveItemToSearchClicked(SearchSuggestion item);
67 | }
68 |
69 | public static class SearchSuggestionViewHolder extends RecyclerView.ViewHolder {
70 |
71 | public TextView body;
72 | public ImageView leftIcon;
73 | public ImageView rightIcon;
74 |
75 | private Listener mListener;
76 |
77 | public interface Listener {
78 |
79 | void onItemClicked(int adapterPosition);
80 |
81 | void onMoveItemToSearchClicked(int adapterPosition);
82 | }
83 |
84 | public SearchSuggestionViewHolder(View v, Listener listener) {
85 | super(v);
86 |
87 | mListener = listener;
88 | body = (TextView) v.findViewById(R.id.body);
89 | leftIcon = (ImageView) v.findViewById(R.id.left_icon);
90 | rightIcon = (ImageView) v.findViewById(R.id.right_icon);
91 |
92 | rightIcon.setOnClickListener(new View.OnClickListener() {
93 | @Override
94 | public void onClick(View v) {
95 |
96 | int adapterPosition = getAdapterPosition();
97 | if (mListener != null && adapterPosition != RecyclerView.NO_POSITION) {
98 | mListener.onMoveItemToSearchClicked(getAdapterPosition());
99 | }
100 | }
101 | });
102 |
103 | itemView.setOnClickListener(new View.OnClickListener() {
104 | @Override
105 | public void onClick(View v) {
106 |
107 | int adapterPosition = getAdapterPosition();
108 | if (mListener != null && adapterPosition != RecyclerView.NO_POSITION) {
109 | mListener.onItemClicked(adapterPosition);
110 | }
111 | }
112 | });
113 | }
114 | }
115 |
116 | public SearchSuggestionsAdapter(Context context, int suggestionTextSize, Listener listener) {
117 | this.mContext = context;
118 | this.mListener = listener;
119 | this.mBodyTextSizePx = suggestionTextSize;
120 |
121 | mRightIconDrawable = Util.getWrappedDrawable(mContext, R.drawable.ic_arrow_back_black_24dp);
122 | DrawableCompat.setTint(mRightIconDrawable, Util.getColor(mContext, R.color.gray_active_icon));
123 | }
124 |
125 | public void swapData(List extends SearchSuggestion> searchSuggestions) {
126 | mSearchSuggestions = searchSuggestions;
127 | notifyDataSetChanged();
128 | }
129 |
130 | public List extends SearchSuggestion> getDataSet() {
131 | return mSearchSuggestions;
132 | }
133 |
134 | public void setOnBindSuggestionCallback(OnBindSuggestionCallback callback) {
135 | this.mOnBindSuggestionCallback = callback;
136 | }
137 |
138 | @Override
139 | public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
140 |
141 | View view = LayoutInflater.from(viewGroup.getContext())
142 | .inflate(R.layout.search_suggestion_item, viewGroup, false);
143 | SearchSuggestionViewHolder viewHolder = new SearchSuggestionViewHolder(view,
144 | new SearchSuggestionViewHolder.Listener() {
145 |
146 | @Override
147 | public void onItemClicked(int adapterPosition) {
148 |
149 | if (mListener != null) {
150 | mListener.onItemSelected(mSearchSuggestions.get(adapterPosition));
151 | }
152 | }
153 |
154 | @Override
155 | public void onMoveItemToSearchClicked(int adapterPosition) {
156 |
157 | if (mListener != null) {
158 | mListener.onMoveItemToSearchClicked(mSearchSuggestions
159 | .get(adapterPosition));
160 | }
161 | }
162 |
163 | });
164 |
165 | viewHolder.rightIcon.setImageDrawable(mRightIconDrawable);
166 | viewHolder.body.setTextSize(TypedValue.COMPLEX_UNIT_PX, mBodyTextSizePx);
167 |
168 | return viewHolder;
169 | }
170 |
171 | @Override
172 | public void onBindViewHolder(RecyclerView.ViewHolder vh, int position) {
173 |
174 | SearchSuggestionViewHolder viewHolder = (SearchSuggestionViewHolder) vh;
175 |
176 | if (!mShowRightMoveUpBtn) {
177 | viewHolder.rightIcon.setEnabled(false);
178 | viewHolder.rightIcon.setVisibility(View.INVISIBLE);
179 | } else {
180 | viewHolder.rightIcon.setEnabled(true);
181 | viewHolder.rightIcon.setVisibility(View.VISIBLE);
182 | }
183 |
184 | SearchSuggestion suggestionItem = mSearchSuggestions.get(position);
185 | viewHolder.body.setText(suggestionItem.getBody());
186 |
187 | if(mTextColor != -1){
188 | viewHolder.body.setTextColor(mTextColor);
189 | }
190 |
191 | if(mRightIconColor != -1){
192 | Util.setIconColor(viewHolder.rightIcon, mRightIconColor);
193 | }
194 |
195 | if (mOnBindSuggestionCallback != null) {
196 | mOnBindSuggestionCallback.onBindSuggestion(viewHolder.itemView, viewHolder.leftIcon, viewHolder.body,
197 | suggestionItem, position);
198 | }
199 | }
200 |
201 | @Override
202 | public int getItemCount() {
203 | return mSearchSuggestions != null ? mSearchSuggestions.size() : 0;
204 | }
205 |
206 | public void setTextColor(int color) {
207 |
208 | boolean notify = false;
209 | if (this.mTextColor != color) {
210 | notify = true;
211 | }
212 | this.mTextColor = color;
213 | if (notify) {
214 | notifyDataSetChanged();
215 | }
216 | }
217 |
218 | public void setRightIconColor(int color) {
219 |
220 | boolean notify = false;
221 | if (this.mRightIconColor != color) {
222 | notify = true;
223 | }
224 | this.mRightIconColor = color;
225 | if (notify) {
226 | notifyDataSetChanged();
227 | }
228 | }
229 |
230 | public void setShowMoveUpIcon(boolean show) {
231 |
232 | boolean notify = false;
233 | if (this.mShowRightMoveUpBtn != show) {
234 | notify = true;
235 | }
236 | this.mShowRightMoveUpBtn = show;
237 | if (notify) {
238 | notifyDataSetChanged();
239 | }
240 | }
241 |
242 | public void reverseList() {
243 | Collections.reverse(mSearchSuggestions);
244 | notifyDataSetChanged();
245 | }
246 | }
247 |
--------------------------------------------------------------------------------
/library/src/main/java/com/arlib/floatingsearchview/suggestions/model/SearchSuggestion.java:
--------------------------------------------------------------------------------
1 | package com.arlib.floatingsearchview.suggestions.model;
2 |
3 | /**
4 | * Copyright (C) 2015 Ari C.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.os.Parcelable;
20 |
21 | /**
22 | * An object that represents a single suggestion item
23 | * in the suggestions drop down generated in response
24 | * to an entered query in the {@link com.arlib.floatingsearchview.FloatingSearchView}
25 | */
26 | public interface SearchSuggestion extends Parcelable{
27 |
28 | /**
29 | * Returns the text that should be displayed
30 | * for the suggestion represented by this object.
31 | *
32 | * @return the text for this suggestion
33 | */
34 | String getBody();
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/library/src/main/java/com/arlib/floatingsearchview/util/Util.java:
--------------------------------------------------------------------------------
1 | package com.arlib.floatingsearchview.util;
2 |
3 | /**
4 | * Copyright (C) 2015 Ari C.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.app.Activity;
20 | import android.content.Context;
21 | import android.content.ContextWrapper;
22 | import android.content.res.Resources;
23 | import android.graphics.drawable.Drawable;
24 | import android.os.Build;
25 | import android.os.Handler;
26 | import android.support.annotation.ColorRes;
27 | import android.support.annotation.DrawableRes;
28 | import android.support.v4.content.ContextCompat;
29 | import android.support.v4.content.res.ResourcesCompat;
30 | import android.support.v4.graphics.drawable.DrawableCompat;
31 | import android.util.DisplayMetrics;
32 | import android.util.TypedValue;
33 | import android.view.Display;
34 | import android.view.View;
35 | import android.view.ViewTreeObserver;
36 | import android.view.inputmethod.InputMethodManager;
37 | import android.widget.EditText;
38 | import android.widget.ImageView;
39 |
40 | public class Util {
41 |
42 | private static final String TAG = "Util";
43 |
44 | public static void showSoftKeyboard(final Context context, final EditText editText) {
45 |
46 | new Handler().postDelayed(new Runnable() {
47 | @Override
48 | public void run() {
49 |
50 | InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
51 | inputMethodManager.showSoftInput(editText, InputMethodManager.SHOW_FORCED);
52 | }
53 | }, 100);
54 | }
55 |
56 | public static void closeSoftKeyboard(Activity activity) {
57 |
58 | View currentFocusView = activity.getCurrentFocus();
59 | if (currentFocusView != null) {
60 | InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
61 | imm.hideSoftInputFromWindow(currentFocusView.getWindowToken(), 0);
62 | }
63 | }
64 |
65 | public static int dpToPx(int dp) {
66 | DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
67 | return (int) (dp * metrics.density);
68 | }
69 |
70 | public static int pxToDp(int px) {
71 | DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
72 | return (int) (px / metrics.density);
73 | }
74 |
75 | public static int spToPx(int sp) {
76 | DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
77 | return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, metrics);
78 | }
79 |
80 | public static int pxToSp(int px) {
81 | DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
82 | return px / (int) metrics.scaledDensity;
83 | }
84 |
85 | public static int getScreenWidth(Activity activity) {
86 |
87 | Display display = activity.getWindowManager().getDefaultDisplay();
88 | DisplayMetrics outMetrics = new DisplayMetrics();
89 | display.getMetrics(outMetrics);
90 |
91 | return outMetrics.widthPixels;
92 | }
93 |
94 | public static int getScreenHeight(Activity activity) {
95 |
96 | Display display = activity.getWindowManager().getDefaultDisplay();
97 | DisplayMetrics outMetrics = new DisplayMetrics();
98 | display.getMetrics(outMetrics);
99 |
100 | return outMetrics.heightPixels;
101 | }
102 |
103 | public static void setIconColor(ImageView iconHolder, int color) {
104 | Drawable wrappedDrawable = DrawableCompat.wrap(iconHolder.getDrawable());
105 | DrawableCompat.setTint(wrappedDrawable, color);
106 | iconHolder.setImageDrawable(wrappedDrawable);
107 | iconHolder.invalidate();
108 | }
109 |
110 | /**
111 | * Gets a reference to a given drawable and prepares it for use with tinting through.
112 | *
113 | * @param resId the resource id for the given drawable
114 | * @return a wrapped drawable ready fo use
115 | * with {@link android.support.v4.graphics.drawable.DrawableCompat}'s tinting methods
116 | * @throws Resources.NotFoundException
117 | */
118 | public static Drawable getWrappedDrawable(Context context, @DrawableRes int resId) throws Resources.NotFoundException {
119 | return DrawableCompat.wrap(ResourcesCompat.getDrawable(context.getResources(),
120 | resId, null));
121 | }
122 |
123 | public static int getColor(Context context, @ColorRes int resId) throws Resources.NotFoundException {
124 | return ContextCompat.getColor(context, resId);
125 | }
126 |
127 | public static void removeGlobalLayoutObserver(View view, ViewTreeObserver.OnGlobalLayoutListener layoutListener) {
128 | if (Build.VERSION.SDK_INT < 16) {
129 | view.getViewTreeObserver().removeGlobalOnLayoutListener(layoutListener);
130 | } else {
131 | view.getViewTreeObserver().removeOnGlobalLayoutListener(layoutListener);
132 | }
133 | }
134 |
135 | public static Activity getHostActivity(Context context) {
136 | while (context instanceof ContextWrapper) {
137 | if (context instanceof Activity) {
138 | return (Activity) context;
139 | }
140 | context = ((ContextWrapper) context).getBaseContext();
141 | }
142 | return null;
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/library/src/main/java/com/arlib/floatingsearchview/util/adapter/GestureDetectorListenerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.arlib.floatingsearchview.util.adapter;
2 |
3 | /**
4 | * Copyright (C) 2015 Ari C.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.view.GestureDetector;
20 | import android.view.MotionEvent;
21 |
22 | public abstract class GestureDetectorListenerAdapter implements
23 | GestureDetector.OnGestureListener{
24 |
25 | private static final String TAG = "GestureDetectorListenerAdapter";
26 |
27 | @Override
28 | public boolean onDown(MotionEvent e) {
29 | return false;
30 | }
31 |
32 | @Override
33 | public void onShowPress(MotionEvent e) {
34 |
35 | }
36 |
37 | @Override
38 | public boolean onSingleTapUp(MotionEvent e) {
39 | return false;
40 | }
41 |
42 | @Override
43 | public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
44 | return false;
45 | }
46 |
47 | @Override
48 | public void onLongPress(MotionEvent e) {
49 |
50 | }
51 |
52 | @Override
53 | public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
54 | return false;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/library/src/main/java/com/arlib/floatingsearchview/util/adapter/OnItemTouchListenerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.arlib.floatingsearchview.util.adapter;
2 |
3 | /**
4 | * Copyright (C) 2015 Ari C.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.support.v7.widget.RecyclerView;
20 | import android.view.MotionEvent;
21 |
22 | public abstract class OnItemTouchListenerAdapter implements RecyclerView.OnItemTouchListener {
23 |
24 | private static final String TAG = "OnItemTouchListenerAdapter";
25 |
26 | @Override
27 | public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
28 | return false;
29 | }
30 |
31 | @Override
32 | public void onTouchEvent(RecyclerView rv, MotionEvent e) {
33 |
34 | }
35 |
36 | @Override
37 | public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
38 |
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/library/src/main/java/com/arlib/floatingsearchview/util/adapter/TextWatcherAdapter.java:
--------------------------------------------------------------------------------
1 | package com.arlib.floatingsearchview.util.adapter;
2 |
3 | /**
4 | * Copyright (C) 2015 Ari C.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.text.Editable;
20 | import android.text.TextWatcher;
21 |
22 | public abstract class TextWatcherAdapter implements TextWatcher {
23 |
24 | private static final String TAG = "TextWatcherAdapter";
25 |
26 | @Override
27 | public void beforeTextChanged(CharSequence s, int start, int count, int after) {
28 |
29 | }
30 |
31 | @Override
32 | public void onTextChanged(CharSequence s, int start, int before, int count) {
33 |
34 | }
35 |
36 | @Override
37 | public void afterTextChanged(Editable s) {
38 |
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/library/src/main/java/com/arlib/floatingsearchview/util/view/SearchInputView.java:
--------------------------------------------------------------------------------
1 | package com.arlib.floatingsearchview.util.view;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.KeyEvent;
6 | import android.view.View;
7 | import android.widget.EditText;
8 |
9 | public class SearchInputView extends EditText {
10 |
11 | private OnKeyboardSearchKeyClickListener mSearchKeyListener;
12 |
13 | private OnKeyboardDismissedListener mOnKeyboardDismissedListener;
14 |
15 | private OnKeyListener mOnKeyListener = new OnKeyListener() {
16 | public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
17 |
18 | if (keyCode == KeyEvent.KEYCODE_ENTER && mSearchKeyListener != null) {
19 | mSearchKeyListener.onSearchKeyClicked();
20 | return true;
21 | }
22 | return false;
23 | }
24 | };
25 |
26 | public SearchInputView(Context context) {
27 | super(context);
28 | init();
29 | }
30 |
31 | public SearchInputView(Context context, AttributeSet attrs) {
32 | super(context, attrs);
33 | init();
34 | }
35 |
36 | public SearchInputView(Context context, AttributeSet attrs, int defStyle) {
37 | super(context, attrs, defStyle);
38 | init();
39 | }
40 |
41 | private void init() {
42 | setOnKeyListener(mOnKeyListener);
43 | }
44 |
45 | @Override
46 | public boolean onKeyPreIme(int keyCode, KeyEvent ev) {
47 | if (ev.getKeyCode() == KeyEvent.KEYCODE_BACK && mOnKeyboardDismissedListener != null) {
48 | mOnKeyboardDismissedListener.onKeyboardDismissed();
49 | }
50 | return super.onKeyPreIme(keyCode, ev);
51 | }
52 |
53 | public void setOnKeyboardDismissedListener(OnKeyboardDismissedListener onKeyboardDismissedListener) {
54 | mOnKeyboardDismissedListener = onKeyboardDismissedListener;
55 | }
56 |
57 | public void setOnSearchKeyListener(OnKeyboardSearchKeyClickListener searchKeyListener) {
58 | mSearchKeyListener = searchKeyListener;
59 | }
60 |
61 | public interface OnKeyboardDismissedListener {
62 | void onKeyboardDismissed();
63 | }
64 |
65 | public interface OnKeyboardSearchKeyClickListener {
66 | void onSearchKeyClicked();
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/library/src/main/res/drawable-hdpi/ic_arrow_back_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-hdpi/ic_arrow_back_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-hdpi/ic_clear_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-hdpi/ic_clear_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-hdpi/ic_history_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-hdpi/ic_history_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-hdpi/ic_invert_colors_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-hdpi/ic_invert_colors_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-hdpi/ic_mic_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-hdpi/ic_mic_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-hdpi/ic_more_vert_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-hdpi/ic_more_vert_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-hdpi/ic_search_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-hdpi/ic_search_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-mdpi/ic_arrow_back_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-mdpi/ic_arrow_back_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-mdpi/ic_clear_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-mdpi/ic_clear_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-mdpi/ic_history_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-mdpi/ic_history_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-mdpi/ic_invert_colors_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-mdpi/ic_invert_colors_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-mdpi/ic_mic_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-mdpi/ic_mic_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-mdpi/ic_more_vert_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-mdpi/ic_more_vert_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-mdpi/ic_search_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-mdpi/ic_search_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-v21/oval_btn_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | -
7 |
8 |
9 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/library/src/main/res/drawable-v21/rect_btn_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 | -
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/library/src/main/res/drawable-v21/suggestion_item_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 | -
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xhdpi/ic_arrow_back_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-xhdpi/ic_arrow_back_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xhdpi/ic_clear_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-xhdpi/ic_clear_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xhdpi/ic_history_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-xhdpi/ic_history_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xhdpi/ic_invert_colors_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-xhdpi/ic_invert_colors_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xhdpi/ic_mic_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-xhdpi/ic_mic_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xhdpi/ic_more_vert_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-xhdpi/ic_more_vert_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xhdpi/ic_search_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-xhdpi/ic_search_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xxhdpi/ic_arrow_back_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-xxhdpi/ic_arrow_back_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xxhdpi/ic_clear_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-xxhdpi/ic_clear_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xxhdpi/ic_history_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-xxhdpi/ic_history_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xxhdpi/ic_invert_colors_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-xxhdpi/ic_invert_colors_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xxhdpi/ic_mic_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-xxhdpi/ic_mic_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xxhdpi/ic_more_vert_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-xxhdpi/ic_more_vert_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xxhdpi/ic_search_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-xxhdpi/ic_search_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xxxhdpi/ic_arrow_back_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-xxxhdpi/ic_arrow_back_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xxxhdpi/ic_clear_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-xxxhdpi/ic_clear_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xxxhdpi/ic_history_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-xxxhdpi/ic_history_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xxxhdpi/ic_invert_colors_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-xxxhdpi/ic_invert_colors_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xxxhdpi/ic_mic_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-xxxhdpi/ic_mic_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xxxhdpi/ic_more_vert_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-xxxhdpi/ic_more_vert_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xxxhdpi/ic_search_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/library/src/main/res/drawable-xxxhdpi/ic_search_black_24dp.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable/divider_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
11 |
12 |
13 |
14 | -
15 |
16 |
17 |
22 |
23 |
24 |
25 | -
26 |
27 |
28 |
33 |
34 |
35 |
36 | -
37 |
38 |
39 |
44 |
45 |
46 |
47 | -
48 |
49 |
50 |
55 |
56 |
57 |
58 |
59 |
60 | -
61 |
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/library/src/main/res/drawable/oval_btn_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | -
6 |
7 |
8 |
9 |
10 |
11 |
12 | -
13 |
14 |
15 |
16 |
17 |
18 |
19 | -
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/library/src/main/res/drawable/suggestion_item_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | -
6 |
7 |
8 |
9 |
10 |
11 |
12 | -
13 |
14 |
15 |
16 |
17 |
18 |
19 | -
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/library/src/main/res/layout/action_item_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/library/src/main/res/layout/floating_search_layout.xml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
14 |
15 |
18 |
19 |
20 |
21 |
22 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/library/src/main/res/layout/overflow_action_item_layout.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/library/src/main/res/layout/search_query_section.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
17 |
18 |
25 |
26 |
35 |
36 |
43 |
44 |
45 |
54 |
55 |
70 |
71 |
72 |
83 |
84 |
94 |
95 |
--------------------------------------------------------------------------------
/library/src/main/res/layout/search_suggestion_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
19 |
20 |
34 |
35 |
48 |
49 |
--------------------------------------------------------------------------------
/library/src/main/res/layout/search_suggestions_section.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
17 |
18 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/library/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/library/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #F0F0F0
4 | #000000
5 | #00000000
6 | #33000000
7 | #FAFAFA
8 | #bbbbbb
9 | #FFFFFF
10 | #FFFFFF
11 | #BEBEBE
12 | #787878
13 | #787878
14 | #e9e9e9
15 | #E7E7E7
16 | #FFFFFF
17 | #F0F0F0
18 | #787878
19 | #787878
20 | #787878
21 | #787878
22 | #808080
23 |
--------------------------------------------------------------------------------
/library/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 | 48dp
3 | 4dp
4 | 4dp
5 | 20dp
6 | 68dp
7 | 64dp
8 | 16dp
9 | 3dp
10 |
11 |
12 | 24dp
13 | 48dp
14 | 12dp
15 |
16 | 18sp
17 | 16sp
18 |
19 |
--------------------------------------------------------------------------------
/sample/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/sample/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 25
5 | buildToolsVersion '25.0.3'
6 |
7 | defaultConfig {
8 | applicationId "com.arlib.floatingsearchviewdemo"
9 | minSdkVersion 14
10 | targetSdkVersion 25
11 | versionCode 11
12 | versionName "3.0"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(dir: 'libs', include: ['*.jar'])
24 | compile project(":library")
25 | compile files('libs/gson-2.4.jar')
26 | compile 'com.android.support:appcompat-v7:25.3.1'
27 | compile 'com.android.support:palette-v7:25.3.1'
28 | compile 'com.android.support:support-v4:25.3.1'
29 | }
30 |
--------------------------------------------------------------------------------
/sample/libs/gson-2.4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/libs/gson-2.4.jar
--------------------------------------------------------------------------------
/sample/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in C:\Users\ari\AppData\Local\Android\sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | ##---------------Begin: proguard configuration for Gson ----------
20 |
21 | #the sample project uses GSON, so if you set minifyEnabled to true, make sure to uncomment the below progaurd rules for GSON
22 | #-keepattributes Signature
23 | #-keepattributes *Annotation*
24 | #-keep class sun.misc.Unsafe { *; }
25 | #-keep class com.google.gson.stream.** { *; }
26 | #-keep class com.google.gson.examples.android.model.** { *; }
27 |
28 | ##---------------End: proguard configuration for Gson ----------
--------------------------------------------------------------------------------
/sample/src/androidTest/java/com/arlib/floatingsearchviewdemo/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.arlib.floatingsearchviewdemo;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/sample/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
9 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/sample/src/main/assets/colors.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "hex": "#EFDECD",
4 | "name": "Almond",
5 | "rgb": "(239, 222, 205)"
6 | },
7 | {
8 | "hex": "#CD9575",
9 | "name": "Antique Brass",
10 | "rgb": "(205, 149, 117)"
11 | },
12 | {
13 | "hex": "#FDD9B5",
14 | "name": "Apricot",
15 | "rgb": "(253, 217, 181)"
16 | },
17 | {
18 | "hex": "#78DBE2",
19 | "name": "Aquamarine",
20 | "rgb": "(120, 219, 226)"
21 | },
22 | {
23 | "hex": "#87A96B",
24 | "name": "Asparagus",
25 | "rgb": "(135, 169, 107)"
26 | },
27 | {
28 | "hex": "#FFA474",
29 | "name": "Atomic Tangerine",
30 | "rgb": "(255, 164, 116)"
31 | },
32 | {
33 | "hex": "#FAE7B5",
34 | "name": "Banana Mania",
35 | "rgb": "(250, 231, 181)"
36 | },
37 | {
38 | "hex": "#9F8170",
39 | "name": "Beaver",
40 | "rgb": "(159, 129, 112)"
41 | },
42 | {
43 | "hex": "#FD7C6E",
44 | "name": "Bittersweet",
45 | "rgb": "(253, 124, 110)"
46 | },
47 | {
48 | "hex": "#000000",
49 | "name": "Black",
50 | "rgb": "(0,0,0)"
51 | },
52 | {
53 | "hex": "#ACE5EE",
54 | "name": "Blizzard Blue",
55 | "rgb": "(172, 229, 238)"
56 | },
57 | {
58 | "hex": "#1F75FE",
59 | "name": "Blue",
60 | "rgb": "(31, 117, 254)"
61 | },
62 | {
63 | "hex": "#A2A2D0",
64 | "name": "Blue Bell",
65 | "rgb": "(162, 162, 208)"
66 | },
67 | {
68 | "hex": "#6699CC",
69 | "name": "Blue Gray",
70 | "rgb": "(102, 153, 204)"
71 | },
72 | {
73 | "hex": "#0D98BA",
74 | "name": "Blue Green",
75 | "rgb": "(13, 152, 186)"
76 | },
77 | {
78 | "hex": "#7366BD",
79 | "name": "Blue Violet",
80 | "rgb": "(115, 102, 189)"
81 | },
82 | {
83 | "hex": "#DE5D83",
84 | "name": "Blush",
85 | "rgb": "(222, 93, 131)"
86 | },
87 | {
88 | "hex": "#CB4154",
89 | "name": "Brick Red",
90 | "rgb": "(203, 65, 84)"
91 | },
92 | {
93 | "hex": "#B4674D",
94 | "name": "Brown",
95 | "rgb": "(180, 103, 77)"
96 | },
97 | {
98 | "hex": "#FF7F49",
99 | "name": "Burnt Orange",
100 | "rgb": "(255, 127, 73)"
101 | },
102 | {
103 | "hex": "#EA7E5D",
104 | "name": "Burnt Sienna",
105 | "rgb": "(234, 126, 93)"
106 | },
107 | {
108 | "hex": "#B0B7C6",
109 | "name": "Cadet Blue",
110 | "rgb": "(176, 183, 198)"
111 | },
112 | {
113 | "hex": "#FFFF99",
114 | "name": "Canary",
115 | "rgb": "(255, 255, 153)"
116 | },
117 | {
118 | "hex": "#1CD3A2",
119 | "name": "Caribbean Green",
120 | "rgb": "(28, 211, 162)"
121 | },
122 | {
123 | "hex": "#FFAACC",
124 | "name": "Carnation Pink",
125 | "rgb": "(255, 170, 204)"
126 | },
127 | {
128 | "hex": "#DD4492",
129 | "name": "Cerise",
130 | "rgb": "(221, 68, 146)"
131 | },
132 | {
133 | "hex": "#1DACD6",
134 | "name": "Cerulean",
135 | "rgb": "(29, 172, 214)"
136 | },
137 | {
138 | "hex": "#BC5D58",
139 | "name": "Chestnut",
140 | "rgb": "(188, 93, 88)"
141 | },
142 | {
143 | "hex": "#DD9475",
144 | "name": "Copper",
145 | "rgb": "(221, 148, 117)"
146 | },
147 | {
148 | "hex": "#9ACEEB",
149 | "name": "Cornflower",
150 | "rgb": "(154, 206, 235)"
151 | },
152 | {
153 | "hex": "#FFBCD9",
154 | "name": "Cotton Candy",
155 | "rgb": "(255, 188, 217)"
156 | },
157 | {
158 | "hex": "#FDDB6D",
159 | "name": "Dandelion",
160 | "rgb": "(253, 219, 109)"
161 | },
162 | {
163 | "hex": "#2B6CC4",
164 | "name": "Denim",
165 | "rgb": "(43, 108, 196)"
166 | },
167 | {
168 | "hex": "#EFCDB8",
169 | "name": "Desert Sand",
170 | "rgb": "(239, 205, 184)"
171 | },
172 | {
173 | "hex": "#6E5160",
174 | "name": "Eggplant",
175 | "rgb": "(110, 81, 96)"
176 | },
177 | {
178 | "hex": "#CEFF1D",
179 | "name": "Electric Lime",
180 | "rgb": "(206, 255, 29)"
181 | },
182 | {
183 | "hex": "#71BC78",
184 | "name": "Fern",
185 | "rgb": "(113, 188, 120)"
186 | },
187 | {
188 | "hex": "#6DAE81",
189 | "name": "Forest Green",
190 | "rgb": "(109, 174, 129)"
191 | },
192 | {
193 | "hex": "#C364C5",
194 | "name": "Fuchsia",
195 | "rgb": "(195, 100, 197)"
196 | },
197 | {
198 | "hex": "#CC6666",
199 | "name": "Fuzzy Wuzzy",
200 | "rgb": "(204, 102, 102)"
201 | },
202 | {
203 | "hex": "#E7C697",
204 | "name": "Gold",
205 | "rgb": "(231, 198, 151)"
206 | },
207 | {
208 | "hex": "#FCD975",
209 | "name": "Goldenrod",
210 | "rgb": "(252, 217, 117)"
211 | },
212 | {
213 | "hex": "#A8E4A0",
214 | "name": "Granny Smith Apple",
215 | "rgb": "(168, 228, 160)"
216 | },
217 | {
218 | "hex": "#95918C",
219 | "name": "Gray",
220 | "rgb": "(149, 145, 140)"
221 | },
222 | {
223 | "hex": "#1CAC78",
224 | "name": "Green",
225 | "rgb": "(28, 172, 120)"
226 | },
227 | {
228 | "hex": "#1164B4",
229 | "name": "Green Blue",
230 | "rgb": "(17, 100, 180)"
231 | },
232 | {
233 | "hex": "#F0E891",
234 | "name": "Green Yellow",
235 | "rgb": "(240, 232, 145)"
236 | },
237 | {
238 | "hex": "#FF1DCE",
239 | "name": "Hot Magenta",
240 | "rgb": "(255, 29, 206)"
241 | },
242 | {
243 | "hex": "#B2EC5D",
244 | "name": "Inchworm",
245 | "rgb": "(178, 236, 93)"
246 | },
247 | {
248 | "hex": "#5D76CB",
249 | "name": "Indigo",
250 | "rgb": "(93, 118, 203)"
251 | },
252 | {
253 | "hex": "#CA3767",
254 | "name": "Jazzberry Jam",
255 | "rgb": "(202, 55, 103)"
256 | },
257 | {
258 | "hex": "#3BB08F",
259 | "name": "Jungle Green",
260 | "rgb": "(59, 176, 143)"
261 | },
262 | {
263 | "hex": "#FEFE22",
264 | "name": "Laser Lemon",
265 | "rgb": "(254, 254, 34)"
266 | },
267 | {
268 | "hex": "#FCB4D5",
269 | "name": "Lavender",
270 | "rgb": "(252, 180, 213)"
271 | },
272 | {
273 | "hex": "#FFF44F",
274 | "name": "Lemon Yellow",
275 | "rgb": "(255, 244, 79)"
276 | },
277 | {
278 | "hex": "#FFBD88",
279 | "name": "Macaroni and Cheese",
280 | "rgb": "(255, 189, 136)"
281 | },
282 | {
283 | "hex": "#F664AF",
284 | "name": "Magenta",
285 | "rgb": "(246, 100, 175)"
286 | },
287 | {
288 | "hex": "#AAF0D1",
289 | "name": "Magic Mint",
290 | "rgb": "(170, 240, 209)"
291 | },
292 | {
293 | "hex": "#CD4A4C",
294 | "name": "Mahogany",
295 | "rgb": "(205, 74, 76)"
296 | },
297 | {
298 | "hex": "#EDD19C",
299 | "name": "Maize",
300 | "rgb": "(237, 209, 156)"
301 | },
302 | {
303 | "hex": "#979AAA",
304 | "name": "Manatee",
305 | "rgb": "(151, 154, 170)"
306 | },
307 | {
308 | "hex": "#FF8243",
309 | "name": "Mango Tango",
310 | "rgb": "(255, 130, 67)"
311 | },
312 | {
313 | "hex": "#C8385A",
314 | "name": "Maroon",
315 | "rgb": "(200, 56, 90)"
316 | },
317 | {
318 | "hex": "#EF98AA",
319 | "name": "Mauvelous",
320 | "rgb": "(239, 152, 170)"
321 | },
322 | {
323 | "hex": "#FDBCB4",
324 | "name": "Melon",
325 | "rgb": "(253, 188, 180)"
326 | },
327 | {
328 | "hex": "#1A4876",
329 | "name": "Midnight Blue",
330 | "rgb": "(26, 72, 118)"
331 | },
332 | {
333 | "hex": "#30BA8F",
334 | "name": "Mountain Meadow",
335 | "rgb": "(48, 186, 143)"
336 | },
337 | {
338 | "hex": "#C54B8C",
339 | "name": "Mulberry",
340 | "rgb": "(197, 75, 140)"
341 | },
342 | {
343 | "hex": "#1974D2",
344 | "name": "Navy Blue",
345 | "rgb": "(25, 116, 210)"
346 | },
347 | {
348 | "hex": "#FFA343",
349 | "name": "Neon Carrot",
350 | "rgb": "(255, 163, 67)"
351 | },
352 | {
353 | "hex": "#BAB86C",
354 | "name": "Olive Green",
355 | "rgb": "(186, 184, 108)"
356 | },
357 | {
358 | "hex": "#FF7538",
359 | "name": "Orange",
360 | "rgb": "(255, 117, 56)"
361 | },
362 | {
363 | "hex": "#FF2B2B",
364 | "name": "Orange Red",
365 | "rgb": "(255, 43, 43)"
366 | },
367 | {
368 | "hex": "#F8D568",
369 | "name": "Orange Yellow",
370 | "rgb": "(248, 213, 104)"
371 | },
372 | {
373 | "hex": "#E6A8D7",
374 | "name": "Orchid",
375 | "rgb": "(230, 168, 215)"
376 | },
377 | {
378 | "hex": "#414A4C",
379 | "name": "Outer Space",
380 | "rgb": "(65, 74, 76)"
381 | },
382 | {
383 | "hex": "#FF6E4A",
384 | "name": "Outrageous Orange",
385 | "rgb": "(255, 110, 74)"
386 | },
387 | {
388 | "hex": "#1CA9C9",
389 | "name": "Pacific Blue",
390 | "rgb": "(28, 169, 201)"
391 | },
392 | {
393 | "hex": "#FFCFAB",
394 | "name": "Peach",
395 | "rgb": "(255, 207, 171)"
396 | },
397 | {
398 | "hex": "#C5D0E6",
399 | "name": "Periwinkle",
400 | "rgb": "(197, 208, 230)"
401 | },
402 | {
403 | "hex": "#FDDDE6",
404 | "name": "Piggy Pink",
405 | "rgb": "(253, 221, 230)"
406 | },
407 | {
408 | "hex": "#158078",
409 | "name": "Pine Green",
410 | "rgb": "(21, 128, 120)"
411 | },
412 | {
413 | "hex": "#FC74FD",
414 | "name": "Pink Flamingo",
415 | "rgb": "(252, 116, 253)"
416 | },
417 | {
418 | "hex": "#F78FA7",
419 | "name": "Pink Sherbet",
420 | "rgb": "(247, 143, 167)"
421 | },
422 | {
423 | "hex": "#8E4585",
424 | "name": "Plum",
425 | "rgb": "(142, 69, 133)"
426 | },
427 | {
428 | "hex": "#7442C8",
429 | "name": "Purple Heart",
430 | "rgb": "(116, 66, 200)"
431 | },
432 | {
433 | "hex": "#9D81BA",
434 | "name": "Purple Mountain's Majesty",
435 | "rgb": "(157, 129, 186)"
436 | },
437 | {
438 | "hex": "#FE4EDA",
439 | "name": "Purple Pizzazz",
440 | "rgb": "(254, 78, 218)"
441 | },
442 | {
443 | "hex": "#FF496C",
444 | "name": "Radical Red",
445 | "rgb": "(255, 73, 108)"
446 | },
447 | {
448 | "hex": "#D68A59",
449 | "name": "Raw Sienna",
450 | "rgb": "(214, 138, 89)"
451 | },
452 | {
453 | "hex": "#714B23",
454 | "name": "Raw Umber",
455 | "rgb": "(113, 75, 35)"
456 | },
457 | {
458 | "hex": "#FF48D0",
459 | "name": "Razzle Dazzle Rose",
460 | "rgb": "(255, 72, 208)"
461 | },
462 | {
463 | "hex": "#E3256B",
464 | "name": "Razzmatazz",
465 | "rgb": "(227, 37, 107)"
466 | },
467 | {
468 | "hex": "#EE204D",
469 | "name": "Red",
470 | "rgb": "(238,32 ,77 )"
471 | },
472 | {
473 | "hex": "#FF5349",
474 | "name": "Red Orange",
475 | "rgb": "(255, 83, 73)"
476 | },
477 | {
478 | "hex": "#C0448F",
479 | "name": "Red Violet",
480 | "rgb": "(192, 68, 143)"
481 | },
482 | {
483 | "hex": "#1FCECB",
484 | "name": "Robin's Egg Blue",
485 | "rgb": "(31, 206, 203)"
486 | },
487 | {
488 | "hex": "#7851A9",
489 | "name": "Royal Purple",
490 | "rgb": "(120, 81, 169)"
491 | },
492 | {
493 | "hex": "#FF9BAA",
494 | "name": "Salmon",
495 | "rgb": "(255, 155, 170)"
496 | },
497 | {
498 | "hex": "#FC2847",
499 | "name": "Scarlet",
500 | "rgb": "(252, 40, 71)"
501 | },
502 | {
503 | "hex": "#76FF7A",
504 | "name": "Screamin' Green",
505 | "rgb": "(118, 255, 122)"
506 | },
507 | {
508 | "hex": "#9FE2BF",
509 | "name": "Sea Green",
510 | "rgb": "(159, 226, 191)"
511 | },
512 | {
513 | "hex": "#A5694F",
514 | "name": "Sepia",
515 | "rgb": "(165, 105, 79)"
516 | },
517 | {
518 | "hex": "#8A795D",
519 | "name": "Shadow",
520 | "rgb": "(138, 121, 93)"
521 | },
522 | {
523 | "hex": "#45CEA2",
524 | "name": "Shamrock",
525 | "rgb": "(69, 206, 162)"
526 | },
527 | {
528 | "hex": "#FB7EFD",
529 | "name": "Shocking Pink",
530 | "rgb": "(251, 126, 253)"
531 | },
532 | {
533 | "hex": "#CDC5C2",
534 | "name": "Silver",
535 | "rgb": "(205, 197, 194)"
536 | },
537 | {
538 | "hex": "#80DAEB",
539 | "name": "Sky Blue",
540 | "rgb": "(128, 218, 235)"
541 | },
542 | {
543 | "hex": "#ECEABE",
544 | "name": "Spring Green",
545 | "rgb": "(236, 234, 190)"
546 | },
547 | {
548 | "hex": "#FFCF48",
549 | "name": "Sunglow",
550 | "rgb": "(255, 207, 72)"
551 | },
552 | {
553 | "hex": "#FD5E53",
554 | "name": "Sunset Orange",
555 | "rgb": "(253, 94, 83)"
556 | },
557 | {
558 | "hex": "#FAA76C",
559 | "name": "Tan",
560 | "rgb": "(250, 167, 108)"
561 | },
562 | {
563 | "hex": "#18A7B5",
564 | "name": "Teal Blue",
565 | "rgb": "(24, 167, 181)"
566 | },
567 | {
568 | "hex": "#EBC7DF",
569 | "name": "Thistle",
570 | "rgb": "(235, 199, 223)"
571 | },
572 | {
573 | "hex": "#FC89AC",
574 | "name": "Tickle Me Pink",
575 | "rgb": "(252, 137, 172)"
576 | },
577 | {
578 | "hex": "#DBD7D2",
579 | "name": "Timberwolf",
580 | "rgb": "(219, 215, 210)"
581 | },
582 | {
583 | "hex": "#17806D",
584 | "name": "Tropical Rain Forest",
585 | "rgb": "(23, 128, 109)"
586 | },
587 | {
588 | "hex": "#DEAA88",
589 | "name": "Tumbleweed",
590 | "rgb": "(222, 170, 136)"
591 | },
592 | {
593 | "hex": "#77DDE7",
594 | "name": "Turquoise Blue",
595 | "rgb": "(119, 221, 231)"
596 | },
597 | {
598 | "hex": "#FFFF66",
599 | "name": "Unmellow Yellow",
600 | "rgb": "(255, 255, 102)"
601 | },
602 | {
603 | "hex": "#926EAE",
604 | "name": "Violet (Purple)",
605 | "rgb": "(146, 110, 174)"
606 | },
607 | {
608 | "hex": "#324AB2",
609 | "name": "Violet Blue",
610 | "rgb": "(50, 74, 178)"
611 | },
612 | {
613 | "hex": "#F75394",
614 | "name": "Violet Red",
615 | "rgb": "(247, 83, 148)"
616 | },
617 | {
618 | "hex": "#FFA089",
619 | "name": "Vivid Tangerine",
620 | "rgb": "(255, 160, 137)"
621 | },
622 | {
623 | "hex": "#8F509D",
624 | "name": "Vivid Violet",
625 | "rgb": "(143, 80, 157)"
626 | },
627 | {
628 | "hex": "#FFFFFF",
629 | "name": "White",
630 | "rgb": "(255, 255, 255)"
631 | },
632 | {
633 | "hex": "#A2ADD0",
634 | "name": "Wild Blue Yonder",
635 | "rgb": "(162, 173, 208)"
636 | },
637 | {
638 | "hex": "#FF43A4",
639 | "name": "Wild Strawberry",
640 | "rgb": "(255, 67, 164)"
641 | },
642 | {
643 | "hex": "#FC6C85",
644 | "name": "Wild Watermelon",
645 | "rgb": "(252, 108, 133)"
646 | },
647 | {
648 | "hex": "#CDA4DE",
649 | "name": "Wisteria",
650 | "rgb": "(205, 164, 222)"
651 | },
652 | {
653 | "hex": "#FCE883",
654 | "name": "Yellow",
655 | "rgb": "(252, 232, 131)"
656 | },
657 | {
658 | "hex": "#C5E384",
659 | "name": "Yellow Green",
660 | "rgb": "(197, 227, 132)"
661 | },
662 | {
663 | "hex": "#FFAE42",
664 | "name": "Yellow Orange",
665 | "rgb": "(255, 174, 66)"
666 | }
667 | ]
--------------------------------------------------------------------------------
/sample/src/main/java/com/arlib/floatingsearchviewdemo/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.arlib.floatingsearchviewdemo;
2 |
3 | /**
4 | * Copyright (C) 2015 Ari C.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.os.Bundle;
20 | import android.support.design.widget.NavigationView;
21 | import android.support.v4.app.Fragment;
22 | import android.support.v4.view.GravityCompat;
23 | import android.support.v4.widget.DrawerLayout;
24 | import android.support.v7.app.AppCompatActivity;
25 | import android.view.MenuItem;
26 |
27 | import com.arlib.floatingsearchview.FloatingSearchView;
28 | import com.arlib.floatingsearchviewdemo.fragment.BaseExampleFragment;
29 | import com.arlib.floatingsearchviewdemo.fragment.ScrollingSearchExampleFragment;
30 | import com.arlib.floatingsearchviewdemo.fragment.SlidingSearchResultsExampleFragment;
31 | import com.arlib.floatingsearchviewdemo.fragment.SlidingSearchViewExampleFragment;
32 |
33 | import java.util.List;
34 |
35 | public class MainActivity extends AppCompatActivity
36 | implements BaseExampleFragment.BaseExampleFragmentCallbacks, NavigationView.OnNavigationItemSelectedListener {
37 |
38 | private final String TAG = "MainActivity";
39 |
40 | private DrawerLayout mDrawerLayout;
41 |
42 | @Override
43 | protected void onCreate(Bundle savedInstanceState) {
44 | super.onCreate(savedInstanceState);
45 | setContentView(R.layout.activity_main);
46 |
47 | mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
48 | NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
49 | navigationView.setNavigationItemSelectedListener(this);
50 |
51 | showFragment(new SlidingSearchResultsExampleFragment());
52 | }
53 |
54 | @Override
55 | public void onAttachSearchViewToDrawer(FloatingSearchView searchView) {
56 | searchView.attachNavigationDrawerToMenuButton(mDrawerLayout);
57 | }
58 |
59 | @Override
60 | public void onBackPressed() {
61 | List fragments = getSupportFragmentManager().getFragments();
62 | BaseExampleFragment currentFragment = (BaseExampleFragment) fragments.get(fragments.size() - 1);
63 |
64 | if (!currentFragment.onActivityBackPress()) {
65 | super.onBackPressed();
66 | }
67 | }
68 |
69 | @Override
70 | public boolean onNavigationItemSelected(MenuItem menuItem) {
71 | mDrawerLayout.closeDrawer(GravityCompat.START);
72 | switch (menuItem.getItemId()) {
73 | case R.id.sliding_list_example:
74 | showFragment(new SlidingSearchResultsExampleFragment());
75 | return true;
76 | case R.id.sliding_search_bar_example:
77 | showFragment(new SlidingSearchViewExampleFragment());
78 | return true;
79 | case R.id.scrolling_search_bar_example:
80 | showFragment(new ScrollingSearchExampleFragment());
81 | return true;
82 | default:
83 | return true;
84 | }
85 | }
86 |
87 | private void showFragment(Fragment fragment) {
88 | getSupportFragmentManager()
89 | .beginTransaction()
90 | .replace(R.id.fragment_container, fragment).commit();
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/arlib/floatingsearchviewdemo/adapter/SearchResultsListAdapter.java:
--------------------------------------------------------------------------------
1 | package com.arlib.floatingsearchviewdemo.adapter;
2 |
3 | /**
4 | * Copyright (C) 2015 Ari C.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.app.Activity;
20 | import android.graphics.Color;
21 | import android.support.v7.graphics.Palette;
22 | import android.support.v7.widget.RecyclerView;
23 | import android.view.LayoutInflater;
24 | import android.view.View;
25 | import android.view.ViewGroup;
26 | import android.view.animation.DecelerateInterpolator;
27 | import android.widget.TextView;
28 |
29 | import com.arlib.floatingsearchview.util.Util;
30 | import com.arlib.floatingsearchviewdemo.R;
31 | import com.arlib.floatingsearchviewdemo.data.ColorWrapper;
32 |
33 | import java.util.ArrayList;
34 | import java.util.List;
35 |
36 | public class SearchResultsListAdapter extends RecyclerView.Adapter {
37 |
38 | private List mDataSet = new ArrayList<>();
39 |
40 | private int mLastAnimatedItemPosition = -1;
41 |
42 | public interface OnItemClickListener{
43 | void onClick(ColorWrapper colorWrapper);
44 | }
45 |
46 | private OnItemClickListener mItemsOnClickListener;
47 |
48 | public static class ViewHolder extends RecyclerView.ViewHolder {
49 | public final TextView mColorName;
50 | public final TextView mColorValue;
51 | public final View mTextContainer;
52 |
53 | public ViewHolder(View view) {
54 | super(view);
55 | mColorName = (TextView) view.findViewById(R.id.color_name);
56 | mColorValue = (TextView) view.findViewById(R.id.color_value);
57 | mTextContainer = view.findViewById(R.id.text_container);
58 | }
59 | }
60 |
61 | public void swapData(List mNewDataSet) {
62 | mDataSet = mNewDataSet;
63 | notifyDataSetChanged();
64 | }
65 |
66 | public void setItemsOnClickListener(OnItemClickListener onClickListener){
67 | this.mItemsOnClickListener = onClickListener;
68 | }
69 |
70 | @Override
71 | public SearchResultsListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
72 | View view = LayoutInflater.from(parent.getContext())
73 | .inflate(R.layout.search_results_list_item, parent, false);
74 | return new ViewHolder(view);
75 | }
76 |
77 | @Override
78 | public void onBindViewHolder(SearchResultsListAdapter.ViewHolder holder, final int position) {
79 |
80 | ColorWrapper colorSuggestion = mDataSet.get(position);
81 | holder.mColorName.setText(colorSuggestion.getName());
82 | holder.mColorValue.setText(colorSuggestion.getHex());
83 |
84 | int color = Color.parseColor(colorSuggestion.getHex());
85 | holder.mColorName.setTextColor(color);
86 | holder.mColorValue.setTextColor(color);
87 |
88 | if(mLastAnimatedItemPosition < position){
89 | animateItem(holder.itemView);
90 | mLastAnimatedItemPosition = position;
91 | }
92 |
93 | if(mItemsOnClickListener != null){
94 | holder.itemView.setOnClickListener(new View.OnClickListener() {
95 | @Override
96 | public void onClick(View v) {
97 | mItemsOnClickListener.onClick(mDataSet.get(position));
98 | }
99 | });
100 | }
101 | }
102 |
103 | @Override
104 | public int getItemCount() {
105 | return mDataSet.size();
106 | }
107 |
108 | private void animateItem(View view) {
109 | view.setTranslationY(Util.getScreenHeight((Activity) view.getContext()));
110 | view.animate()
111 | .translationY(0)
112 | .setInterpolator(new DecelerateInterpolator(3.f))
113 | .setDuration(700)
114 | .start();
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/arlib/floatingsearchviewdemo/data/ColorSuggestion.java:
--------------------------------------------------------------------------------
1 | package com.arlib.floatingsearchviewdemo.data;
2 |
3 | import android.os.Parcel;
4 |
5 | import com.arlib.floatingsearchview.suggestions.model.SearchSuggestion;
6 |
7 | /**
8 | * Copyright (C) 2015 Ari C.
9 | *
10 | * Licensed under the Apache License, Version 2.0 (the "License");
11 | * you may not use this file except in compliance with the License.
12 | * You may obtain a copy of the License at
13 | *
14 | * http://www.apache.org/licenses/LICENSE-2.0
15 | *
16 | * Unless required by applicable law or agreed to in writing, software
17 | * distributed under the License is distributed on an "AS IS" BASIS,
18 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 | * See the License for the specific language governing permissions and
20 | * limitations under the License.
21 | */
22 |
23 | public class ColorSuggestion implements SearchSuggestion {
24 |
25 | private String mColorName;
26 | private boolean mIsHistory = false;
27 |
28 | public ColorSuggestion(String suggestion) {
29 | this.mColorName = suggestion.toLowerCase();
30 | }
31 |
32 | public ColorSuggestion(Parcel source) {
33 | this.mColorName = source.readString();
34 | this.mIsHistory = source.readInt() != 0;
35 | }
36 |
37 | public void setIsHistory(boolean isHistory) {
38 | this.mIsHistory = isHistory;
39 | }
40 |
41 | public boolean getIsHistory() {
42 | return this.mIsHistory;
43 | }
44 |
45 | @Override
46 | public String getBody() {
47 | return mColorName;
48 | }
49 |
50 | public static final Creator CREATOR = new Creator() {
51 | @Override
52 | public ColorSuggestion createFromParcel(Parcel in) {
53 | return new ColorSuggestion(in);
54 | }
55 |
56 | @Override
57 | public ColorSuggestion[] newArray(int size) {
58 | return new ColorSuggestion[size];
59 | }
60 | };
61 |
62 | @Override
63 | public int describeContents() {
64 | return 0;
65 | }
66 |
67 | @Override
68 | public void writeToParcel(Parcel dest, int flags) {
69 | dest.writeString(mColorName);
70 | dest.writeInt(mIsHistory ? 1 : 0);
71 | }
72 | }
--------------------------------------------------------------------------------
/sample/src/main/java/com/arlib/floatingsearchviewdemo/data/ColorWrapper.java:
--------------------------------------------------------------------------------
1 | package com.arlib.floatingsearchviewdemo.data;
2 |
3 | /**
4 | * Copyright (C) 2015 Ari C.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.os.Parcel;
20 | import android.os.Parcelable;
21 |
22 | import com.google.gson.annotations.Expose;
23 | import com.google.gson.annotations.SerializedName;
24 |
25 | public class ColorWrapper implements Parcelable {
26 |
27 | @SerializedName("hex")
28 | @Expose
29 | private String hex;
30 | @SerializedName("name")
31 | @Expose
32 | private String name;
33 | @SerializedName("rgb")
34 | @Expose
35 | private String rgb;
36 |
37 | private ColorWrapper(Parcel in) {
38 | hex = in.readString();
39 | name = in.readString();
40 | rgb = in.readString();
41 | }
42 |
43 | @Override
44 | public void writeToParcel(Parcel dest, int flags) {
45 | dest.writeString(hex);
46 | dest.writeString(name);
47 | dest.writeString(rgb);
48 | }
49 |
50 | @Override
51 | public int describeContents() {
52 | return 0;
53 | }
54 |
55 | /**
56 | *
57 | * @return
58 | * The hex
59 | */
60 | public String getHex() {
61 | return hex;
62 | }
63 |
64 | /**
65 | *
66 | * @param hex
67 | * The hex
68 | */
69 | public void setHex(String hex) {
70 | this.hex = hex;
71 | }
72 |
73 | /**
74 | *
75 | * @return
76 | * The name
77 | */
78 | public String getName() {
79 | return name;
80 | }
81 |
82 | /**
83 | *
84 | * @param name
85 | * The name
86 | */
87 | public void setName(String name) {
88 | this.name = name;
89 | }
90 |
91 | /**
92 | *
93 | * @return
94 | * The rgb
95 | */
96 | public String getRgb() {
97 | return rgb;
98 | }
99 |
100 | /**
101 | *
102 | * @param rgb
103 | * The rgb
104 | */
105 | public void setRgb(String rgb) {
106 | this.rgb = rgb;
107 | }
108 |
109 | public static final Creator CREATOR = new Creator() {
110 | @Override
111 | public ColorWrapper createFromParcel(Parcel in) {
112 | return new ColorWrapper(in);
113 | }
114 |
115 | @Override
116 | public ColorWrapper[] newArray(int size) {
117 | return new ColorWrapper[size];
118 | }
119 | };
120 | }
--------------------------------------------------------------------------------
/sample/src/main/java/com/arlib/floatingsearchviewdemo/data/DataHelper.java:
--------------------------------------------------------------------------------
1 | package com.arlib.floatingsearchviewdemo.data;
2 |
3 | /**
4 | * Copyright (C) 2015 Ari C.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.content.Context;
20 | import android.widget.Filter;
21 |
22 | import com.google.gson.Gson;
23 | import com.google.gson.reflect.TypeToken;
24 |
25 | import java.io.IOException;
26 | import java.io.InputStream;
27 | import java.lang.reflect.Type;
28 | import java.util.ArrayList;
29 | import java.util.Arrays;
30 | import java.util.Collections;
31 | import java.util.Comparator;
32 | import java.util.List;
33 |
34 | public class DataHelper {
35 |
36 | private static final String COLORS_FILE_NAME = "colors.json";
37 |
38 | private static List sColorWrappers = new ArrayList<>();
39 |
40 | private static List sColorSuggestions =
41 | new ArrayList<>(Arrays.asList(
42 | new ColorSuggestion("green"),
43 | new ColorSuggestion("blue"),
44 | new ColorSuggestion("pink"),
45 | new ColorSuggestion("purple"),
46 | new ColorSuggestion("brown"),
47 | new ColorSuggestion("gray"),
48 | new ColorSuggestion("Granny Smith Apple"),
49 | new ColorSuggestion("Indigo"),
50 | new ColorSuggestion("Periwinkle"),
51 | new ColorSuggestion("Mahogany"),
52 | new ColorSuggestion("Maize"),
53 | new ColorSuggestion("Mahogany"),
54 | new ColorSuggestion("Outer Space"),
55 | new ColorSuggestion("Melon"),
56 | new ColorSuggestion("Yellow"),
57 | new ColorSuggestion("Orange"),
58 | new ColorSuggestion("Red"),
59 | new ColorSuggestion("Orchid")));
60 |
61 | public interface OnFindColorsListener {
62 | void onResults(List results);
63 | }
64 |
65 | public interface OnFindSuggestionsListener {
66 | void onResults(List results);
67 | }
68 |
69 | public static List getHistory(Context context, int count) {
70 |
71 | List suggestionList = new ArrayList<>();
72 | ColorSuggestion colorSuggestion;
73 | for (int i = 0; i < sColorSuggestions.size(); i++) {
74 | colorSuggestion = sColorSuggestions.get(i);
75 | colorSuggestion.setIsHistory(true);
76 | suggestionList.add(colorSuggestion);
77 | if (suggestionList.size() == count) {
78 | break;
79 | }
80 | }
81 | return suggestionList;
82 | }
83 |
84 | public static void resetSuggestionsHistory() {
85 | for (ColorSuggestion colorSuggestion : sColorSuggestions) {
86 | colorSuggestion.setIsHistory(false);
87 | }
88 | }
89 |
90 | public static void findSuggestions(Context context, String query, final int limit, final long simulatedDelay,
91 | final OnFindSuggestionsListener listener) {
92 | new Filter() {
93 |
94 | @Override
95 | protected FilterResults performFiltering(CharSequence constraint) {
96 |
97 | try {
98 | Thread.sleep(simulatedDelay);
99 | } catch (InterruptedException e) {
100 | e.printStackTrace();
101 | }
102 |
103 | DataHelper.resetSuggestionsHistory();
104 | List suggestionList = new ArrayList<>();
105 | if (!(constraint == null || constraint.length() == 0)) {
106 |
107 | for (ColorSuggestion suggestion : sColorSuggestions) {
108 | if (suggestion.getBody().toUpperCase()
109 | .startsWith(constraint.toString().toUpperCase())) {
110 |
111 | suggestionList.add(suggestion);
112 | if (limit != -1 && suggestionList.size() == limit) {
113 | break;
114 | }
115 | }
116 | }
117 | }
118 |
119 | FilterResults results = new FilterResults();
120 | Collections.sort(suggestionList, new Comparator() {
121 | @Override
122 | public int compare(ColorSuggestion lhs, ColorSuggestion rhs) {
123 | return lhs.getIsHistory() ? -1 : 0;
124 | }
125 | });
126 | results.values = suggestionList;
127 | results.count = suggestionList.size();
128 |
129 | return results;
130 | }
131 |
132 | @Override
133 | protected void publishResults(CharSequence constraint, FilterResults results) {
134 |
135 | if (listener != null) {
136 | listener.onResults((List) results.values);
137 | }
138 | }
139 | }.filter(query);
140 |
141 | }
142 |
143 |
144 | public static void findColors(Context context, String query, final OnFindColorsListener listener) {
145 | initColorWrapperList(context);
146 |
147 | new Filter() {
148 |
149 | @Override
150 | protected FilterResults performFiltering(CharSequence constraint) {
151 |
152 |
153 | List suggestionList = new ArrayList<>();
154 |
155 | if (!(constraint == null || constraint.length() == 0)) {
156 |
157 | for (ColorWrapper color : sColorWrappers) {
158 | if (color.getName().toUpperCase()
159 | .startsWith(constraint.toString().toUpperCase())) {
160 |
161 | suggestionList.add(color);
162 | }
163 | }
164 |
165 | }
166 |
167 | FilterResults results = new FilterResults();
168 | results.values = suggestionList;
169 | results.count = suggestionList.size();
170 |
171 | return results;
172 | }
173 |
174 | @Override
175 | protected void publishResults(CharSequence constraint, FilterResults results) {
176 |
177 | if (listener != null) {
178 | listener.onResults((List) results.values);
179 | }
180 | }
181 | }.filter(query);
182 |
183 | }
184 |
185 | private static void initColorWrapperList(Context context) {
186 |
187 | if (sColorWrappers.isEmpty()) {
188 | String jsonString = loadJson(context);
189 | sColorWrappers = deserializeColors(jsonString);
190 | }
191 | }
192 |
193 | private static String loadJson(Context context) {
194 |
195 | String jsonString;
196 |
197 | try {
198 | InputStream is = context.getAssets().open(COLORS_FILE_NAME);
199 | int size = is.available();
200 | byte[] buffer = new byte[size];
201 | is.read(buffer);
202 | is.close();
203 | jsonString = new String(buffer, "UTF-8");
204 | } catch (IOException ex) {
205 | ex.printStackTrace();
206 | return null;
207 | }
208 |
209 | return jsonString;
210 | }
211 |
212 | private static List deserializeColors(String jsonString) {
213 |
214 | Gson gson = new Gson();
215 |
216 | Type collectionType = new TypeToken>() {
217 | }.getType();
218 | return gson.fromJson(jsonString, collectionType);
219 | }
220 |
221 | }
--------------------------------------------------------------------------------
/sample/src/main/java/com/arlib/floatingsearchviewdemo/fragment/BaseExampleFragment.java:
--------------------------------------------------------------------------------
1 | package com.arlib.floatingsearchviewdemo.fragment;
2 |
3 | import android.content.Context;
4 | import android.support.v4.app.Fragment;
5 |
6 | import com.arlib.floatingsearchview.FloatingSearchView;
7 |
8 | /**
9 | * Created by ari on 8/16/16.
10 | */
11 | public abstract class BaseExampleFragment extends Fragment {
12 |
13 |
14 | private BaseExampleFragmentCallbacks mCallbacks;
15 |
16 | public interface BaseExampleFragmentCallbacks{
17 |
18 | void onAttachSearchViewToDrawer(FloatingSearchView searchView);
19 | }
20 |
21 | @Override
22 | public void onAttach(Context context) {
23 | super.onAttach(context);
24 | if (context instanceof BaseExampleFragmentCallbacks) {
25 | mCallbacks = (BaseExampleFragmentCallbacks) context;
26 | } else {
27 | throw new RuntimeException(context.toString()
28 | + " must implement BaseExampleFragmentCallbacks");
29 | }
30 | }
31 |
32 | @Override
33 | public void onDetach() {
34 | super.onDetach();
35 | mCallbacks = null;
36 | }
37 |
38 | protected void attachSearchViewActivityDrawer(FloatingSearchView searchView){
39 | if(mCallbacks != null){
40 | mCallbacks.onAttachSearchViewToDrawer(searchView);
41 | }
42 | }
43 |
44 | public abstract boolean onActivityBackPress();
45 | }
46 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/arlib/floatingsearchviewdemo/fragment/ScrollingSearchExampleFragment.java:
--------------------------------------------------------------------------------
1 | package com.arlib.floatingsearchviewdemo.fragment;
2 |
3 | import android.graphics.Color;
4 | import android.os.Bundle;
5 | import android.support.annotation.Nullable;
6 | import android.support.design.widget.AppBarLayout;
7 | import android.support.v4.content.res.ResourcesCompat;
8 | import android.text.Html;
9 | import android.util.Log;
10 | import android.view.LayoutInflater;
11 | import android.view.MenuItem;
12 | import android.view.View;
13 | import android.view.ViewGroup;
14 | import android.widget.ImageView;
15 | import android.widget.TextView;
16 | import android.widget.Toast;
17 |
18 | import com.arlib.floatingsearchview.FloatingSearchView;
19 | import com.arlib.floatingsearchview.suggestions.SearchSuggestionsAdapter;
20 | import com.arlib.floatingsearchview.suggestions.model.SearchSuggestion;
21 | import com.arlib.floatingsearchview.util.Util;
22 | import com.arlib.floatingsearchviewdemo.R;
23 | import com.arlib.floatingsearchviewdemo.data.ColorSuggestion;
24 | import com.arlib.floatingsearchviewdemo.data.ColorWrapper;
25 | import com.arlib.floatingsearchviewdemo.data.DataHelper;
26 |
27 | import java.util.List;
28 |
29 |
30 | public class ScrollingSearchExampleFragment extends BaseExampleFragment implements AppBarLayout.OnOffsetChangedListener {
31 | private final String TAG = "BlankFragment";
32 |
33 | public static final long FIND_SUGGESTION_SIMULATED_DELAY = 250;
34 |
35 | private FloatingSearchView mSearchView;
36 | private AppBarLayout mAppBar;
37 |
38 | private boolean mIsDarkSearchTheme = false;
39 |
40 | private String mLastQuery = "";
41 |
42 | public ScrollingSearchExampleFragment() {
43 | // Required empty public constructor
44 | }
45 |
46 | @Override
47 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
48 | Bundle savedInstanceState) {
49 | return inflater.inflate(R.layout.fragment_scrolling_search_example, container, false);
50 | }
51 |
52 | @Override
53 | public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
54 | super.onViewCreated(view, savedInstanceState);
55 | mSearchView = (FloatingSearchView) view.findViewById(R.id.floating_search_view);
56 | mAppBar = (AppBarLayout) view.findViewById(R.id.appbar);
57 |
58 | mAppBar.addOnOffsetChangedListener(this);
59 |
60 | setupDrawer();
61 | setupSearchBar();
62 | }
63 |
64 | private void setupSearchBar() {
65 | mSearchView.setOnQueryChangeListener(new FloatingSearchView.OnQueryChangeListener() {
66 |
67 | @Override
68 | public void onSearchTextChanged(String oldQuery, final String newQuery) {
69 |
70 | if (!oldQuery.equals("") && newQuery.equals("")) {
71 | mSearchView.clearSuggestions();
72 | } else {
73 |
74 | //this shows the top left circular progress
75 | //you can call it where ever you want, but
76 | //it makes sense to do it when loading something in
77 | //the background.
78 | mSearchView.showProgress();
79 |
80 | //simulates a query call to a data source
81 | //with a new query.
82 | DataHelper.findSuggestions(getActivity(), newQuery, 5,
83 | FIND_SUGGESTION_SIMULATED_DELAY, new DataHelper.OnFindSuggestionsListener() {
84 |
85 | @Override
86 | public void onResults(List results) {
87 |
88 | //this will swap the data and
89 | //render the collapse/expand animations as necessary
90 | mSearchView.swapSuggestions(results);
91 |
92 | //let the users know that the background
93 | //process has completed
94 | mSearchView.hideProgress();
95 | }
96 | });
97 | }
98 |
99 | Log.d(TAG, "onSearchTextChanged()");
100 | }
101 | });
102 |
103 | mSearchView.setOnSearchListener(new FloatingSearchView.OnSearchListener() {
104 | @Override
105 | public void onSuggestionClicked(final SearchSuggestion searchSuggestion) {
106 |
107 | ColorSuggestion colorSuggestion = (ColorSuggestion) searchSuggestion;
108 | DataHelper.findColors(getActivity(), colorSuggestion.getBody(),
109 | new DataHelper.OnFindColorsListener() {
110 |
111 | @Override
112 | public void onResults(List results) {
113 | //show search results
114 | }
115 |
116 | });
117 | Log.d(TAG, "onSuggestionClicked()");
118 |
119 | mLastQuery = searchSuggestion.getBody();
120 | }
121 |
122 | @Override
123 | public void onSearchAction(String query) {
124 | mLastQuery = query;
125 |
126 | DataHelper.findColors(getActivity(), query,
127 | new DataHelper.OnFindColorsListener() {
128 |
129 | @Override
130 | public void onResults(List results) {
131 | //show search results
132 | }
133 |
134 | });
135 | Log.d(TAG, "onSearchAction()");
136 | }
137 | });
138 |
139 | mSearchView.setOnFocusChangeListener(new FloatingSearchView.OnFocusChangeListener() {
140 | @Override
141 | public void onFocus() {
142 |
143 | //show suggestions when search bar gains focus (typically history suggestions)
144 | mSearchView.swapSuggestions(DataHelper.getHistory(getActivity(), 3));
145 |
146 | Log.d(TAG, "onFocus()");
147 | }
148 |
149 | @Override
150 | public void onFocusCleared() {
151 |
152 | //set the title of the bar so that when focus is returned a new query begins
153 | mSearchView.setSearchBarTitle(mLastQuery);
154 |
155 | //you can also set setSearchText(...) to make keep the query there when not focused and when focus returns
156 | //mSearchView.setSearchText(searchSuggestion.getBody());
157 |
158 | Log.d(TAG, "onFocusCleared()");
159 | }
160 | });
161 |
162 |
163 | //handle menu clicks the same way as you would
164 | //in a regular activity
165 | mSearchView.setOnMenuItemClickListener(new FloatingSearchView.OnMenuItemClickListener() {
166 | @Override
167 | public void onActionMenuItemSelected(MenuItem item) {
168 |
169 | if (item.getItemId() == R.id.action_change_colors) {
170 |
171 | mIsDarkSearchTheme = true;
172 |
173 | //demonstrate setting colors for items
174 | mSearchView.setBackgroundColor(Color.parseColor("#787878"));
175 | mSearchView.setViewTextColor(Color.parseColor("#e9e9e9"));
176 | mSearchView.setHintTextColor(Color.parseColor("#e9e9e9"));
177 | mSearchView.setActionMenuOverflowColor(Color.parseColor("#e9e9e9"));
178 | mSearchView.setMenuItemIconColor(Color.parseColor("#e9e9e9"));
179 | mSearchView.setLeftActionIconColor(Color.parseColor("#e9e9e9"));
180 | mSearchView.setClearBtnColor(Color.parseColor("#e9e9e9"));
181 | mSearchView.setDividerColor(Color.parseColor("#BEBEBE"));
182 | mSearchView.setLeftActionIconColor(Color.parseColor("#e9e9e9"));
183 | } else {
184 |
185 | //just print action
186 | Toast.makeText(getActivity().getApplicationContext(), item.getTitle(),
187 | Toast.LENGTH_SHORT).show();
188 | }
189 |
190 | }
191 | });
192 |
193 | //use this listener to listen to menu clicks when app:floatingSearch_leftAction="showHome"
194 | mSearchView.setOnHomeActionClickListener(new FloatingSearchView.OnHomeActionClickListener() {
195 | @Override
196 | public void onHomeClicked() {
197 |
198 | Log.d(TAG, "onHomeClicked()");
199 | }
200 | });
201 |
202 | /*
203 | * Here you have access to the left icon and the text of a given suggestion
204 | * item after as it is bound to the suggestion list. You can utilize this
205 | * callback to change some properties of the left icon and the text. For example, you
206 | * can load the left icon images using your favorite image loading library, or change text color.
207 | *
208 | *
209 | * Important:
210 | * Keep in mind that the suggestion list is a RecyclerView, so views are reused for different
211 | * items in the list.
212 | */
213 | mSearchView.setOnBindSuggestionCallback(new SearchSuggestionsAdapter.OnBindSuggestionCallback() {
214 | @Override
215 | public void onBindSuggestion(View suggestionView, ImageView leftIcon,
216 | TextView textView, SearchSuggestion item, int itemPosition) {
217 | ColorSuggestion colorSuggestion = (ColorSuggestion) item;
218 |
219 | String textColor = mIsDarkSearchTheme ? "#ffffff" : "#000000";
220 | String textLight = mIsDarkSearchTheme ? "#bfbfbf" : "#787878";
221 |
222 | if (colorSuggestion.getIsHistory()) {
223 | leftIcon.setImageDrawable(ResourcesCompat.getDrawable(getResources(),
224 | R.drawable.ic_history_black_24dp, null));
225 |
226 | Util.setIconColor(leftIcon, Color.parseColor(textColor));
227 | leftIcon.setAlpha(.36f);
228 | } else {
229 | leftIcon.setAlpha(0.0f);
230 | leftIcon.setImageDrawable(null);
231 | }
232 |
233 | textView.setTextColor(Color.parseColor(textColor));
234 | String text = colorSuggestion.getBody()
235 | .replaceFirst(mSearchView.getQuery(),
236 | "" + mSearchView.getQuery() + "");
237 | textView.setText(Html.fromHtml(text));
238 | }
239 |
240 | });
241 | }
242 |
243 | @Override
244 | public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
245 | mSearchView.setTranslationY(verticalOffset);
246 | }
247 |
248 | @Override
249 | public boolean onActivityBackPress() {
250 | //if mSearchView.setSearchFocused(false) causes the focused search
251 | //to close, then we don't want to close the activity. if mSearchView.setSearchFocused(false)
252 | //returns false, we know that the search was already closed so the call didn't change the focus
253 | //state and it makes sense to call supper onBackPressed() and close the activity
254 | if (!mSearchView.setSearchFocused(false)) {
255 | return false;
256 | }
257 | return true;
258 | }
259 |
260 | private void setupDrawer() {
261 | attachSearchViewActivityDrawer(mSearchView);
262 | }
263 | }
264 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/arlib/floatingsearchviewdemo/fragment/SlidingSearchResultsExampleFragment.java:
--------------------------------------------------------------------------------
1 | package com.arlib.floatingsearchviewdemo.fragment;
2 |
3 | import android.graphics.Color;
4 | import android.os.Bundle;
5 | import android.support.annotation.Nullable;
6 | import android.support.v4.content.res.ResourcesCompat;
7 | import android.support.v7.widget.LinearLayoutManager;
8 | import android.support.v7.widget.RecyclerView;
9 | import android.text.Html;
10 | import android.util.Log;
11 | import android.view.LayoutInflater;
12 | import android.view.MenuItem;
13 | import android.view.View;
14 | import android.view.ViewGroup;
15 | import android.widget.ImageView;
16 | import android.widget.TextView;
17 | import android.widget.Toast;
18 |
19 | import com.arlib.floatingsearchview.FloatingSearchView;
20 | import com.arlib.floatingsearchview.suggestions.SearchSuggestionsAdapter;
21 | import com.arlib.floatingsearchview.suggestions.model.SearchSuggestion;
22 | import com.arlib.floatingsearchview.util.Util;
23 | import com.arlib.floatingsearchviewdemo.R;
24 | import com.arlib.floatingsearchviewdemo.adapter.SearchResultsListAdapter;
25 | import com.arlib.floatingsearchviewdemo.data.ColorSuggestion;
26 | import com.arlib.floatingsearchviewdemo.data.ColorWrapper;
27 | import com.arlib.floatingsearchviewdemo.data.DataHelper;
28 |
29 | import java.util.List;
30 |
31 |
32 | public class SlidingSearchResultsExampleFragment extends BaseExampleFragment {
33 | private final String TAG = "BlankFragment";
34 |
35 | public static final long FIND_SUGGESTION_SIMULATED_DELAY = 250;
36 |
37 | private FloatingSearchView mSearchView;
38 |
39 | private RecyclerView mSearchResultsList;
40 | private SearchResultsListAdapter mSearchResultsAdapter;
41 |
42 | private boolean mIsDarkSearchTheme = false;
43 |
44 | private String mLastQuery = "";
45 |
46 | public SlidingSearchResultsExampleFragment() {
47 | // Required empty public constructor
48 | }
49 |
50 | @Override
51 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
52 | Bundle savedInstanceState) {
53 | return inflater.inflate(R.layout.fragment_sliding_search_results_example_fragment, container, false);
54 | }
55 |
56 | @Override
57 | public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
58 | super.onViewCreated(view, savedInstanceState);
59 | mSearchView = (FloatingSearchView) view.findViewById(R.id.floating_search_view);
60 | mSearchResultsList = (RecyclerView) view.findViewById(R.id.search_results_list);
61 |
62 | setupFloatingSearch();
63 | setupResultsList();
64 | setupDrawer();
65 | }
66 |
67 | private void setupFloatingSearch() {
68 | mSearchView.setOnQueryChangeListener(new FloatingSearchView.OnQueryChangeListener() {
69 |
70 | @Override
71 | public void onSearchTextChanged(String oldQuery, final String newQuery) {
72 |
73 | if (!oldQuery.equals("") && newQuery.equals("")) {
74 | mSearchView.clearSuggestions();
75 | } else {
76 |
77 | //this shows the top left circular progress
78 | //you can call it where ever you want, but
79 | //it makes sense to do it when loading something in
80 | //the background.
81 | mSearchView.showProgress();
82 |
83 | //simulates a query call to a data source
84 | //with a new query.
85 | DataHelper.findSuggestions(getActivity(), newQuery, 5,
86 | FIND_SUGGESTION_SIMULATED_DELAY, new DataHelper.OnFindSuggestionsListener() {
87 |
88 | @Override
89 | public void onResults(List results) {
90 |
91 | //this will swap the data and
92 | //render the collapse/expand animations as necessary
93 | mSearchView.swapSuggestions(results);
94 |
95 | //let the users know that the background
96 | //process has completed
97 | mSearchView.hideProgress();
98 | }
99 | });
100 | }
101 |
102 | Log.d(TAG, "onSearchTextChanged()");
103 | }
104 | });
105 |
106 | mSearchView.setOnSearchListener(new FloatingSearchView.OnSearchListener() {
107 | @Override
108 | public void onSuggestionClicked(final SearchSuggestion searchSuggestion) {
109 |
110 | ColorSuggestion colorSuggestion = (ColorSuggestion) searchSuggestion;
111 | DataHelper.findColors(getActivity(), colorSuggestion.getBody(),
112 | new DataHelper.OnFindColorsListener() {
113 |
114 | @Override
115 | public void onResults(List results) {
116 | mSearchResultsAdapter.swapData(results);
117 | }
118 |
119 | });
120 | Log.d(TAG, "onSuggestionClicked()");
121 |
122 | mLastQuery = searchSuggestion.getBody();
123 | }
124 |
125 | @Override
126 | public void onSearchAction(String query) {
127 | mLastQuery = query;
128 |
129 | DataHelper.findColors(getActivity(), query,
130 | new DataHelper.OnFindColorsListener() {
131 |
132 | @Override
133 | public void onResults(List results) {
134 | mSearchResultsAdapter.swapData(results);
135 | }
136 |
137 | });
138 | Log.d(TAG, "onSearchAction()");
139 | }
140 | });
141 |
142 | mSearchView.setOnFocusChangeListener(new FloatingSearchView.OnFocusChangeListener() {
143 | @Override
144 | public void onFocus() {
145 |
146 | //show suggestions when search bar gains focus (typically history suggestions)
147 | mSearchView.swapSuggestions(DataHelper.getHistory(getActivity(), 3));
148 |
149 | Log.d(TAG, "onFocus()");
150 | }
151 |
152 | @Override
153 | public void onFocusCleared() {
154 |
155 | //set the title of the bar so that when focus is returned a new query begins
156 | mSearchView.setSearchBarTitle(mLastQuery);
157 |
158 | //you can also set setSearchText(...) to make keep the query there when not focused and when focus returns
159 | //mSearchView.setSearchText(searchSuggestion.getBody());
160 |
161 | Log.d(TAG, "onFocusCleared()");
162 | }
163 | });
164 |
165 |
166 | //handle menu clicks the same way as you would
167 | //in a regular activity
168 | mSearchView.setOnMenuItemClickListener(new FloatingSearchView.OnMenuItemClickListener() {
169 | @Override
170 | public void onActionMenuItemSelected(MenuItem item) {
171 |
172 | if (item.getItemId() == R.id.action_change_colors) {
173 |
174 | mIsDarkSearchTheme = true;
175 |
176 | //demonstrate setting colors for items
177 | mSearchView.setBackgroundColor(Color.parseColor("#787878"));
178 | mSearchView.setViewTextColor(Color.parseColor("#e9e9e9"));
179 | mSearchView.setHintTextColor(Color.parseColor("#e9e9e9"));
180 | mSearchView.setActionMenuOverflowColor(Color.parseColor("#e9e9e9"));
181 | mSearchView.setMenuItemIconColor(Color.parseColor("#e9e9e9"));
182 | mSearchView.setLeftActionIconColor(Color.parseColor("#e9e9e9"));
183 | mSearchView.setClearBtnColor(Color.parseColor("#e9e9e9"));
184 | mSearchView.setDividerColor(Color.parseColor("#BEBEBE"));
185 | mSearchView.setLeftActionIconColor(Color.parseColor("#e9e9e9"));
186 | } else {
187 |
188 | //just print action
189 | Toast.makeText(getActivity().getApplicationContext(), item.getTitle(),
190 | Toast.LENGTH_SHORT).show();
191 | }
192 |
193 | }
194 | });
195 |
196 | //use this listener to listen to menu clicks when app:floatingSearch_leftAction="showHome"
197 | mSearchView.setOnHomeActionClickListener(new FloatingSearchView.OnHomeActionClickListener() {
198 | @Override
199 | public void onHomeClicked() {
200 |
201 | Log.d(TAG, "onHomeClicked()");
202 | }
203 | });
204 |
205 | /*
206 | * Here you have access to the left icon and the text of a given suggestion
207 | * item after as it is bound to the suggestion list. You can utilize this
208 | * callback to change some properties of the left icon and the text. For example, you
209 | * can load the left icon images using your favorite image loading library, or change text color.
210 | *
211 | *
212 | * Important:
213 | * Keep in mind that the suggestion list is a RecyclerView, so views are reused for different
214 | * items in the list.
215 | */
216 | mSearchView.setOnBindSuggestionCallback(new SearchSuggestionsAdapter.OnBindSuggestionCallback() {
217 | @Override
218 | public void onBindSuggestion(View suggestionView, ImageView leftIcon,
219 | TextView textView, SearchSuggestion item, int itemPosition) {
220 | ColorSuggestion colorSuggestion = (ColorSuggestion) item;
221 |
222 | String textColor = mIsDarkSearchTheme ? "#ffffff" : "#000000";
223 | String textLight = mIsDarkSearchTheme ? "#bfbfbf" : "#787878";
224 |
225 | if (colorSuggestion.getIsHistory()) {
226 | leftIcon.setImageDrawable(ResourcesCompat.getDrawable(getResources(),
227 | R.drawable.ic_history_black_24dp, null));
228 |
229 | Util.setIconColor(leftIcon, Color.parseColor(textColor));
230 | leftIcon.setAlpha(.36f);
231 | } else {
232 | leftIcon.setAlpha(0.0f);
233 | leftIcon.setImageDrawable(null);
234 | }
235 |
236 | textView.setTextColor(Color.parseColor(textColor));
237 | String text = colorSuggestion.getBody()
238 | .replaceFirst(mSearchView.getQuery(),
239 | "" + mSearchView.getQuery() + "");
240 | textView.setText(Html.fromHtml(text));
241 | }
242 |
243 | });
244 |
245 | //listen for when suggestion list expands/shrinks in order to move down/up the
246 | //search results list
247 | mSearchView.setOnSuggestionsListHeightChanged(new FloatingSearchView.OnSuggestionsListHeightChanged() {
248 | @Override
249 | public void onSuggestionsListHeightChanged(float newHeight) {
250 | mSearchResultsList.setTranslationY(newHeight);
251 | }
252 | });
253 |
254 | /*
255 | * When the user types some text into the search field, a clear button (and 'x' to the
256 | * right) of the search text is shown.
257 | *
258 | * This listener provides a callback for when this button is clicked.
259 | */
260 | mSearchView.setOnClearSearchActionListener(new FloatingSearchView.OnClearSearchActionListener() {
261 | @Override
262 | public void onClearSearchClicked() {
263 |
264 | Log.d(TAG, "onClearSearchClicked()");
265 | }
266 | });
267 | }
268 |
269 | private void setupResultsList() {
270 | mSearchResultsAdapter = new SearchResultsListAdapter();
271 | mSearchResultsList.setAdapter(mSearchResultsAdapter);
272 | mSearchResultsList.setLayoutManager(new LinearLayoutManager(getContext()));
273 | }
274 |
275 | @Override
276 | public boolean onActivityBackPress() {
277 | //if mSearchView.setSearchFocused(false) causes the focused search
278 | //to close, then we don't want to close the activity. if mSearchView.setSearchFocused(false)
279 | //returns false, we know that the search was already closed so the call didn't change the focus
280 | //state and it makes sense to call supper onBackPressed() and close the activity
281 | if (!mSearchView.setSearchFocused(false)) {
282 | return false;
283 | }
284 | return true;
285 | }
286 |
287 | private void setupDrawer() {
288 | attachSearchViewActivityDrawer(mSearchView);
289 | }
290 |
291 | }
292 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/arlib/floatingsearchviewdemo/fragment/SlidingSearchViewExampleFragment.java:
--------------------------------------------------------------------------------
1 | package com.arlib.floatingsearchviewdemo.fragment;
2 |
3 | import android.animation.Animator;
4 | import android.animation.AnimatorListenerAdapter;
5 | import android.animation.ObjectAnimator;
6 | import android.animation.ValueAnimator;
7 | import android.graphics.Color;
8 | import android.graphics.drawable.ColorDrawable;
9 | import android.os.Build;
10 | import android.os.Bundle;
11 | import android.support.annotation.Nullable;
12 | import android.support.v4.content.res.ResourcesCompat;
13 | import android.text.Html;
14 | import android.util.Log;
15 | import android.view.LayoutInflater;
16 | import android.view.MenuItem;
17 | import android.view.View;
18 | import android.view.ViewGroup;
19 | import android.widget.ImageView;
20 | import android.widget.TextView;
21 | import android.widget.Toast;
22 |
23 | import com.arlib.floatingsearchview.FloatingSearchView;
24 | import com.arlib.floatingsearchview.suggestions.SearchSuggestionsAdapter;
25 | import com.arlib.floatingsearchview.suggestions.model.SearchSuggestion;
26 | import com.arlib.floatingsearchview.util.Util;
27 | import com.arlib.floatingsearchviewdemo.R;
28 | import com.arlib.floatingsearchviewdemo.data.ColorSuggestion;
29 | import com.arlib.floatingsearchviewdemo.data.DataHelper;
30 |
31 | import java.util.List;
32 |
33 |
34 | public class SlidingSearchViewExampleFragment extends BaseExampleFragment {
35 | private final String TAG = "BlankFragment";
36 |
37 | public static final long FIND_SUGGESTION_SIMULATED_DELAY = 250;
38 |
39 | private static final long ANIM_DURATION = 350;
40 |
41 | private View mHeaderView;
42 | private View mDimSearchViewBackground;
43 | private ColorDrawable mDimDrawable;
44 | private FloatingSearchView mSearchView;
45 |
46 | private boolean mIsDarkSearchTheme = false;
47 |
48 | private String mLastQuery = "";
49 |
50 | public SlidingSearchViewExampleFragment() {
51 | // Required empty public constructor
52 | }
53 |
54 | @Override
55 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
56 | Bundle savedInstanceState) {
57 | return inflater.inflate(R.layout.fragment_sliding_search_example, container, false);
58 | }
59 |
60 | @Override
61 | public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
62 | super.onViewCreated(view, savedInstanceState);
63 | mSearchView = (FloatingSearchView) view.findViewById(R.id.floating_search_view);
64 | mHeaderView = view.findViewById(R.id.header_view);
65 |
66 | mDimSearchViewBackground = view.findViewById(R.id.dim_background);
67 | mDimDrawable = new ColorDrawable(Color.BLACK);
68 | mDimDrawable.setAlpha(0);
69 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
70 | mDimSearchViewBackground.setBackground(mDimDrawable);
71 | } else {
72 | mDimSearchViewBackground.setBackgroundDrawable(mDimDrawable);
73 | }
74 |
75 | setupFloatingSearch();
76 | setupDrawer();
77 | }
78 |
79 | private void setupFloatingSearch() {
80 | mSearchView.setOnQueryChangeListener(new FloatingSearchView.OnQueryChangeListener() {
81 |
82 | @Override
83 | public void onSearchTextChanged(String oldQuery, final String newQuery) {
84 |
85 | if (!oldQuery.equals("") && newQuery.equals("")) {
86 | mSearchView.clearSuggestions();
87 | } else {
88 |
89 | //this shows the top left circular progress
90 | //you can call it where ever you want, but
91 | //it makes sense to do it when loading something in
92 | //the background.
93 | mSearchView.showProgress();
94 |
95 | //simulates a query call to a data source
96 | //with a new query.
97 | DataHelper.findSuggestions(getActivity(), newQuery, 5,
98 | FIND_SUGGESTION_SIMULATED_DELAY, new DataHelper.OnFindSuggestionsListener() {
99 |
100 | @Override
101 | public void onResults(List results) {
102 |
103 | //this will swap the data and
104 | //render the collapse/expand animations as necessary
105 | mSearchView.swapSuggestions(results);
106 |
107 | //let the users know that the background
108 | //process has completed
109 | mSearchView.hideProgress();
110 | }
111 | });
112 | }
113 |
114 | Log.d(TAG, "onSearchTextChanged()");
115 | }
116 | });
117 |
118 | mSearchView.setOnSearchListener(new FloatingSearchView.OnSearchListener() {
119 | @Override
120 | public void onSuggestionClicked(final SearchSuggestion searchSuggestion) {
121 |
122 | mLastQuery = searchSuggestion.getBody();
123 | }
124 |
125 | @Override
126 | public void onSearchAction(String query) {
127 | mLastQuery = query;
128 |
129 | Log.d(TAG, "onSearchAction()");
130 | }
131 | });
132 |
133 | mSearchView.setOnFocusChangeListener(new FloatingSearchView.OnFocusChangeListener() {
134 | @Override
135 | public void onFocus() {
136 | int headerHeight = getResources().getDimensionPixelOffset(R.dimen.sliding_search_view_header_height);
137 | ObjectAnimator anim = ObjectAnimator.ofFloat(mSearchView, "translationY",
138 | headerHeight, 0);
139 | anim.setDuration(350);
140 | fadeDimBackground(0, 150, null);
141 | anim.addListener(new AnimatorListenerAdapter() {
142 |
143 | @Override
144 | public void onAnimationEnd(Animator animation) {
145 | //show suggestions when search bar gains focus (typically history suggestions)
146 | mSearchView.swapSuggestions(DataHelper.getHistory(getActivity(), 3));
147 |
148 | }
149 | });
150 | anim.start();
151 |
152 | Log.d(TAG, "onFocus()");
153 | }
154 |
155 | @Override
156 | public void onFocusCleared() {
157 | int headerHeight = getResources().getDimensionPixelOffset(R.dimen.sliding_search_view_header_height);
158 | ObjectAnimator anim = ObjectAnimator.ofFloat(mSearchView, "translationY",
159 | 0, headerHeight);
160 | anim.setDuration(350);
161 | anim.start();
162 | fadeDimBackground(150, 0, null);
163 |
164 | //set the title of the bar so that when focus is returned a new query begins
165 | mSearchView.setSearchBarTitle(mLastQuery);
166 |
167 | //you can also set setSearchText(...) to make keep the query there when not focused and when focus returns
168 | //mSearchView.setSearchText(searchSuggestion.getBody());
169 |
170 | Log.d(TAG, "onFocusCleared()");
171 | }
172 | });
173 |
174 |
175 | //handle menu clicks the same way as you would
176 | //in a regular activity
177 | mSearchView.setOnMenuItemClickListener(new FloatingSearchView.OnMenuItemClickListener() {
178 | @Override
179 | public void onActionMenuItemSelected(MenuItem item) {
180 |
181 | if (item.getItemId() == R.id.action_change_colors) {
182 |
183 | mIsDarkSearchTheme = true;
184 |
185 | //demonstrate setting colors for items
186 | mSearchView.setBackgroundColor(Color.parseColor("#787878"));
187 | mSearchView.setViewTextColor(Color.parseColor("#e9e9e9"));
188 | mSearchView.setHintTextColor(Color.parseColor("#e9e9e9"));
189 | mSearchView.setActionMenuOverflowColor(Color.parseColor("#e9e9e9"));
190 | mSearchView.setMenuItemIconColor(Color.parseColor("#e9e9e9"));
191 | mSearchView.setLeftActionIconColor(Color.parseColor("#e9e9e9"));
192 | mSearchView.setClearBtnColor(Color.parseColor("#e9e9e9"));
193 | mSearchView.setDividerColor(Color.parseColor("#BEBEBE"));
194 | mSearchView.setLeftActionIconColor(Color.parseColor("#e9e9e9"));
195 | } else {
196 |
197 | //just print action
198 | Toast.makeText(getActivity().getApplicationContext(), item.getTitle(),
199 | Toast.LENGTH_SHORT).show();
200 | }
201 |
202 | }
203 | });
204 |
205 | //use this listener to listen to menu clicks when app:floatingSearch_leftAction="showHome"
206 | mSearchView.setOnHomeActionClickListener(new FloatingSearchView.OnHomeActionClickListener() {
207 | @Override
208 | public void onHomeClicked() {
209 |
210 | Log.d(TAG, "onHomeClicked()");
211 | }
212 | });
213 |
214 | /*
215 | * Here you have access to the left icon and the text of a given suggestion
216 | * item after as it is bound to the suggestion list. You can utilize this
217 | * callback to change some properties of the left icon and the text. For example, you
218 | * can load the left icon images using your favorite image loading library, or change text color.
219 | *
220 | *
221 | * Important:
222 | * Keep in mind that the suggestion list is a RecyclerView, so views are reused for different
223 | * items in the list.
224 | */
225 | mSearchView.setOnBindSuggestionCallback(new SearchSuggestionsAdapter.OnBindSuggestionCallback() {
226 | @Override
227 | public void onBindSuggestion(View suggestionView, ImageView leftIcon,
228 | TextView textView, SearchSuggestion item, int itemPosition) {
229 | ColorSuggestion colorSuggestion = (ColorSuggestion) item;
230 |
231 | String textColor = mIsDarkSearchTheme ? "#ffffff" : "#000000";
232 | String textLight = mIsDarkSearchTheme ? "#bfbfbf" : "#787878";
233 |
234 | if (colorSuggestion.getIsHistory()) {
235 | leftIcon.setImageDrawable(ResourcesCompat.getDrawable(getResources(),
236 | R.drawable.ic_history_black_24dp, null));
237 |
238 | Util.setIconColor(leftIcon, Color.parseColor(textColor));
239 | leftIcon.setAlpha(.36f);
240 | } else {
241 | leftIcon.setAlpha(0.0f);
242 | leftIcon.setImageDrawable(null);
243 | }
244 |
245 | textView.setTextColor(Color.parseColor(textColor));
246 | String text = colorSuggestion.getBody()
247 | .replaceFirst(mSearchView.getQuery(),
248 | "" + mSearchView.getQuery() + "");
249 | textView.setText(Html.fromHtml(text));
250 | }
251 |
252 | });
253 |
254 | /*
255 | * When the user types some text into the search field, a clear button (and 'x' to the
256 | * right) of the search text is shown.
257 | *
258 | * This listener provides a callback for when this button is clicked.
259 | */
260 | mSearchView.setOnClearSearchActionListener(new FloatingSearchView.OnClearSearchActionListener() {
261 | @Override
262 | public void onClearSearchClicked() {
263 |
264 | Log.d(TAG, "onClearSearchClicked()");
265 | }
266 | });
267 | }
268 |
269 |
270 | @Override
271 | public boolean onActivityBackPress() {
272 | //if mSearchView.setSearchFocused(false) causes the focused search
273 | //to close, then we don't want to close the activity. if mSearchView.setSearchFocused(false)
274 | //returns false, we know that the search was already closed so the call didn't change the focus
275 | //state and it makes sense to call supper onBackPressed() and close the activity
276 | if (!mSearchView.setSearchFocused(false)) {
277 | return false;
278 | }
279 | return true;
280 | }
281 |
282 | private void setupDrawer() {
283 | attachSearchViewActivityDrawer(mSearchView);
284 | }
285 |
286 | private void fadeDimBackground(int from, int to, Animator.AnimatorListener listener) {
287 | ValueAnimator anim = ValueAnimator.ofInt(from, to);
288 | anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
289 | @Override
290 | public void onAnimationUpdate(ValueAnimator animation) {
291 |
292 | int value = (Integer) animation.getAnimatedValue();
293 | mDimDrawable.setAlpha(value);
294 | }
295 | });
296 | if (listener != null) {
297 | anim.addListener(listener);
298 | }
299 | anim.setDuration(ANIM_DURATION);
300 | anim.start();
301 | }
302 | }
303 |
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-hdpi/ic_invert_colors_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/drawable-hdpi/ic_invert_colors_black_24dp.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-hdpi/ic_keyboard_voice_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/drawable-hdpi/ic_keyboard_voice_black_24dp.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-hdpi/ic_lightbulb_outline_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/drawable-hdpi/ic_lightbulb_outline_black_24dp.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-hdpi/ic_local_taxi_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/drawable-hdpi/ic_local_taxi_black_24dp.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-hdpi/ic_my_location_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/drawable-hdpi/ic_my_location_black_24dp.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-hdpi/ic_restaurant_menu_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/drawable-hdpi/ic_restaurant_menu_black_24dp.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-mdpi/ic_invert_colors_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/drawable-mdpi/ic_invert_colors_black_24dp.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-mdpi/ic_keyboard_voice_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/drawable-mdpi/ic_keyboard_voice_black_24dp.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-mdpi/ic_lightbulb_outline_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/drawable-mdpi/ic_lightbulb_outline_black_24dp.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-mdpi/ic_local_taxi_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/drawable-mdpi/ic_local_taxi_black_24dp.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-mdpi/ic_my_location_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/drawable-mdpi/ic_my_location_black_24dp.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-mdpi/ic_restaurant_menu_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/drawable-mdpi/ic_restaurant_menu_black_24dp.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xhdpi/ic_invert_colors_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/drawable-xhdpi/ic_invert_colors_black_24dp.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xhdpi/ic_keyboard_voice_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/drawable-xhdpi/ic_keyboard_voice_black_24dp.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xhdpi/ic_lightbulb_outline_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/drawable-xhdpi/ic_lightbulb_outline_black_24dp.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xhdpi/ic_local_taxi_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/drawable-xhdpi/ic_local_taxi_black_24dp.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xhdpi/ic_my_location_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/drawable-xhdpi/ic_my_location_black_24dp.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xhdpi/ic_restaurant_menu_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/drawable-xhdpi/ic_restaurant_menu_black_24dp.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxhdpi/ic_invert_colors_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/drawable-xxhdpi/ic_invert_colors_black_24dp.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxhdpi/ic_keyboard_voice_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/drawable-xxhdpi/ic_keyboard_voice_black_24dp.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxhdpi/ic_lightbulb_outline_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/drawable-xxhdpi/ic_lightbulb_outline_black_24dp.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxhdpi/ic_local_taxi_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/drawable-xxhdpi/ic_local_taxi_black_24dp.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxhdpi/ic_my_location_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/drawable-xxhdpi/ic_my_location_black_24dp.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxhdpi/ic_restaurant_menu_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/drawable-xxhdpi/ic_restaurant_menu_black_24dp.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxxhdpi/ic_invert_colors_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/drawable-xxxhdpi/ic_invert_colors_black_24dp.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxxhdpi/ic_keyboard_voice_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/drawable-xxxhdpi/ic_keyboard_voice_black_24dp.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxxhdpi/ic_lightbulb_outline_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/drawable-xxxhdpi/ic_lightbulb_outline_black_24dp.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxxhdpi/ic_local_taxi_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/drawable-xxxhdpi/ic_local_taxi_black_24dp.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxxhdpi/ic_my_location_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/drawable-xxxhdpi/ic_my_location_black_24dp.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxxhdpi/ic_restaurant_menu_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/drawable-xxxhdpi/ic_restaurant_menu_black_24dp.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable/circle_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
12 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
13 |
14 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/fragment_scrolling_search_example.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
16 |
17 |
22 |
23 |
28 |
29 |
30 |
31 |
36 |
37 |
43 |
44 |
45 |
46 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/fragment_sliding_search_example.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
16 |
17 |
21 |
22 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/fragment_sliding_search_results_example_fragment.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
26 |
27 |
42 |
43 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/search_results_list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
15 |
16 |
23 |
24 |
29 |
30 |
--------------------------------------------------------------------------------
/sample/src/main/res/menu/menu_app.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/sample/src/main/res/menu/menu_search_view.xml:
--------------------------------------------------------------------------------
1 |
25 |
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arimorty/floatingsearchview/a0f8fbc90d98eb1b629c6295dd2d3577412e7b1e/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 | 5dp
3 | 250dp
4 |
5 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | FloatingSearchView
3 | action voice rec
4 | action location
5 | action taxi
6 | change style
7 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula,
8 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum
9 |
10 |
11 | Hello blank fragment
12 | Sliding list
13 | Sliding search view
14 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus dictum lorem ac leo tincidunt varius. Donec lacinia elementum lobortis. Nulla pellentesque cursus sem. Aliquam vestibulum lacinia metus, ac faucibus nunc fringilla a. Nullam mauris lorem, pharetra vitae mollis in, gravida a mi. Sed eu elit vitae lorem vestibulum volutpat eget blandit tortor. Duis dignissim porta dolor, ut porttitor lectus pretium vitae. Phasellus quis augue ante. Nam tempus egestas consectetur. Praesent nec placerat nisi, non malesuada dolor. Duis malesuada semper lorem, nec feugiat nisl. Nulla facilisi. Sed aliquam ex ut turpis malesuada dignissim. Nam risus mi, dapibus maximus nisl ac, efficitur suscipit ex. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec malesuada nisl eget faucibus mollis. Nam sit amet mauris a metus euismod porttitor et sed mi. Nunc vel vehicula arcu, eu lacinia odio. Fusce id lacus vel dui blandit maximus id eget neque. Sed eu porta diam. Nunc vitae egestas diam. Donec semper hendrerit laoreet. Aliquam quis aliquam nulla. Aenean euismod lacus sed pretium scelerisque. Suspendisse mollis arcu at ligula pulvinar, nec elementum velit fermentum. Sed sed mollis ligula, vel eleifend metus. Sed magna metus, tempus ut bibendum at, aliquam at nisi. Integer nec fringilla mauris, vel viverra augue. Morbi eu mi mauris. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Proin molestie ante nec tristique finibus. In hac habitasse platea dictumst. Maecenas sed risus condimentum, feugiat velit ac, dictum erat. Curabitur pharetra ac nulla sed lacinia. Curabitur rutrum dolor vestibulum magna ultrices congue ac sed libero. Nam semper mi a neque ultricies commodo. In condimentum in odio in porttitor. Suspendisse maximus vestibulum nunc, vel gravida dui fermentum eu. Morbi sed orci augue. Praesent dolor justo, cursus sit amet ex et, posuere mattis lorem. Donec in efficitur orci. Nam semper odio a interdum aliquet. Vivamus vitae luctus purus, in fermentum diam. Pellentesque quis orci vitae est placerat faucibus. Maecenas non gravida ipsum, sit amet ultrices sem. Phasellus fringilla ultrices erat, vel aliquam sapien varius ac. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aliquam porta semper sapien. Pellentesque volutpat porta sapien, ut tristique metus. In hac habitasse platea dictumst. Aenean pharetra molestie dapibus. Nunc sed dolor elit. Quisque eget enim non tellus volutpat mollis a id dolor. Aenean sit amet sem sem. Nunc viverra efficitur lorem. Quisque quis metus dictum, mattis ante non, pellentesque sapien. Integer quis lectus feugiat, consectetur nulla quis, viverra nulla. Curabitur eu sodales nisl. Morbi non enim pellentesque, lobortis est id, dignissim mauris. Nulla et tempor lectus.
15 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus dictum lorem ac leo tincidunt varius. Donec lacinia elementum lobortis. Nulla pellentesque cursus sem. Aliquam vestibulum lacinia metus, ac faucibus nunc fringilla a. Nullam mauris lorem, pharetra vitae mollis in, gravida a mi. Sed eu elit vitae lorem vestibulum volutpat eget blandit tortor. Duis dignissim porta dolor, ut porttitor lectus pretium vitae. Phasellus quis augue ante. Nam tempus egestas consectetur. Praesent nec placerat nisi, non malesuada dolor. Duis malesuada semper lorem, nec feugiat nisl. Nulla facilisi. Sed aliquam ex ut turpis malesuada dignissim. Nam risus mi, dapibus maximus nisl ac, efficitur suscipit ex. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec malesuada nisl eget faucibus mollis. Nam sit amet mauris a metus euismod porttitor et sed mi. Nunc vel vehicula arcu, eu lacinia odio. Fusce id lacus vel dui blandit maximus id eget neque. Sed eu porta diam. Nunc vitae egestas diam. Donec semper hendrerit laoreet. Aliquam quis aliquam nulla. Aenean euismod lacus sed pretium scelerisque. Suspendisse mollis arcu at ligula pulvinar, nec elementum velit fermentum. Sed sed mollis ligula, vel eleifend metus. Sed magna metus, tempus ut bibendum at, aliquam at nisi. Integer nec fringilla mauris, vel viverra augue. Morbi eu mi mauris. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Proin molestie ante nec tristique finibus. In hac habitasse platea dictumst. Maecenas sed risus condimentum, feugiat velit ac, dictum erat. Curabitur pharetra ac nulla sed lacinia. Curabitur rutrum dolor vestibulum magna ultrices congue ac sed libero. Nam semper mi a neque ultricies commodo. In condimentum in odio in porttitor. Suspendisse maximus vestibulum nunc, vel gravida dui fermentum eu. Morbi sed orci augue. Praesent dolor justo, cursus sit amet ex et, posuere mattis lorem. Donec in efficitur orci. Nam semper odio a interdum aliquet. Vivamus vitae luctus purus, in fermentum diam. Pellentesque quis orci vitae est placerat faucibus. Maecenas non gravida ipsum, sit amet ultrices sem. Phasellus fringilla ultrices erat, vel aliquam sapien varius ac. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aliquam porta semper sapien. Pellentesque volutpat porta sapien, ut tristique metus. In hac habitasse platea dictumst. Aenean pharetra molestie dapibus. Nunc sed dolor elit. Quisque eget enim non tellus volutpat mollis a id dolor. Aenean sit amet sem sem. Nunc viverra efficitur lorem. Quisque quis metus dictum, mattis ante non, pellentesque sapien. Integer quis lectus feugiat, consectetur nulla quis, viverra nulla. Curabitur eu sodales nisl. Morbi non enim pellentesque, lobortis est id, dignissim mauris. Nulla et tempor lectus.
16 | scrolling behavior
17 |
18 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':sample', ':library', ':library-rxbinding', ':library-rxbinding-kotlin'
2 |
--------------------------------------------------------------------------------