├── .gitignore
├── LICENSE
├── README.md
├── bintray.gradle
├── build.gradle
├── demo.gif
├── install.gradle
├── sample
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── xyz
│ │ └── sahildave
│ │ └── widget
│ │ └── sample
│ │ ├── MainActivity.java
│ │ ├── SearchStaticListFragment.java
│ │ ├── SearchStaticListSupportFragment.java
│ │ ├── SearchStaticRecyclerFragment.java
│ │ └── SearchStaticScrollFragment.java
│ └── res
│ ├── drawable-hdpi
│ └── ic_launcher.png
│ ├── drawable-ldpi
│ └── ic_launcher.png
│ ├── drawable-mdpi
│ └── ic_launcher.png
│ ├── drawable-tvdpi
│ └── ic_launcher.png
│ ├── drawable-xhdpi
│ └── ic_launcher.png
│ ├── drawable-xxhdpi
│ └── ic_launcher.png
│ ├── drawable-xxxhdpi
│ └── ic_launcher.png
│ ├── layout
│ ├── activity_main.xml
│ ├── content_main.xml
│ ├── fragment_search_static_list.xml
│ ├── fragment_search_static_recycler.xml
│ ├── fragment_search_static_scroll.xml
│ └── search_static_list_item.xml
│ ├── values-v21
│ └── styles.xml
│ ├── values-w820dp
│ └── dimens.xml
│ └── values
│ ├── colors.xml
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
├── searchviewlayout
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── xyz
│ │ └── sahildave
│ │ └── widget
│ │ ├── SearchViewLayout.java
│ │ └── Utils.java
│ └── res
│ ├── anim
│ ├── fade_in_anim_set.xml
│ └── fade_out_anim_set.xml
│ ├── animator
│ ├── fade_in_object_animator.xml
│ └── fade_out_object_animator.xml
│ ├── drawable-hdpi
│ ├── ic_arrow_back.png
│ ├── ic_directions_subway.png
│ ├── ic_restaurant_menu.png
│ └── ic_search.png
│ ├── drawable-ldpi
│ ├── ic_arrow_back.png
│ ├── ic_directions_subway.png
│ ├── ic_restaurant_menu.png
│ └── ic_search.png
│ ├── drawable-mdpi
│ ├── ic_arrow_back.png
│ ├── ic_directions_subway.png
│ ├── ic_restaurant_menu.png
│ └── ic_search.png
│ ├── drawable-tvdpi
│ ├── ic_arrow_back.png
│ ├── ic_directions_subway.png
│ ├── ic_restaurant_menu.png
│ └── ic_search.png
│ ├── drawable-xhdpi
│ ├── ic_arrow_back.png
│ ├── ic_directions_subway.png
│ ├── ic_restaurant_menu.png
│ └── ic_search.png
│ ├── drawable-xxhdpi
│ ├── ic_arrow_back.png
│ ├── ic_directions_subway.png
│ ├── ic_restaurant_menu.png
│ └── ic_search.png
│ ├── drawable-xxxhdpi
│ ├── ic_arrow_back.png
│ ├── ic_directions_subway.png
│ ├── ic_restaurant_menu.png
│ └── ic_search.png
│ ├── drawable
│ └── rounded_corners.xml
│ ├── layout
│ ├── widget_search_bar.xml
│ └── widget_search_bar_expanded.xml
│ └── values
│ ├── colors.xml
│ ├── dimens.xml
│ └── integer.xml
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.ap_
4 |
5 | # Files for the Dalvik VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # Generated files
12 | bin/
13 | gen/
14 |
15 | # Gradle files
16 | gradlew
17 | gradlew.*
18 | gradle.*
19 | .gradle/
20 | gradle/
21 | build/
22 |
23 | # Local configuration file (sdk path, etc)
24 | local.properties
25 |
26 | # Proguard folder generated by Eclipse
27 | proguard/
28 |
29 | # Log Files
30 | *.log
31 | .gradle
32 | /local.properties
33 | /.idea/workspace.xml
34 | /.idea/libraries
35 | .DS_Store
36 | /build
37 | .idea
38 | *.iml
39 | credential.properties
40 | /captures
41 |
42 | */mirror/
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
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 | #### THIS PROJECT IS DEPRECATED
2 | Component is not maintained anymore.
3 | ---
4 |
5 |
6 | Implementation of **Lollipop+ Dialer** and **Google Maps**.
7 |
8 | ## DEMO
9 |
10 | 
11 |
12 |
13 | #### Add in View
14 | Add to your layout by using the include tag.
15 | ``` xml
16 |
17 | ```
18 | ---
19 | #### API
20 | This overlays the full activity and shows the **fragment** which you have assigned by using `setExpandedContentFragment`.
21 |
22 | ``` java
23 | searchViewLayout.setExpandedContentFragment(this, new SearchStaticFragment());
24 | ```
25 | ---
26 | If you want to **animate your Toolbar** too like the demo gif, you can enable it by using `handleToolbarAnimation`.
27 |
28 | ``` java
29 | searchViewLayout.handleToolbarAnimation(toolbar);
30 | ```
31 | ---
32 | Setting **Background colors for Transition**. Default should also work just fine:
33 |
34 | ``` java
35 | // Create Drawable for collapsed state. Default color is android.R.color.transparent
36 | ColorDrawable collapsed = new ColorDrawable(
37 | ContextCompat.getColor(this, R.color.colorPrimary));
38 |
39 | // Create Drawable for expanded state. Default color is #F0F0F0
40 | ColorDrawable expanded = new ColorDrawable(
41 | ContextCompat.getColor(this, R.color.default_color_expanded));
42 |
43 | // Send both colors to searchViewLayout
44 | searchViewLayout.setTransitionDrawables(collapsed, expanded);
45 | ```
46 | ---
47 | **Listen to search** complete by:
48 | ``` java
49 | searchViewLayout.setSearchListener(new SearchViewLayout.SearchListener() {
50 | @Override
51 | public void onFinished(String searchKeyword) {
52 | searchViewLayout.collapse();
53 | Snackbar.make(searchViewLayout, "Search Done - " + searchKeyword, Snackbar.LENGTH_LONG).show();
54 | }
55 | });
56 | ```
57 | ---
58 | **Listen to collapse/expand animation** by using `setOnToggleAnimationListener`. For eg the FAB in demo hides on expanded and shows on collapse.
59 | ``` java
60 | searchViewLayout.setOnToggleAnimationListener(new SearchViewLayout.OnToggleAnimationListener() {
61 | @Override
62 | public void onStart(boolean expanded) {
63 | if(expanded) {
64 | fab.hide();
65 | } else {
66 | fab.show();
67 | }
68 | }
69 |
70 | @Override
71 | public void onFinish(boolean expanded) { }
72 | });
73 | ```
74 | ---
75 | **Listen to search box** complete by:
76 | ``` java
77 | searchViewLayout.setSearchBoxListener(new SearchViewLayout.SearchBoxListener() {
78 | @Override
79 | public void beforeTextChanged(CharSequence s, int start, int count, int after) {
80 | }
81 | @Override
82 | public void onTextChanged(CharSequence s, int start, int before, int count) {
83 | }
84 | @Override
85 | public void afterTextChanged(Editable s) {
86 | }
87 | });
88 | ```
89 | ---
90 | **Setting Hints**
91 |
92 | If you want to set hints in the view, there are three APIs. `setCollapsedHint` would come up in the default/collapsed state. `setExpandedHint` would work for expanded state i.e. after click the view and the keyboard is up. `setHint` would set both the hints in one go, use this you want to show the same hint in both the states.
93 |
94 | ``` java
95 | searchViewLayout.setCollapsedHint("Collapsed Hint");
96 | searchViewLayout.setExpandedHint("Expanded Hint");
97 | searchViewLayout.setHint("Global Hint");
98 | ```
99 | **Setting Icons**
100 | Use `setCollapsedIcon`, `setExpandedBackIcon`, `setExpandedSearchIcon` to setup icons according to your choice. The argument should be a DrawableRes
101 | ### NOTES
102 |
103 | 1. If you want to add a scrolling widget in your `setExpandedContentFragment`, add a `onTouchListener` and disallow the parent intercept by using`v.getParent().requestDisallowInterceptTouchEvent(true);`Check out fragments in sample for the implement of ListView, RecyclerView and ScrollView.
104 |
105 | ``` java
106 | recyclerView.setOnTouchListener(new View.OnTouchListener() {
107 | // Setting on Touch Listener for handling the touch inside ScrollView
108 | @Override
109 | public boolean onTouch(View v, MotionEvent event) {
110 | // Disallow the touch request for parent scroll on touch of child view
111 | v.getParent().requestDisallowInterceptTouchEvent(true);
112 | return false;
113 | }
114 | });
115 |
116 | ```
117 |
118 | 2. The default height of the view is `120dp` which is also present in the dimens.xml file as
119 | ``` xml
120 | 120dp
121 | ```
122 | You can use it for adding margin on top of your main content layout.
123 |
124 |
125 | ### GET
126 |
127 | Available at jCenter and mavenCentral.
128 |
129 | ``` groovy
130 | dependencies {
131 | compile 'xyz.sahildave:searchviewlayout:0.6'
132 | }
133 | ```
134 |
135 | ### CHANGELOG
136 |
137 | ### 0.6
138 | * Added support for API 15
139 |
140 | ### 0.5
141 | * Added support for fragment-v4
142 |
143 | ### 0.4
144 | * Moved anim files to /animator res dir
145 |
146 | ### 0.3
147 | * Added search edit text API
148 | * Larger touch target
149 |
150 | ### 0.2
151 | * Added APIs for setting icons
152 | * Improved animations by using `onAnimationUpdate`
153 |
154 | ### 0.1
155 | * Added hints API.
156 | * Added `search_view_layout_approx_height`
157 |
158 | #### 0.0.2
159 | * Added API `setTransitionDrawables` which solves crashes in < API 19
160 |
161 | #### Contribute
162 |
163 | Contribute by creating issues (tagged enhancement, bugs) in the repo or create a pull request.
164 |
--------------------------------------------------------------------------------
/bintray.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.jfrog.bintray'
2 |
3 | version = libraryVersion
4 |
5 | task sourcesJar(type: Jar) {
6 | from android.sourceSets.main.java.srcDirs
7 | classifier = 'sources'
8 | }
9 |
10 | task javadoc(type: Javadoc) {
11 | source = android.sourceSets.main.java.srcDirs
12 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
13 | }
14 |
15 | task javadocJar(type: Jar, dependsOn: javadoc) {
16 | classifier = 'javadoc'
17 | from javadoc.destinationDir
18 | }
19 | artifacts {
20 | archives javadocJar
21 | archives sourcesJar
22 | }
23 |
24 | // Bintray
25 | Properties properties = new Properties()
26 | properties.load(project.rootProject.file('local.properties').newDataInputStream())
27 |
28 | bintray {
29 | user = properties.getProperty("bintray.user")
30 | key = properties.getProperty("bintray.apikey")
31 |
32 | configurations = ['archives']
33 | pkg {
34 | repo = bintrayRepo
35 | name = bintrayName
36 | desc = libraryDescription
37 | websiteUrl = siteUrl
38 | vcsUrl = gitUrl
39 | licenses = allLicenses
40 | publish = true
41 | publicDownloadNumbers = true
42 | version {
43 | desc = libraryDescription
44 | gpg {
45 | sign = true //Determines whether to GPG sign the files. The default is false
46 | passphrase = properties.getProperty("bintray.gpg.password")
47 | //Optional. The passphrase for GPG signing'
48 | }
49 | }
50 | }
51 | }
--------------------------------------------------------------------------------
/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.1.2'
9 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4'
10 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3'
11 | // NOTE: Do not place your application dependencies here; they belong
12 | // in the individual module build.gradle files
13 | }
14 | }
15 |
16 | allprojects {
17 | repositories {
18 | jcenter()
19 | }
20 | }
21 |
22 | task clean(type: Delete) {
23 | delete rootProject.buildDir
24 | }
25 |
--------------------------------------------------------------------------------
/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/demo.gif
--------------------------------------------------------------------------------
/install.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.github.dcendents.android-maven'
2 |
3 | // Maven Group ID for the artifact
4 | group = publishedGroupId
5 |
6 | install {
7 | repositories.mavenInstaller {
8 | // This generates POM.xml with proper parameters
9 | pom {
10 | project {
11 | packaging 'aar'
12 | groupId publishedGroupId
13 | artifactId artifact
14 |
15 | // Add your description here
16 | name libraryName
17 | description libraryDescription
18 | url siteUrl
19 |
20 | // Set your license
21 | licenses {
22 | license {
23 | name licenseName
24 | url licenseUrl
25 | }
26 | }
27 | developers {
28 | developer {
29 | id developerId
30 | name developerName
31 | email developerEmail
32 | }
33 | }
34 | scm {
35 | connection gitUrl
36 | developerConnection gitUrl
37 | url siteUrl
38 |
39 | }
40 | }
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/sample/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.ap_
4 |
5 | # Files for the Dalvik VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # Generated files
12 | bin/
13 | gen/
14 |
15 | # Gradle files
16 | gradlew
17 | gradlew.*
18 | gradle.*
19 | .gradle/
20 | gradle/
21 | build/
22 |
23 | # Local configuration file (sdk path, etc)
24 | local.properties
25 |
26 | # Proguard folder generated by Eclipse
27 | proguard/
28 |
29 | # Log Files
30 | *.log
31 | .gradle
32 | /local.properties
33 | /.idea/workspace.xml
34 | /.idea/libraries
35 | .DS_Store
36 | /build
37 | .idea
38 | *.iml
39 | credential.properties
40 | /captures
41 |
42 | */mirror/
--------------------------------------------------------------------------------
/sample/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "23.0.2"
6 |
7 | defaultConfig {
8 | applicationId "xyz.sahildave.searchviewfragment.sample"
9 | minSdkVersion 15
10 | targetSdkVersion 23
11 | versionCode 1
12 | versionName "1.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 'com.android.support:appcompat-v7:23.1.1'
25 | compile 'com.android.support:recyclerview-v7:23.1.1'
26 | compile 'com.android.support:design:23.1.1'
27 | compile project(':searchviewlayout')
28 | }
29 |
--------------------------------------------------------------------------------
/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 /home/sahil/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 |
--------------------------------------------------------------------------------
/sample/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
11 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/sample/src/main/java/xyz/sahildave/widget/sample/MainActivity.java:
--------------------------------------------------------------------------------
1 | package xyz.sahildave.widget.sample;
2 |
3 | import android.graphics.drawable.ColorDrawable;
4 | import android.os.Bundle;
5 | import android.support.design.widget.FloatingActionButton;
6 | import android.support.design.widget.Snackbar;
7 | import android.support.v4.content.ContextCompat;
8 | import android.support.v7.app.AppCompatActivity;
9 | import android.support.v7.widget.Toolbar;
10 | import android.text.Editable;
11 | import android.util.Log;
12 | import android.view.View;
13 |
14 | import xyz.sahildave.widget.SearchViewLayout;
15 |
16 | public class MainActivity extends AppCompatActivity {
17 |
18 | private static final String TAG = MainActivity.class.getSimpleName();
19 |
20 | @Override
21 | protected void onCreate(Bundle savedInstanceState) {
22 | super.onCreate(savedInstanceState);
23 | setContentView(R.layout.activity_main);
24 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
25 | setSupportActionBar(toolbar);
26 |
27 | final FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
28 | fab.setOnClickListener(new View.OnClickListener() {
29 | @Override
30 | public void onClick(View view) {
31 | Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
32 | .setAction("Action", null).show();
33 | }
34 | });
35 |
36 |
37 | final SearchViewLayout searchViewLayout = (SearchViewLayout) findViewById(R.id.search_view_container);
38 | searchViewLayout.setExpandedContentSupportFragment(this, new SearchStaticListSupportFragment());
39 | searchViewLayout.handleToolbarAnimation(toolbar);
40 | searchViewLayout.setCollapsedHint("Collapsed Hint");
41 | searchViewLayout.setExpandedHint("Expanded Hint");
42 | // searchViewLayout.setHint("Global Hint");
43 |
44 | ColorDrawable collapsed = new ColorDrawable(ContextCompat.getColor(this, R.color.colorPrimary));
45 | ColorDrawable expanded = new ColorDrawable(ContextCompat.getColor(this, R.color.default_color_expanded));
46 | searchViewLayout.setTransitionDrawables(collapsed, expanded);
47 | searchViewLayout.setSearchListener(new SearchViewLayout.SearchListener() {
48 | @Override
49 | public void onFinished(String searchKeyword) {
50 | searchViewLayout.collapse();
51 | Snackbar.make(searchViewLayout, "Start Search for - " + searchKeyword, Snackbar.LENGTH_LONG).show();
52 | }
53 | });
54 | searchViewLayout.setOnToggleAnimationListener(new SearchViewLayout.OnToggleAnimationListener() {
55 | @Override
56 | public void onStart(boolean expanding) {
57 | if (expanding) {
58 | fab.hide();
59 | } else {
60 | fab.show();
61 | }
62 | }
63 |
64 | @Override
65 | public void onFinish(boolean expanded) { }
66 | });
67 | searchViewLayout.setSearchBoxListener(new SearchViewLayout.SearchBoxListener() {
68 | @Override
69 | public void beforeTextChanged(CharSequence s, int start, int count, int after) {
70 | Log.d(TAG, "beforeTextChanged: " + s + "," + start + "," + count + "," + after);
71 | }
72 |
73 | @Override
74 | public void onTextChanged(CharSequence s, int start, int before, int count) {
75 | Log.d(TAG, "onTextChanged: " + s + "," + start + "," + before + "," + count);
76 | }
77 |
78 | @Override
79 | public void afterTextChanged(Editable s) {
80 | Log.d(TAG, "afterTextChanged: " + s);
81 | }
82 | });
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/sample/src/main/java/xyz/sahildave/widget/sample/SearchStaticListFragment.java:
--------------------------------------------------------------------------------
1 | package xyz.sahildave.widget.sample;
2 |
3 | import android.app.Fragment;
4 | import android.content.Context;
5 | import android.os.Bundle;
6 | import android.view.LayoutInflater;
7 | import android.view.MotionEvent;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.ArrayAdapter;
11 | import android.widget.ListView;
12 | import android.widget.TextView;
13 |
14 | import java.util.ArrayList;
15 | import java.util.List;
16 |
17 | public class SearchStaticListFragment extends Fragment {
18 |
19 | public SearchStaticListFragment() {
20 | // Required empty public constructor
21 | }
22 |
23 | @Override
24 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
25 | Bundle savedInstanceState) {
26 | // Inflate the layout for this fragment
27 | View rootView = inflater.inflate(R.layout.fragment_search_static_list, container, false);
28 | ListView listView = (ListView) rootView.findViewById(R.id.search_static_list);
29 | ArrayList strings = new ArrayList<>();
30 | for (int i = 0; i < 10; i++) {
31 | strings.add(i+" -- \n"+getString(R.string.lorem_1));
32 | }
33 | ListViewAdapter adapter = new ListViewAdapter(getActivity(), strings);
34 | listView.setAdapter(adapter);
35 | listView.setOnTouchListener(new View.OnTouchListener() {
36 | // Setting on Touch Listener for handling the touch inside ScrollView
37 | @Override
38 | public boolean onTouch(View v, MotionEvent event) {
39 | // Disallow the touch request for parent scroll on touch of child view
40 | v.getParent().requestDisallowInterceptTouchEvent(true);
41 | return false;
42 | }
43 | });
44 | return rootView;
45 | }
46 |
47 | public class ListViewAdapter extends ArrayAdapter {
48 |
49 | private final Context context;
50 | private final List values;
51 |
52 | public ListViewAdapter(Context context, List objects) {
53 | super(context, R.layout.search_static_list_item, objects);
54 | this.context = context;
55 | this.values = objects;
56 | }
57 |
58 | @Override
59 | public View getView(int position, View convertView, ViewGroup parent) {
60 | LayoutInflater inflater = (LayoutInflater) context
61 | .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
62 | View rowView = inflater.inflate(R.layout.search_static_list_item, parent, false);
63 | TextView textView = (TextView) rowView.findViewById(R.id.card_details);
64 | textView.setText(values.get(position));
65 | return rowView;
66 | }
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/sample/src/main/java/xyz/sahildave/widget/sample/SearchStaticListSupportFragment.java:
--------------------------------------------------------------------------------
1 | package xyz.sahildave.widget.sample;
2 |
3 | import android.content.Context;
4 | import android.os.Bundle;
5 | import android.support.v4.app.Fragment;
6 | import android.view.LayoutInflater;
7 | import android.view.MotionEvent;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.ArrayAdapter;
11 | import android.widget.ListView;
12 | import android.widget.TextView;
13 |
14 | import java.util.ArrayList;
15 | import java.util.List;
16 |
17 | public class SearchStaticListSupportFragment extends Fragment {
18 |
19 | public SearchStaticListSupportFragment() {
20 | // Required empty public constructor
21 | }
22 |
23 | @Override
24 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
25 | Bundle savedInstanceState) {
26 | // Inflate the layout for this fragment
27 | View rootView = inflater.inflate(R.layout.fragment_search_static_list, container, false);
28 | ListView listView = (ListView) rootView.findViewById(R.id.search_static_list);
29 | ArrayList strings = new ArrayList<>();
30 | for (int i = 0; i < 10; i++) {
31 | strings.add(i+" -- \n"+getString(R.string.lorem_1));
32 | }
33 | ListViewAdapter adapter = new ListViewAdapter(getActivity(), strings);
34 | listView.setAdapter(adapter);
35 | listView.setOnTouchListener(new View.OnTouchListener() {
36 | // Setting on Touch Listener for handling the touch inside ScrollView
37 | @Override
38 | public boolean onTouch(View v, MotionEvent event) {
39 | // Disallow the touch request for parent scroll on touch of child view
40 | v.getParent().requestDisallowInterceptTouchEvent(true);
41 | return false;
42 | }
43 | });
44 | return rootView;
45 | }
46 |
47 | public class ListViewAdapter extends ArrayAdapter {
48 |
49 | private final Context context;
50 | private final List values;
51 |
52 | public ListViewAdapter(Context context, List objects) {
53 | super(context, R.layout.search_static_list_item, objects);
54 | this.context = context;
55 | this.values = objects;
56 | }
57 |
58 | @Override
59 | public View getView(int position, View convertView, ViewGroup parent) {
60 | LayoutInflater inflater = (LayoutInflater) context
61 | .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
62 | View rowView = inflater.inflate(R.layout.search_static_list_item, parent, false);
63 | TextView textView = (TextView) rowView.findViewById(R.id.card_details);
64 | textView.setText(values.get(position));
65 | return rowView;
66 | }
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/sample/src/main/java/xyz/sahildave/widget/sample/SearchStaticRecyclerFragment.java:
--------------------------------------------------------------------------------
1 | package xyz.sahildave.widget.sample;
2 |
3 | import android.app.Fragment;
4 | import android.os.Bundle;
5 | import android.support.v7.widget.LinearLayoutManager;
6 | import android.support.v7.widget.RecyclerView;
7 | import android.view.LayoutInflater;
8 | import android.view.MotionEvent;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.widget.TextView;
12 |
13 | import java.util.ArrayList;
14 | import java.util.List;
15 |
16 | public class SearchStaticRecyclerFragment extends Fragment {
17 |
18 | public SearchStaticRecyclerFragment() {
19 | // Required empty public constructor
20 | }
21 |
22 | @Override
23 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
24 | Bundle savedInstanceState) {
25 | // Inflate the layout for this fragment
26 | View rootView = inflater.inflate(R.layout.fragment_search_static_recycler, container, false);
27 | RecyclerView recyclerView = ((RecyclerView) rootView.findViewById(R.id.search_static_recycler));
28 | recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
29 | ArrayList strings = new ArrayList<>();
30 | for (int i = 0; i < 10; i++) {
31 | strings.add(i+" -- \n"+getString(R.string.lorem_1));
32 | }
33 | ListViewAdapter adapter = new ListViewAdapter(strings);
34 | recyclerView.setAdapter(adapter);
35 | recyclerView.setOnTouchListener(new View.OnTouchListener() {
36 | // Setting on Touch Listener for handling the touch inside ScrollView
37 | @Override
38 | public boolean onTouch(View v, MotionEvent event) {
39 | // Disallow the touch request for parent scroll on touch of child view
40 | v.getParent().requestDisallowInterceptTouchEvent(true);
41 | return false;
42 | }
43 | });
44 | return rootView;
45 | }
46 |
47 | // Define a public click listener interface for items of the v7.RecyclerView which has no OnItemClickListener by default
48 | public interface ListOnItemClickListener {
49 | void onItemClick(View view, int position);
50 | void onItemLongClick(View view, int position);
51 | }
52 |
53 | public class ListViewAdapter extends RecyclerView.Adapter {
54 | public List mStringList;
55 | public ListViewAdapter(List stringList) {
56 | this.mStringList = stringList;
57 | }
58 |
59 | private ListOnItemClickListener mOnItemClickListener;
60 | public void setListOnItemClickListener(ListOnItemClickListener mOnItemClickListener) {
61 | this.mOnItemClickListener = mOnItemClickListener;
62 | }
63 |
64 | class ListViewHolder extends RecyclerView.ViewHolder {
65 | private final TextView mDetailText;
66 | public ListViewHolder(View itemView) {
67 | super(itemView);
68 | mDetailText = (TextView) itemView.findViewById(R.id.card_details);
69 | }
70 | }
71 |
72 | @Override
73 | public ListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
74 | return new ListViewHolder(LayoutInflater
75 | .from(parent.getContext())
76 | .inflate(R.layout.search_static_list_item, parent, false));
77 | }
78 |
79 | @Override
80 | public int getItemCount() {
81 | return mStringList.size();
82 | }
83 |
84 | @Override
85 | public void onBindViewHolder(final ListViewHolder viewHolder, int position) {
86 | viewHolder.mDetailText.setText(mStringList.get(position));
87 |
88 | // Click event called here
89 | if (mOnItemClickListener != null) {
90 | viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
91 | @Override
92 | public void onClick(View v) {
93 | int pos = viewHolder.getLayoutPosition();
94 | mOnItemClickListener.onItemClick(viewHolder.itemView, pos);
95 | }
96 | });
97 |
98 | viewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
99 | @Override
100 | public boolean onLongClick(View v) {
101 | int pos = viewHolder.getLayoutPosition();
102 | mOnItemClickListener.onItemLongClick(viewHolder.itemView, pos);
103 | return false;
104 | }
105 | });
106 | }
107 |
108 | }
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/sample/src/main/java/xyz/sahildave/widget/sample/SearchStaticScrollFragment.java:
--------------------------------------------------------------------------------
1 | package xyz.sahildave.widget.sample;
2 |
3 | import android.app.Fragment;
4 | import android.os.Bundle;
5 | import android.view.LayoutInflater;
6 | import android.view.MotionEvent;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 |
10 | public class SearchStaticScrollFragment extends Fragment {
11 |
12 | public SearchStaticScrollFragment() {
13 | // Required empty public constructor
14 | }
15 |
16 | @Override
17 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
18 | Bundle savedInstanceState) {
19 | // Inflate the layout for this fragment
20 | View rootView = inflater.inflate(R.layout.fragment_search_static_scroll, container, false);
21 | (rootView.findViewById(R.id.scrollView))
22 | .setOnTouchListener(new View.OnTouchListener() {
23 | public boolean onTouch(View v, MotionEvent event) {
24 | v.getParent().requestDisallowInterceptTouchEvent(true);
25 | return false;
26 | }
27 | });
28 |
29 | return rootView;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/sample/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-ldpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/sample/src/main/res/drawable-ldpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/sample/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-tvdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/sample/src/main/res/drawable-tvdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/sample/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/sample/src/main/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/sample/src/main/res/drawable-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
16 |
17 |
23 |
24 |
25 |
26 |
27 |
28 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/content_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
21 |
22 |
29 |
30 |
36 |
37 |
43 |
44 |
45 |
46 |
53 |
54 |
60 |
61 |
67 |
68 |
69 |
70 |
77 |
78 |
84 |
85 |
91 |
92 |
93 |
94 |
101 |
102 |
108 |
109 |
115 |
116 |
117 |
118 |
125 |
126 |
132 |
133 |
139 |
140 |
141 |
142 |
149 |
150 |
156 |
157 |
163 |
164 |
165 |
166 |
167 |
168 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/fragment_search_static_list.xml:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/fragment_search_static_recycler.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/fragment_search_static_scroll.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
14 |
15 |
23 |
24 |
28 |
29 |
35 |
36 |
43 |
44 |
45 |
46 |
47 |
48 |
56 |
57 |
61 |
62 |
68 |
69 |
76 |
77 |
78 |
79 |
80 |
88 |
89 |
93 |
94 |
100 |
101 |
108 |
109 |
110 |
111 |
112 |
120 |
121 |
125 |
126 |
132 |
133 |
140 |
141 |
142 |
143 |
144 |
152 |
153 |
157 |
158 |
164 |
165 |
172 |
173 |
174 |
175 |
176 |
184 |
185 |
189 |
190 |
196 |
197 |
204 |
205 |
206 |
207 |
208 |
216 |
217 |
221 |
222 |
228 |
229 |
236 |
237 |
238 |
239 |
240 |
248 |
249 |
253 |
254 |
260 |
261 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/search_static_list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
15 |
16 |
23 |
24 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/sample/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 | >
2 |
8 |
9 |
--------------------------------------------------------------------------------
/sample/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 | 16dp
6 |
7 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Search View Sample
3 |
4 |
5 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vehicula sem a malesuada rhoncus.
6 | Pellentesque ut dolor a dui porttitor porta lacinia non libero.
7 |
8 |
9 | Phasellus congue tincidunt lectus, at dignissim ligula maximus eu.
10 | Quisque interdum nunc eget tellus bibendum suscipit. Phasellus feugiat ultricies posuere.
11 |
12 |
13 | Sed pellentesque placerat quam, ut ultricies turpis feugiat a.
14 | Aliquam a volutpat risus.
15 |
16 |
17 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/searchviewlayout/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.ap_
4 |
5 | # Files for the Dalvik VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # Generated files
12 | bin/
13 | gen/
14 |
15 | # Gradle files
16 | gradlew
17 | gradlew.*
18 | gradle.*
19 | .gradle/
20 | gradle/
21 | build/
22 |
23 | # Local configuration file (sdk path, etc)
24 | local.properties
25 |
26 | # Proguard folder generated by Eclipse
27 | proguard/
28 |
29 | # Log Files
30 | *.log
31 | .gradle
32 | /local.properties
33 | /.idea/workspace.xml
34 | /.idea/libraries
35 | .DS_Store
36 | /build
37 | .idea
38 | *.iml
39 | credential.properties
40 | /captures
41 |
42 | */mirror/
--------------------------------------------------------------------------------
/searchviewlayout/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | def mLibraryVersion = 0.6
4 | ext {
5 | bintrayRepo = 'maven'
6 | bintrayName = 'Search-View-Layout'
7 |
8 | publishedGroupId = 'xyz.sahildave'
9 | libraryName = 'Search-View-Layout'
10 | artifact = 'searchviewlayout'
11 |
12 | libraryDescription = 'Search View Layout like Lollipop Dialer'
13 |
14 | siteUrl = 'https://github.com/sahildave/Search-View-Layout'
15 | gitUrl = 'https://github.com/sahildave/Search-View-Layout.git'
16 |
17 | libraryVersion = "${mLibraryVersion}"
18 |
19 | developerId = 'sahildave'
20 | developerName = 'Sahil Dave'
21 | developerEmail = 'sahildave1991@gmail.com'
22 |
23 | licenseName = 'Apache License, Version 2.0'
24 | licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0'
25 | allLicenses = ["ALv2"]
26 | }
27 |
28 | android {
29 | compileSdkVersion 23
30 | buildToolsVersion "23.0.2"
31 |
32 | defaultConfig {
33 | minSdkVersion 15
34 | targetSdkVersion 23
35 | versionCode 1
36 | versionName "${mLibraryVersion}"
37 | }
38 | }
39 |
40 | dependencies {
41 | compile fileTree(dir: 'libs', include: ['*.jar'])
42 | compile 'com.android.support:support-v4:23.1.1'
43 | compile 'com.android.support:appcompat-v7:23.1.1'
44 | compile 'com.android.support:cardview-v7:23.1.1'
45 | }
46 |
47 | apply from: '../install.gradle'
48 | apply from: '../bintray.gradle'
--------------------------------------------------------------------------------
/searchviewlayout/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 /home/sahil/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 |
--------------------------------------------------------------------------------
/searchviewlayout/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/searchviewlayout/src/main/java/xyz/sahildave/widget/SearchViewLayout.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Sahil Dave
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License
15 | */
16 |
17 | package xyz.sahildave.widget;
18 |
19 | import android.animation.Animator;
20 | import android.animation.AnimatorListenerAdapter;
21 | import android.animation.ValueAnimator;
22 | import android.app.Activity;
23 | import android.content.Context;
24 | import android.graphics.drawable.ColorDrawable;
25 | import android.graphics.drawable.Drawable;
26 | import android.graphics.drawable.TransitionDrawable;
27 | import android.support.annotation.DrawableRes;
28 | import android.support.v4.app.FragmentActivity;
29 | import android.support.v4.content.ContextCompat;
30 | import android.support.v7.widget.Toolbar;
31 | import android.text.Editable;
32 | import android.text.TextWatcher;
33 | import android.util.AttributeSet;
34 | import android.util.Log;
35 | import android.view.KeyEvent;
36 | import android.view.View;
37 | import android.view.ViewGroup;
38 | import android.view.inputmethod.EditorInfo;
39 | import android.widget.EditText;
40 | import android.widget.FrameLayout;
41 | import android.widget.ImageView;
42 | import android.widget.TextView;
43 |
44 | public class SearchViewLayout extends FrameLayout {
45 | public static int ANIMATION_DURATION = 1500;
46 | private static final String LOG_TAG = SearchViewLayout.class.getSimpleName();
47 |
48 | private boolean mIsExpanded = false;
49 |
50 | private ViewGroup mCollapsed;
51 | private ViewGroup mExpanded;
52 | private EditText mSearchEditText;
53 | private View mSearchIcon;
54 | private View mCollapsedSearchBox;
55 | private View mBackButtonView;
56 | private View mExpandedSearchIcon;
57 |
58 | private int toolbarExpandedHeight = 0;
59 |
60 | private ValueAnimator mAnimator;
61 | private OnToggleAnimationListener mOnToggleAnimationListener;
62 | private SearchListener mSearchListener;
63 | private SearchBoxListener mSearchBoxListener;
64 | private android.app.Fragment mExpandedContentFragment;
65 | private android.support.v4.app.Fragment mExpandedContentSupportFragment;
66 | private android.app.FragmentManager mFragmentManager;
67 | private android.support.v4.app.FragmentManager mSupportFragmentManager;
68 | private TransitionDrawable mBackgroundTransition;
69 | private Toolbar mToolbar;
70 |
71 | private Drawable mCollapsedDrawable;
72 | private Drawable mExpandedDrawable;
73 |
74 | private int mExpandedHeight;
75 | private int mCollapsedHeight;
76 | private TextView mCollapsedHintView;
77 |
78 | /***
79 | * Interface for listening to animation start and finish.
80 | * expanding and expanded tell the current state of animation.
81 | */
82 | public interface OnToggleAnimationListener {
83 | void onStart(boolean expanding);
84 |
85 | void onFinish(boolean expanded);
86 | }
87 |
88 | /***
89 | * Interface for listening to search finish call.
90 | * Called on clicking of search button on keyboard and {@link #mExpandedSearchIcon}
91 | */
92 |
93 | public interface SearchListener {
94 | void onFinished(String searchKeyword);
95 | }
96 |
97 | /***
98 | * Interface for listening to search edit text.
99 | */
100 |
101 | public interface SearchBoxListener {
102 | void beforeTextChanged(CharSequence s, int start, int count, int after);
103 | void onTextChanged(CharSequence s, int start, int before, int count);
104 | void afterTextChanged(Editable s);
105 | }
106 |
107 |
108 | public void setOnToggleAnimationListener(OnToggleAnimationListener listener) {
109 | mOnToggleAnimationListener = listener;
110 | }
111 |
112 | public void setSearchListener(SearchListener listener) {
113 | mSearchListener = listener;
114 | }
115 |
116 | public void setSearchBoxListener(SearchBoxListener listener) {
117 | mSearchBoxListener = listener;
118 | }
119 |
120 | public SearchViewLayout(Context context, AttributeSet attrs) {
121 | super(context, attrs);
122 | ANIMATION_DURATION = context.getResources().getInteger(R.integer.animation_duration);
123 | }
124 |
125 | @Override
126 | protected void onFinishInflate() {
127 | mCollapsed = (ViewGroup) findViewById(R.id.search_box_collapsed);
128 | mSearchIcon = findViewById(R.id.search_magnifying_glass);
129 | mCollapsedSearchBox = findViewById(R.id.search_box_start_search);
130 | mCollapsedHintView = (TextView) findViewById(R.id.search_box_collapsed_hint);
131 |
132 | mExpanded = (ViewGroup) findViewById(R.id.search_expanded_root);
133 | mSearchEditText = (EditText) mExpanded.findViewById(R.id.search_expanded_edit_text);
134 | mBackButtonView = mExpanded.findViewById(R.id.search_expanded_back_button);
135 | mExpandedSearchIcon = findViewById(R.id.search_expanded_magnifying_glass);
136 |
137 | // Convert a long click into a click to expand the search box, and then long click on the
138 | // search view. This accelerates the long-press scenario for copy/paste.
139 | mCollapsedSearchBox.setOnLongClickListener(new OnLongClickListener() {
140 | @Override
141 | public boolean onLongClick(View view) {
142 | mCollapsedSearchBox.performClick();
143 | mSearchEditText.performLongClick();
144 | return false;
145 | }
146 | });
147 |
148 | mCollapsed.setOnClickListener(mSearchViewOnClickListener);
149 | mSearchIcon.setOnClickListener(mSearchViewOnClickListener);
150 | mCollapsedSearchBox.setOnClickListener(mSearchViewOnClickListener);
151 |
152 | mSearchEditText.setOnFocusChangeListener(new OnFocusChangeListener() {
153 | @Override
154 | public void onFocusChange(View v, boolean hasFocus) {
155 | if (hasFocus) {
156 | Utils.showInputMethod(v);
157 | } else {
158 | Utils.hideInputMethod(v);
159 | }
160 | }
161 | });
162 | mSearchEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
163 | @Override
164 | public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
165 | if (actionId == EditorInfo.IME_ACTION_SEARCH) {
166 | callSearchListener();
167 | Utils.hideInputMethod(v);
168 | return true;
169 | }
170 | return false;
171 | }
172 | });
173 | mSearchEditText.addTextChangedListener(new TextWatcher() {
174 | @Override
175 | public void onTextChanged(CharSequence s, int start, int before, int count) {
176 | if (mSearchEditText.getText().length() > 0) {
177 | if (mExpandedSearchIcon.getVisibility() != View.VISIBLE) {
178 | Utils.fadeIn(mExpandedSearchIcon, ANIMATION_DURATION);
179 | }
180 | } else {
181 | Utils.fadeOut(mExpandedSearchIcon, ANIMATION_DURATION);
182 | }
183 | if(mSearchBoxListener!=null) mSearchBoxListener.onTextChanged(s, start, before, count);
184 | }
185 |
186 | @Override
187 | public void beforeTextChanged(CharSequence s, int start, int count, int after) {
188 | if(mSearchBoxListener!=null) mSearchBoxListener.beforeTextChanged(s, start, count, after);
189 | }
190 |
191 | @Override
192 | public void afterTextChanged(Editable s) {
193 | if(mSearchBoxListener!=null) mSearchBoxListener.afterTextChanged(s);
194 | }
195 | });
196 |
197 | mBackButtonView.setOnClickListener(new OnClickListener() {
198 | @Override
199 | public void onClick(View v) {
200 | collapse();
201 | }
202 | });
203 |
204 | mExpandedSearchIcon.setOnClickListener(new OnClickListener() {
205 | @Override
206 | public void onClick(View v) {
207 | callSearchListener();
208 | Utils.hideInputMethod(v);
209 | }
210 | });
211 |
212 | mCollapsedDrawable = new ColorDrawable(ContextCompat.getColor(getContext(), android.R.color.transparent));
213 | mExpandedDrawable = new ColorDrawable(ContextCompat.getColor(getContext(), R.color.default_color_expanded));
214 | mBackgroundTransition = new TransitionDrawable(new Drawable[]{mCollapsedDrawable, mExpandedDrawable});
215 | mBackgroundTransition.setCrossFadeEnabled(true);
216 | setBackgroundCompat();
217 | Utils.setPaddingAll(SearchViewLayout.this, 8);
218 |
219 | super.onFinishInflate();
220 | }
221 |
222 | /***
223 | * Should toolbar be animated, y position.
224 | * @param toolbar current toolbar which needs to be animated.
225 | */
226 |
227 | public void handleToolbarAnimation(Toolbar toolbar) {
228 | this.mToolbar = toolbar;
229 | }
230 |
231 | /***
232 | * Set the fragment which would be shown in the expanded state
233 | * @param activity to get fragment manager
234 | * @param contentFragment fragment which needs to be shown.
235 | * @throws RuntimeException if support version of content fragment already set
236 | */
237 |
238 | public void setExpandedContentFragment(Activity activity, android.app.Fragment contentFragment) {
239 | mExpandedContentFragment = contentFragment;
240 | mFragmentManager = activity.getFragmentManager();
241 | mExpandedHeight = Utils.getSizeOfScreen(activity).y;
242 | }
243 |
244 | /***
245 | * Set the support version fragment which would be shown in the expanded state
246 | * @param activity to get support version of fragment manager, activity must be a FragmentActivity
247 | * @param contentSupportFragment support version of fragment which needs to be shown.
248 | * @throws RuntimeException if content fragment already set
249 | */
250 |
251 | public void setExpandedContentSupportFragment(FragmentActivity activity, android.support.v4.app.Fragment contentSupportFragment) {
252 | mExpandedContentSupportFragment = contentSupportFragment;
253 | mSupportFragmentManager = activity.getSupportFragmentManager();
254 | mExpandedHeight = Utils.getSizeOfScreen(activity).y;
255 | }
256 |
257 | /***
258 | * Set the background colours of the searchview.
259 | * @param collapsedDrawable drawable for collapsed state, default transparent
260 | * @param expandedDrawable drawable for expanded state, default color.default_color_expanded
261 | */
262 | public void setTransitionDrawables(Drawable collapsedDrawable, Drawable expandedDrawable) {
263 | this.mCollapsedDrawable = collapsedDrawable;
264 | this.mExpandedDrawable = expandedDrawable;
265 |
266 | mBackgroundTransition = new TransitionDrawable(new Drawable[]{mCollapsedDrawable, mExpandedDrawable});
267 | mBackgroundTransition.setCrossFadeEnabled(true);
268 | setBackgroundCompat();
269 | Utils.setPaddingAll(SearchViewLayout.this, 8);
270 | }
271 |
272 | @SuppressWarnings("deprecation")
273 | private void setBackgroundCompat() {
274 | if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
275 | setBackground(mBackgroundTransition);
276 | } else {
277 | setBackgroundDrawable(mBackgroundTransition);
278 | }
279 | }
280 |
281 | /***
282 | * Set hint in the collapsed state
283 | *
284 | * Also see {@link #setHint(String)}
285 | * @param searchViewHint
286 | */
287 | public void setCollapsedHint(String searchViewHint) {
288 | if (searchViewHint != null) {
289 | mCollapsedHintView.setHint(searchViewHint);
290 | }
291 | }
292 |
293 | /***
294 | * Set hint in the expanded state
295 | *
296 | * Also see {@link #setHint(String)}
297 | * @param searchViewHint
298 | */
299 | public void setExpandedHint(String searchViewHint) {
300 | if (searchViewHint != null) {
301 | mSearchEditText.setHint(searchViewHint);
302 | }
303 | }
304 |
305 | /***
306 | * Overrides both, {@link #setCollapsedHint(String)} and {@link #setExpandedHint(String)},
307 | * and sets hint for both the views.
308 | *
309 | * Use this if you don't want to show different hints in both the states
310 | * @param searchViewHint
311 | */
312 | public void setHint(String searchViewHint) {
313 | if (searchViewHint != null) {
314 | mCollapsedHintView.setHint(searchViewHint);
315 | mSearchEditText.setHint(searchViewHint);
316 | }
317 | }
318 |
319 | /***
320 | * Set a text for the expanded editText
321 | *
322 | * Maybe what you input is not a full keyword, and you can use this to stuff the editText
323 | * usually by clicking the items of list showing inexact results.
324 | * @param searchViewText
325 | */
326 | public void setExpandedText(String searchViewText) {
327 | if (searchViewText != null) {
328 | mSearchEditText.setText(searchViewText);
329 | }
330 | }
331 |
332 | public void expand(boolean requestFocus) {
333 | mCollapsedHeight = getHeight();
334 | toggleToolbar(true);
335 | if (mBackgroundTransition != null)
336 | mBackgroundTransition.startTransition(ANIMATION_DURATION);
337 | mIsExpanded = true;
338 |
339 | animateStates(true, 1f, 0f);
340 | Utils.crossFadeViews(mExpanded, mCollapsed, ANIMATION_DURATION);
341 |
342 | if (requestFocus) {
343 | mSearchEditText.requestFocus();
344 | }
345 | }
346 |
347 | public void collapse() {
348 | toggleToolbar(false);
349 | if (mBackgroundTransition != null)
350 | mBackgroundTransition.reverseTransition(ANIMATION_DURATION);
351 | mSearchEditText.setText(null);
352 | mIsExpanded = false;
353 |
354 | animateStates(false, 0f, 1f);
355 | Utils.crossFadeViews(mCollapsed, mExpanded, ANIMATION_DURATION);
356 |
357 | hideContentFragment();
358 | }
359 |
360 | public boolean isExpanded() {
361 | return mIsExpanded;
362 | }
363 |
364 | /**
365 | * Allow user to set a search icon in the collapsed view
366 | *
367 | * @param iconResource resource id of icon
368 | */
369 | public void setCollapsedIcon(@DrawableRes int iconResource) {
370 | ((ImageView)mSearchIcon).setImageResource(iconResource);
371 |
372 | }
373 |
374 | /**
375 | * Allow user to set a back icon in the expanded view
376 | *
377 | * @param iconResource resource id of icon
378 | */
379 | public void setExpandedBackIcon(@DrawableRes int iconResource) {
380 | ((ImageView)mBackButtonView).setImageResource(iconResource);
381 | }
382 |
383 | /**
384 | * Allow user to set a search icon in the expanded view
385 | *
386 | * @param iconResource resource id of icon
387 | */
388 | public void setExpandedSearchIcon(@DrawableRes int iconResource) {
389 | ((ImageView)mExpandedSearchIcon).setImageResource(iconResource);
390 | }
391 |
392 | private void showContentFragment() {
393 | if (mFragmentManager != null) {
394 | final android.app.FragmentTransaction transaction = mFragmentManager.beginTransaction();
395 | transaction.setCustomAnimations(R.animator.fade_in_object_animator, R.animator.fade_out_object_animator);
396 | transaction.replace(R.id.search_expanded_content, mExpandedContentFragment);
397 | transaction.commit();
398 | } else if (mSupportFragmentManager != null) {
399 | final android.support.v4.app.FragmentTransaction transaction = mSupportFragmentManager.beginTransaction();
400 | transaction.setCustomAnimations(R.anim.fade_in_anim_set, R.anim.fade_out_anim_set);
401 | transaction.replace(R.id.search_expanded_content, mExpandedContentSupportFragment);
402 | transaction.commit();
403 | }
404 | }
405 |
406 | private void hideContentFragment() {
407 | if (mFragmentManager != null) {
408 | final android.app.FragmentTransaction transaction = mFragmentManager.beginTransaction();
409 | transaction.remove(mExpandedContentFragment).commit();
410 | } else if (mSupportFragmentManager != null) {
411 | final android.support.v4.app.FragmentTransaction transaction = mSupportFragmentManager.beginTransaction();
412 | transaction.remove(mExpandedContentSupportFragment).commit();
413 | } else {
414 | Log.e(LOG_TAG, "Fragment Manager is null. Returning");
415 | }
416 | }
417 |
418 | private void toggleToolbar(boolean expanding) {
419 | if (mToolbar == null) return;
420 |
421 | mToolbar.clearAnimation();
422 | if (expanding) {
423 | toolbarExpandedHeight = mToolbar.getHeight();
424 | }
425 |
426 | int toYValue = expanding ? toolbarExpandedHeight * (-1) : 0;
427 |
428 | mToolbar.animate()
429 | .y(toYValue)
430 | .setDuration(ANIMATION_DURATION)
431 | .start();
432 |
433 | Utils.animateHeight(
434 | mToolbar,
435 | expanding ? toolbarExpandedHeight : 0,
436 | expanding ? 0 : toolbarExpandedHeight,
437 | ANIMATION_DURATION);
438 | }
439 |
440 | private void animateStates(final boolean expand, final float start, final float end) {
441 | mAnimator = ValueAnimator.ofFloat(start, end);
442 | mAnimator.cancel();
443 |
444 | mAnimator.addListener(new AnimatorListenerAdapter() {
445 | @Override
446 | public void onAnimationEnd(Animator animation) {
447 | if (expand) {
448 | Utils.setPaddingAll(SearchViewLayout.this, 0);
449 | showContentFragment();
450 |
451 | ViewGroup.LayoutParams params = getLayoutParams();
452 | params.height = mExpandedHeight;
453 | setLayoutParams(params);
454 | } else {
455 | Utils.setPaddingAll(SearchViewLayout.this, 8);
456 | }
457 | if (mOnToggleAnimationListener != null)
458 | mOnToggleAnimationListener.onFinish(expand);
459 | }
460 |
461 | @Override
462 | public void onAnimationStart(Animator animation) {
463 | super.onAnimationStart(animation);
464 | if (!expand) {
465 | ViewGroup.LayoutParams params = getLayoutParams();
466 | params.height = mCollapsedHeight;
467 | setLayoutParams(params);
468 | }
469 | if (mOnToggleAnimationListener != null)
470 | mOnToggleAnimationListener.onStart(expand);
471 | }
472 | });
473 |
474 | mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
475 | @Override
476 | public void onAnimationUpdate(ValueAnimator animation) {
477 | int padding = (int) (8 * animation.getAnimatedFraction());
478 | if (expand) padding = 8 - padding;
479 | Utils.setPaddingAll(SearchViewLayout.this, padding);
480 | }
481 | });
482 |
483 | mAnimator.setDuration(ANIMATION_DURATION);
484 | mAnimator.start();
485 | }
486 |
487 | private void callSearchListener() {
488 | Editable editable = mSearchEditText.getText();
489 | if (editable != null && editable.length() > 0) {
490 | if (mSearchListener != null) {
491 | mSearchListener.onFinished(editable.toString());
492 | }
493 | }
494 | }
495 |
496 | @Override
497 | public boolean dispatchKeyEventPreIme(KeyEvent event) {
498 | if (mSearchEditTextLayoutListener != null) {
499 | if (mSearchEditTextLayoutListener.onKey(this, event.getKeyCode(), event)) {
500 | return true;
501 | }
502 | }
503 | return super.dispatchKeyEventPreIme(event);
504 | }
505 |
506 | /**
507 | * Open the search UI when the user clicks on the search box.
508 | */
509 | private final View.OnClickListener mSearchViewOnClickListener = new View.OnClickListener() {
510 | @Override
511 | public void onClick(View v) {
512 | if (!mIsExpanded) {
513 | expand(true);
514 | }
515 | }
516 | };
517 |
518 | /**
519 | * If the search term is empty and the user closes the soft keyboard, close the search UI.
520 | */
521 | private final View.OnKeyListener mSearchEditTextLayoutListener = new View.OnKeyListener() {
522 | @Override
523 | public boolean onKey(View v, int keyCode, KeyEvent event) {
524 | if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN &&
525 | isExpanded()) {
526 | boolean keyboardHidden = Utils.hideInputMethod(v);
527 | if (keyboardHidden) return true;
528 | collapse();
529 | return true;
530 | }
531 | return false;
532 | }
533 | };
534 |
535 | }
536 |
--------------------------------------------------------------------------------
/searchviewlayout/src/main/java/xyz/sahildave/widget/Utils.java:
--------------------------------------------------------------------------------
1 | package xyz.sahildave.widget;
2 |
3 | import android.animation.ValueAnimator;
4 | import android.app.Activity;
5 | import android.content.Context;
6 | import android.graphics.Point;
7 | import android.support.v4.view.ViewCompat;
8 | import android.support.v4.view.ViewPropertyAnimatorCompat;
9 | import android.support.v4.view.ViewPropertyAnimatorListener;
10 | import android.view.Display;
11 | import android.view.View;
12 | import android.view.ViewGroup;
13 | import android.view.inputmethod.InputMethodManager;
14 |
15 | /**
16 | * Created by sahil on 27/10/15.
17 | */
18 | public class Utils {
19 | public static int dpToPx(Context context, float dp) {
20 | float density = context.getResources().getDisplayMetrics().density;
21 | return Math.round(dp * density);
22 | }
23 |
24 | public static void setPaddingAll(View v, int paddingInDp) {
25 | v.setPadding(
26 | dpToPx(v.getContext(), paddingInDp),
27 | dpToPx(v.getContext(), paddingInDp),
28 | dpToPx(v.getContext(), paddingInDp),
29 | dpToPx(v.getContext(), paddingInDp));
30 |
31 | }
32 |
33 | public static Point getSizeOfScreen(Activity activity) {
34 | Display display = activity.getWindowManager().getDefaultDisplay();
35 | Point size = new Point();
36 | display.getSize(size);
37 | return size;
38 | }
39 |
40 |
41 | public static boolean showInputMethod(View view) {
42 | final InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService(
43 | Context.INPUT_METHOD_SERVICE);
44 | if (imm != null) {
45 | return imm.showSoftInput(view, 0);
46 | }
47 | return false;
48 | }
49 |
50 | public static boolean hideInputMethod(View view) {
51 | final InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService(
52 | Context.INPUT_METHOD_SERVICE);
53 | if (imm != null) {
54 | return imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
55 | }
56 | return false;
57 | }
58 |
59 | // AnimUtils
60 |
61 | public static final int DEFAULT_DURATION = -1;
62 | public static final int NO_DELAY = 0;
63 |
64 | public static class AnimationCallback {
65 |
66 | public void onAnimationEnd() {}
67 | public void onAnimationCancel() {}
68 | }
69 | public static void crossFadeViews(View fadeIn, View fadeOut, int duration) {
70 | fadeIn(fadeIn, duration);
71 | fadeOut(fadeOut, duration);
72 | }
73 | public static void fadeOut(View fadeOut, int duration) {
74 | fadeOut(fadeOut, duration, null);
75 | }
76 | public static void fadeOut(final View fadeOut, int durationMs,
77 | final AnimationCallback callback) {
78 | fadeOut.setAlpha(1);
79 | final ViewPropertyAnimatorCompat animator = ViewCompat.animate(fadeOut);
80 | animator.cancel();
81 | animator.alpha(0).withLayer().setListener(new ViewPropertyAnimatorListener() {
82 | @Override
83 | public void onAnimationStart(View view) {
84 |
85 | }
86 |
87 | @Override
88 | public void onAnimationEnd(View view) {
89 | fadeOut.setVisibility(View.GONE);
90 | if (callback != null) {
91 | callback.onAnimationEnd();
92 | }
93 | }
94 |
95 | @Override
96 | public void onAnimationCancel(View view) {
97 | fadeOut.setVisibility(View.GONE);
98 | fadeOut.setAlpha(0);
99 | if (callback != null) {
100 | callback.onAnimationCancel();
101 | }
102 | }
103 | });
104 | if (durationMs != DEFAULT_DURATION) {
105 | animator.setDuration(durationMs);
106 | }
107 | animator.start();
108 | }
109 | public static void fadeIn(View fadeIn, int durationMs) {
110 | fadeIn(fadeIn, durationMs, NO_DELAY, null);
111 | }
112 | public static void fadeIn(final View fadeIn, int durationMs, int delay,
113 | final AnimationCallback callback) {
114 | fadeIn.setAlpha(0);
115 | final ViewPropertyAnimatorCompat animator = ViewCompat.animate(fadeIn);
116 | animator.cancel();
117 | animator.setStartDelay(delay);
118 | animator.alpha(1).withLayer().setListener(new ViewPropertyAnimatorListener() {
119 | @Override
120 | public void onAnimationStart(View view) {
121 | fadeIn.setVisibility(View.VISIBLE);
122 | }
123 |
124 | @Override
125 | public void onAnimationCancel(View view) {
126 | fadeIn.setAlpha(1);
127 | if (callback != null) {
128 | callback.onAnimationCancel();
129 | }
130 | }
131 |
132 | @Override
133 | public void onAnimationEnd(View view) {
134 | if (callback != null) {
135 | callback.onAnimationEnd();
136 | }
137 | }
138 | });
139 | if (durationMs != DEFAULT_DURATION) {
140 | animator.setDuration(durationMs);
141 | }
142 | animator.start();
143 | }
144 |
145 | public static void animateHeight(final View view, int from, int to, int duration) {
146 | boolean expanding = to > from;
147 |
148 | ValueAnimator anim = ValueAnimator.ofInt(from, to);
149 | anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
150 | @Override
151 | public void onAnimationUpdate(ValueAnimator valueAnimator) {
152 | int val = (Integer) valueAnimator.getAnimatedValue();
153 | ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
154 | layoutParams.height = val;
155 | view.setLayoutParams(layoutParams);
156 | }
157 | });
158 | anim.setDuration(duration);
159 | anim.start();
160 |
161 | view.animate().alpha(expanding ? 1 : 0).setDuration(duration / 2).start();
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/anim/fade_in_anim_set.xml:
--------------------------------------------------------------------------------
1 |
3 |
7 |
8 |
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/anim/fade_out_anim_set.xml:
--------------------------------------------------------------------------------
1 |
3 |
7 |
8 |
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/animator/fade_in_object_animator.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/animator/fade_out_object_animator.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/drawable-hdpi/ic_arrow_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/searchviewlayout/src/main/res/drawable-hdpi/ic_arrow_back.png
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/drawable-hdpi/ic_directions_subway.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/searchviewlayout/src/main/res/drawable-hdpi/ic_directions_subway.png
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/drawable-hdpi/ic_restaurant_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/searchviewlayout/src/main/res/drawable-hdpi/ic_restaurant_menu.png
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/drawable-hdpi/ic_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/searchviewlayout/src/main/res/drawable-hdpi/ic_search.png
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/drawable-ldpi/ic_arrow_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/searchviewlayout/src/main/res/drawable-ldpi/ic_arrow_back.png
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/drawable-ldpi/ic_directions_subway.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/searchviewlayout/src/main/res/drawable-ldpi/ic_directions_subway.png
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/drawable-ldpi/ic_restaurant_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/searchviewlayout/src/main/res/drawable-ldpi/ic_restaurant_menu.png
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/drawable-ldpi/ic_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/searchviewlayout/src/main/res/drawable-ldpi/ic_search.png
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/drawable-mdpi/ic_arrow_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/searchviewlayout/src/main/res/drawable-mdpi/ic_arrow_back.png
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/drawable-mdpi/ic_directions_subway.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/searchviewlayout/src/main/res/drawable-mdpi/ic_directions_subway.png
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/drawable-mdpi/ic_restaurant_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/searchviewlayout/src/main/res/drawable-mdpi/ic_restaurant_menu.png
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/drawable-mdpi/ic_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/searchviewlayout/src/main/res/drawable-mdpi/ic_search.png
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/drawable-tvdpi/ic_arrow_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/searchviewlayout/src/main/res/drawable-tvdpi/ic_arrow_back.png
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/drawable-tvdpi/ic_directions_subway.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/searchviewlayout/src/main/res/drawable-tvdpi/ic_directions_subway.png
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/drawable-tvdpi/ic_restaurant_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/searchviewlayout/src/main/res/drawable-tvdpi/ic_restaurant_menu.png
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/drawable-tvdpi/ic_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/searchviewlayout/src/main/res/drawable-tvdpi/ic_search.png
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/drawable-xhdpi/ic_arrow_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/searchviewlayout/src/main/res/drawable-xhdpi/ic_arrow_back.png
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/drawable-xhdpi/ic_directions_subway.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/searchviewlayout/src/main/res/drawable-xhdpi/ic_directions_subway.png
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/drawable-xhdpi/ic_restaurant_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/searchviewlayout/src/main/res/drawable-xhdpi/ic_restaurant_menu.png
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/drawable-xhdpi/ic_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/searchviewlayout/src/main/res/drawable-xhdpi/ic_search.png
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/drawable-xxhdpi/ic_arrow_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/searchviewlayout/src/main/res/drawable-xxhdpi/ic_arrow_back.png
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/drawable-xxhdpi/ic_directions_subway.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/searchviewlayout/src/main/res/drawable-xxhdpi/ic_directions_subway.png
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/drawable-xxhdpi/ic_restaurant_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/searchviewlayout/src/main/res/drawable-xxhdpi/ic_restaurant_menu.png
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/drawable-xxhdpi/ic_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/searchviewlayout/src/main/res/drawable-xxhdpi/ic_search.png
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/drawable-xxxhdpi/ic_arrow_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/searchviewlayout/src/main/res/drawable-xxxhdpi/ic_arrow_back.png
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/drawable-xxxhdpi/ic_directions_subway.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/searchviewlayout/src/main/res/drawable-xxxhdpi/ic_directions_subway.png
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/drawable-xxxhdpi/ic_restaurant_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/searchviewlayout/src/main/res/drawable-xxxhdpi/ic_restaurant_menu.png
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/drawable-xxxhdpi/ic_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sahildave/Search-View-Layout/39bec74b727d975a9c95001412d0c946ccf3b400/searchviewlayout/src/main/res/drawable-xxxhdpi/ic_search.png
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/drawable/rounded_corners.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/layout/widget_search_bar.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
20 |
21 |
28 |
29 |
39 |
40 |
46 |
47 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/layout/widget_search_bar_expanded.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
21 |
27 |
40 |
50 |
51 |
52 |
56 |
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | #000000
5 |
6 | #ffffff
7 |
8 | #a4a4a4
9 | #a4a4a4
10 | #b6b6b6
11 | #f8f8f8
12 |
13 | #F0F0F0
14 |
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 8dp
5 |
6 | 8dp
7 |
8 | 8dp
9 | 14sp
10 |
11 | 8dp
12 |
13 | 8dp
14 |
15 |
16 | 4dp
17 | 2dp
18 | 16dp
19 | 16dp
20 | 3dp
21 |
22 |
23 | 24dp
24 |
26 | 24dp
27 |
28 | 14dp
29 |
30 | 16dp
31 |
32 | 8dp
33 |
34 | 20sp
35 |
36 |
38 | 120dp
39 |
--------------------------------------------------------------------------------
/searchviewlayout/src/main/res/values/integer.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 300
4 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':sample', ':searchviewlayout'
2 |
--------------------------------------------------------------------------------