├── .gitignore ├── .idea ├── .name ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── libraries │ ├── appcompat_v7_21_0_2.xml │ ├── support_annotations_21_0_2.xml │ └── support_v4_21_0_2.xml ├── misc.xml ├── modules.xml ├── scopes │ └── scope_settings.xml ├── vcs.xml └── workspace.xml ├── CustomSearchDemo.iml ├── CustomSearchView.iml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── app.iml ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── yetwish │ │ └── customsearchdemo │ │ └── activity │ │ ├── MainActivity.java │ │ ├── adapter │ │ └── SearchAdapter.java │ │ ├── model │ │ └── Bean.java │ │ ├── util │ │ ├── CommonAdapter.java │ │ └── ViewHolder.java │ │ └── widge │ │ └── SearchView.java │ └── res │ ├── drawable-hdpi │ ├── ic_launcher.png │ ├── icon.png │ ├── search_clear_normal.png │ ├── search_clear_pressed.png │ └── search_icon.png │ ├── drawable-mdpi │ └── ic_launcher.png │ ├── drawable-xhdpi │ └── ic_launcher.png │ ├── drawable-xxhdpi │ └── ic_launcher.png │ ├── drawable │ ├── btn_search_bg.xml │ ├── iv_delete_bg.xml │ ├── lv_search_tips_bg.xml │ └── search_edittext_shape.xml │ ├── layout │ ├── activity_main.xml │ ├── item_bean_list.xml │ └── search_layout.xml │ ├── menu │ └── menu_main.xml │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── 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 | .gradle/ 17 | build/ 18 | /*/build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | CustomSearchDemo -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/libraries/appcompat_v7_21_0_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/libraries/support_annotations_21_0_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/libraries/support_v4_21_0_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 1.8 14 | 15 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/scopes/scope_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 20 | 21 | 22 | 23 | 24 | 30 | 31 | 32 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 57 | 58 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 149 | 173 | 977 | 982 | 1139 | 1140 | 1141 | 1166 | 1167 | 1168 | 1173 | 1174 | 1175 | 1176 | 1177 | 1178 | 1179 | 1180 | 1181 | 1182 | 1183 | 1184 | 1186 | 1187 | 1188 | 1189 | 1190 | 1191 | 1192 | 1193 | 1194 | 1195 | 1196 | 1197 | 1198 | 1199 | 1200 | 1201 | 1202 | 1203 | 1206 | 1207 | 1208 | 1209 | 1212 | 1213 | 1216 | 1217 | 1220 | 1221 | 1222 | 1223 | 1226 | 1227 | 1230 | 1231 | 1234 | 1235 | 1238 | 1239 | 1240 | 1241 | 1244 | 1245 | 1248 | 1249 | 1250 | 1251 | 1252 | 1253 | 1254 | 1255 | 1256 | 1257 | 1260 | 1261 | 1262 | 1263 | 1266 | 1267 | 1270 | 1271 | 1272 | 1273 | 1276 | 1277 | 1280 | 1281 | 1284 | 1285 | 1286 | 1287 | 1290 | 1291 | 1294 | 1295 | 1298 | 1299 | 1302 | 1303 | 1306 | 1307 | 1308 | 1309 | 1312 | 1313 | 1316 | 1317 | 1320 | 1321 | 1324 | 1325 | 1328 | 1329 | 1332 | 1333 | 1334 | 1335 | 1338 | 1339 | 1342 | 1343 | 1346 | 1347 | 1350 | 1351 | 1354 | 1355 | 1358 | 1359 | 1362 | 1363 | 1364 | 1365 | 1368 | 1369 | 1372 | 1373 | 1376 | 1377 | 1380 | 1381 | 1384 | 1385 | 1388 | 1389 | 1392 | 1393 | 1394 | 1395 | 1398 | 1399 | 1402 | 1403 | 1406 | 1407 | 1410 | 1411 | 1414 | 1415 | 1418 | 1419 | 1422 | 1423 | 1424 | 1425 | 1428 | 1429 | 1432 | 1433 | 1436 | 1437 | 1440 | 1441 | 1444 | 1445 | 1448 | 1449 | 1452 | 1453 | 1454 | 1455 | 1458 | 1459 | 1462 | 1463 | 1466 | 1467 | 1470 | 1471 | 1474 | 1475 | 1478 | 1479 | 1482 | 1483 | 1484 | 1485 | 1488 | 1489 | 1492 | 1493 | 1496 | 1497 | 1500 | 1501 | 1504 | 1505 | 1508 | 1509 | 1512 | 1513 | 1516 | 1517 | 1518 | 1519 | 1522 | 1523 | 1526 | 1527 | 1530 | 1531 | 1534 | 1535 | 1538 | 1539 | 1542 | 1543 | 1546 | 1547 | 1550 | 1551 | 1552 | 1553 | 1556 | 1557 | 1560 | 1561 | 1564 | 1565 | 1568 | 1569 | 1572 | 1573 | 1576 | 1577 | 1580 | 1581 | 1584 | 1585 | 1586 | 1587 | 1590 | 1591 | 1594 | 1595 | 1598 | 1599 | 1602 | 1603 | 1606 | 1607 | 1610 | 1611 | 1614 | 1615 | 1618 | 1619 | 1620 | 1621 | 1622 | 1623 | 1624 | 1625 | 1626 | 1627 | 1628 | 1629 | 1630 | 1631 | 1632 | 1633 | 1634 | 1635 | 1636 | 1637 | 1638 | 1639 | 1640 | 1641 | 1642 | 1643 | 1644 | 1645 | 1646 | 1647 | 1648 | 1649 | 1650 | 1651 | 1652 | 1653 | 1654 | 1655 | 1656 | 1657 | 1671 | 1672 | 1673 | 1674 | 1675 | 1676 | 1677 | 1695 | 1696 | 1697 | 1716 | 1717 | 1730 | 1731 | 1732 | 1750 | 1757 | 1758 | 1759 | 1779 | 1780 | 1781 | 1782 | 1783 | 1785 | 1786 | localhost 1787 | 5050 1788 | 1789 | 1790 | 1791 | 1792 | 1795 | 1796 | 1797 | 1798 | 1799 | 1800 | 1801 | 1802 | 1431351249386 1803 | 1431351249386 1804 | 1805 | 1806 | 1807 | 1808 | 1809 | 1810 | 1811 | 1812 | 1813 | 1814 | 1815 | 1816 | 1817 | 1818 | 1819 | 1820 | 1821 | 1822 | 1823 | 1824 | 1825 | 1826 | 1827 | 1828 | 1829 | 1830 | 1831 | 1832 | 1833 | 1834 | 1835 | 1836 | 1837 | 1838 | 1839 | 1840 | 1841 | 1842 | 1843 | 1844 | 1847 | 1850 | 1851 | 1852 | 1854 | 1855 | 1858 | 1859 | 1860 | 1861 | 1862 | 1863 | 1864 | 1865 | 1866 | 1867 | 1868 | 1869 | 1870 | 1871 | 1872 | 1873 | 1874 | 1875 | 1876 | 1877 | 1878 | 1879 | 1880 | 1881 | 1882 | 1883 | 1884 | 1885 | 1886 | 1887 | 1888 | 1889 | 1890 | 1891 | 1892 | 1893 | 1894 | 1895 | 1896 | 1897 | 1898 | 1899 | 1900 | 1901 | 1902 | 1903 | 1904 | 1905 | 1906 | 1907 | 1908 | 1909 | 1910 | 1911 | 1912 | 1913 | 1914 | 1915 | 1916 | 1917 | 1918 | 1919 | 1920 | 1921 | 1922 | 1923 | 1924 | 1925 | 1926 | 1927 | 1928 | 1929 | 1930 | 1931 | 1932 | 1933 | 1934 | 1935 | 1936 | 1937 | 1938 | 1939 | 1940 | 1941 | 1942 | 1943 | 1944 | 1945 | 1946 | 1947 | 1948 | 1949 | 1950 | 1951 | 1952 | 1953 | 1954 | 1955 | 1956 | 1957 | 1958 | 1959 | 1960 | 1961 | 1962 | 1963 | 1964 | 1965 | 1966 | 1967 | 1968 | 1969 | 1970 | 1971 | 1972 | 1973 | 1974 | 1975 | 1976 | 1977 | 1978 | 1979 | 1980 | 1981 | 1982 | 1983 | 1984 | 1985 | 1986 | 1987 | 1988 | 1989 | 1990 | 1991 | 1992 | 1993 | 1994 | 1995 | 1996 | 1997 | 1998 | 1999 | 2000 | 2001 | 2002 | 2003 | 2004 | 2005 | 2006 | 2007 | 2008 | 2009 | 2010 | 2011 | 2012 | 2013 | 2014 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 2026 | 2027 | 2028 | 2029 | 2030 | 2031 | 2032 | 2033 | 2034 | 2035 | 2036 | 2037 | 2038 | 2039 | 2040 | 2041 | 2042 | 2043 | 2044 | 2045 | 2046 | 2047 | 2048 | 2049 | 2050 | 2051 | 2052 | 2053 | 2054 | 2055 | 2056 | 2057 | 2058 | 2059 | 2060 | 2061 | 2062 | 2063 | 2064 | 2065 | 2066 | 2067 | 2068 | 2069 | 2070 | 2071 | 2072 | 2073 | 2074 | 2075 | 2076 | 2077 | 2078 | 2079 | 2080 | 2081 | 2082 | 2083 | 2084 | 2085 | 2086 | 2087 | 2088 | 2089 | 2090 | 2091 | 2092 | 2093 | 2094 | 2095 | 2096 | 2097 | 2098 | 2099 | 2100 | 2101 | 2102 | 2103 | 2104 | 2105 | 2106 | 2107 | 2108 | 2109 | 2110 | 2111 | 2112 | 2113 | 2114 | 2115 | 2116 | 2117 | 2118 | 2119 | 2120 | 2121 | 2122 | 2123 | 2124 | 2125 | 2126 | 2127 | 2128 | 2129 | 2130 | 2131 | 2132 | 2133 | 2134 | 2135 | 2136 | 2137 | 2138 | 2139 | 2140 | 2141 | 2142 | 2143 | 2144 | 2145 | 2146 | 2147 | 2148 | 2149 | 2150 | 2151 | 2152 | 2153 | 2154 | 2155 | 2156 | 2157 | 2158 | 2159 | 2160 | 2161 | 2162 | 2163 | 2164 | 2165 | 2166 | 2167 | 2168 | 2169 | 2170 | 2171 | 2172 | 2173 | 2174 | 2175 | 2176 | 2177 | 2178 | 2179 | 2180 | 2181 | 2182 | 2183 | 2184 | 2185 | 2186 | 2187 | 2188 | 2189 | 2190 | 2191 | 2192 | 2193 | 2194 | 2195 | 2196 | 2197 | 2198 | 2199 | 2200 | 2201 | 2202 | 2203 | 2204 | 2205 | 2206 | 2207 | 2208 | 2209 | 2210 | 2211 | 2212 | 2213 | 2214 | 2215 | 2216 | 2217 | 2218 | 2219 | 2220 | 2221 | 2222 | 2223 | 2224 | 2225 | 2226 | 2227 | 2228 | 2229 | 2230 | 2231 | 2232 | 2233 | 2234 | 2235 | 2236 | 2237 | 2238 | 2239 | 2240 | 2241 | 2242 | 2243 | 2244 | 2245 | 2246 | 2247 | 2248 | 2249 | 2250 | 2251 | 2252 | 2253 | 2254 | 2255 | 2256 | 2257 | 2258 | 2259 | 2260 | 2261 | 2262 | 2263 | 2264 | 2265 | 2266 | 2267 | 2268 | 2269 | -------------------------------------------------------------------------------- /CustomSearchDemo.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /CustomSearchView.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CustomSearchView 2 | customer search view 3 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/app.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 21 5 | buildToolsVersion "21.1.2" 6 | 7 | defaultConfig { 8 | applicationId "com.yetwish.customsearchdemo" 9 | minSdkVersion 14 10 | targetSdkVersion 21 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:21.0.2' 25 | } 26 | -------------------------------------------------------------------------------- /app/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 F:\Android\sdk\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 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/yetwish/customsearchdemo/activity/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.yetwish.customsearchdemo.activity; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.os.Bundle; 6 | import android.view.View; 7 | import android.view.Window; 8 | import android.view.inputmethod.InputMethodManager; 9 | import android.widget.AdapterView; 10 | import android.widget.ArrayAdapter; 11 | import android.widget.ListView; 12 | import android.widget.Toast; 13 | 14 | import com.yetwish.customsearchdemo.R; 15 | import com.yetwish.customsearchdemo.activity.adapter.SearchAdapter; 16 | import com.yetwish.customsearchdemo.activity.model.Bean; 17 | import com.yetwish.customsearchdemo.activity.widge.SearchView; 18 | 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | 22 | 23 | public class MainActivity extends Activity implements SearchView.SearchViewListener { 24 | 25 | /** 26 | * 搜索结果列表view 27 | */ 28 | private ListView lvResults; 29 | 30 | /** 31 | * 搜索view 32 | */ 33 | private SearchView searchView; 34 | 35 | 36 | /** 37 | * 热搜框列表adapter 38 | */ 39 | private ArrayAdapter hintAdapter; 40 | 41 | /** 42 | * 自动补全列表adapter 43 | */ 44 | private ArrayAdapter autoCompleteAdapter; 45 | 46 | /** 47 | * 搜索结果列表adapter 48 | */ 49 | private SearchAdapter resultAdapter; 50 | 51 | private List dbData; 52 | 53 | /** 54 | * 热搜版数据 55 | */ 56 | private List hintData; 57 | 58 | /** 59 | * 搜索过程中自动补全数据 60 | */ 61 | private List autoCompleteData; 62 | 63 | /** 64 | * 搜索结果的数据 65 | */ 66 | private List resultData; 67 | 68 | /** 69 | * 默认提示框显示项的个数 70 | */ 71 | private static int DEFAULT_HINT_SIZE = 4; 72 | 73 | /** 74 | * 提示框显示项的个数 75 | */ 76 | private static int hintSize = DEFAULT_HINT_SIZE; 77 | 78 | /** 79 | * 设置提示框显示项的个数 80 | * 81 | * @param hintSize 提示框显示个数 82 | */ 83 | public static void setHintSize(int hintSize) { 84 | MainActivity.hintSize = hintSize; 85 | } 86 | 87 | 88 | @Override 89 | protected void onCreate(Bundle savedInstanceState) { 90 | super.onCreate(savedInstanceState); 91 | requestWindowFeature(Window.FEATURE_NO_TITLE); 92 | setContentView(R.layout.activity_main); 93 | initData(); 94 | initViews(); 95 | } 96 | 97 | /** 98 | * 初始化视图 99 | */ 100 | private void initViews() { 101 | lvResults = (ListView) findViewById(R.id.main_lv_search_results); 102 | searchView = (SearchView) findViewById(R.id.main_search_layout); 103 | //设置监听 104 | searchView.setSearchViewListener(this); 105 | //设置adapter 106 | searchView.setTipsHintAdapter(hintAdapter); 107 | searchView.setAutoCompleteAdapter(autoCompleteAdapter); 108 | 109 | lvResults.setOnItemClickListener(new AdapterView.OnItemClickListener() { 110 | @Override 111 | public void onItemClick(AdapterView adapterView, View view, int position, long l) { 112 | Toast.makeText(MainActivity.this, position + "", Toast.LENGTH_SHORT).show(); 113 | } 114 | }); 115 | } 116 | 117 | /** 118 | * 初始化数据 119 | */ 120 | private void initData() { 121 | //从数据库获取数据 122 | getDbData(); 123 | //初始化热搜版数据 124 | getHintData(); 125 | //初始化自动补全数据 126 | getAutoCompleteData(null); 127 | //初始化搜索结果数据 128 | getResultData(null); 129 | } 130 | 131 | /** 132 | * 获取db 数据 133 | */ 134 | private void getDbData() { 135 | int size = 100; 136 | dbData = new ArrayList<>(size); 137 | for (int i = 0; i < size; i++) { 138 | dbData.add(new Bean(R.drawable.icon, "android开发必备技能" + (i + 1), "Android自定义view——自定义搜索view", i * 20 + 2 + "")); 139 | } 140 | } 141 | 142 | /** 143 | * 获取热搜版data 和adapter 144 | */ 145 | private void getHintData() { 146 | hintData = new ArrayList<>(hintSize); 147 | for (int i = 1; i <= hintSize; i++) { 148 | hintData.add("热搜版" + i + ":Android自定义View"); 149 | } 150 | hintAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, hintData); 151 | } 152 | 153 | /** 154 | * 获取自动补全data 和adapter 155 | */ 156 | private void getAutoCompleteData(String text) { 157 | if (autoCompleteData == null) { 158 | //初始化 159 | autoCompleteData = new ArrayList<>(hintSize); 160 | } else { 161 | // 根据text 获取auto data 162 | autoCompleteData.clear(); 163 | for (int i = 0, count = 0; i < dbData.size() 164 | && count < hintSize; i++) { 165 | if (dbData.get(i).getTitle().contains(text.trim())) { 166 | autoCompleteData.add(dbData.get(i).getTitle()); 167 | count++; 168 | } 169 | } 170 | } 171 | if (autoCompleteAdapter == null) { 172 | autoCompleteAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, autoCompleteData); 173 | } else { 174 | autoCompleteAdapter.notifyDataSetChanged(); 175 | } 176 | } 177 | 178 | /** 179 | * 获取搜索结果data和adapter 180 | */ 181 | private void getResultData(String text) { 182 | if (resultData == null) { 183 | // 初始化 184 | resultData = new ArrayList<>(); 185 | } else { 186 | resultData.clear(); 187 | for (int i = 0; i < dbData.size(); i++) { 188 | if (dbData.get(i).getTitle().contains(text.trim())) { 189 | resultData.add(dbData.get(i)); 190 | } 191 | } 192 | } 193 | if (resultAdapter == null) { 194 | resultAdapter = new SearchAdapter(this, resultData, R.layout.item_bean_list); 195 | } else { 196 | resultAdapter.notifyDataSetChanged(); 197 | } 198 | } 199 | 200 | /** 201 | * 当搜索框 文本改变时 触发的回调 ,更新自动补全数据 202 | * @param text 203 | */ 204 | @Override 205 | public void onRefreshAutoComplete(String text) { 206 | //更新数据 207 | getAutoCompleteData(text); 208 | } 209 | 210 | /** 211 | * 点击搜索键时edit text触发的回调 212 | * 213 | * @param text 214 | */ 215 | @Override 216 | public void onSearch(String text) { 217 | //更新result数据 218 | getResultData(text); 219 | lvResults.setVisibility(View.VISIBLE); 220 | //第一次获取结果 还未配置适配器 221 | if (lvResults.getAdapter() == null) { 222 | //获取搜索数据 设置适配器 223 | lvResults.setAdapter(resultAdapter); 224 | } else { 225 | //更新搜索数据 226 | resultAdapter.notifyDataSetChanged(); 227 | } 228 | Toast.makeText(this, "完成搜素", Toast.LENGTH_SHORT).show(); 229 | 230 | 231 | } 232 | 233 | } 234 | -------------------------------------------------------------------------------- /app/src/main/java/com/yetwish/customsearchdemo/activity/adapter/SearchAdapter.java: -------------------------------------------------------------------------------- 1 | package com.yetwish.customsearchdemo.activity.adapter; 2 | 3 | import android.content.Context; 4 | import android.view.View; 5 | 6 | import com.yetwish.customsearchdemo.R; 7 | import com.yetwish.customsearchdemo.activity.model.Bean; 8 | import com.yetwish.customsearchdemo.activity.util.CommonAdapter; 9 | import com.yetwish.customsearchdemo.activity.util.ViewHolder; 10 | 11 | import java.util.List; 12 | 13 | /** 14 | * Created by yetwish on 2015-05-11 15 | */ 16 | 17 | public class SearchAdapter extends CommonAdapter{ 18 | 19 | public SearchAdapter(Context context, List data, int layoutId) { 20 | super(context, data, layoutId); 21 | } 22 | 23 | @Override 24 | public void convert(ViewHolder holder, int position) { 25 | holder.setImageResource(R.id.item_search_iv_icon,mData.get(position).getIconId()) 26 | .setText(R.id.item_search_tv_title,mData.get(position).getTitle()) 27 | .setText(R.id.item_search_tv_content,mData.get(position).getContent()) 28 | .setText(R.id.item_search_tv_comments,mData.get(position).getComments()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/yetwish/customsearchdemo/activity/model/Bean.java: -------------------------------------------------------------------------------- 1 | package com.yetwish.customsearchdemo.activity.model; 2 | 3 | /** 4 | * bean 类 5 | * Created by yetwish on 2015-05-11 6 | */ 7 | 8 | public class Bean { 9 | 10 | private int iconId; 11 | private String title; 12 | private String content; 13 | private String comments; 14 | 15 | public Bean(int iconId, String title, String content, String comments) { 16 | this.iconId = iconId; 17 | this.title = title; 18 | this.content = content; 19 | this.comments = comments; 20 | } 21 | 22 | public int getIconId() { 23 | return iconId; 24 | } 25 | 26 | public void setIconId(int iconId) { 27 | this.iconId = iconId; 28 | } 29 | 30 | public String getTitle() { 31 | return title; 32 | } 33 | 34 | public void setTitle(String title) { 35 | this.title = title; 36 | } 37 | 38 | public String getContent() { 39 | return content; 40 | } 41 | 42 | public void setContent(String content) { 43 | this.content = content; 44 | } 45 | 46 | public String getComments() { 47 | return comments; 48 | } 49 | 50 | public void setComments(String comments) { 51 | this.comments = comments; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /app/src/main/java/com/yetwish/customsearchdemo/activity/util/CommonAdapter.java: -------------------------------------------------------------------------------- 1 | package com.yetwish.customsearchdemo.activity.util; 2 | 3 | import android.content.Context; 4 | import android.view.View; 5 | import android.view.ViewGroup; 6 | import android.widget.BaseAdapter; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * Created by yetwish on 2015-05-11 12 | */ 13 | 14 | public abstract class CommonAdapter extends BaseAdapter{ 15 | 16 | protected Context mContext; 17 | protected List mData; 18 | protected int mLayoutId; 19 | 20 | public CommonAdapter(Context context,List data,int layoutId){ 21 | mContext = context; 22 | mData = data; 23 | mLayoutId = layoutId; 24 | } 25 | 26 | @Override 27 | public int getCount() { 28 | return mData.size(); 29 | } 30 | 31 | @Override 32 | public T getItem(int i) { 33 | return mData.get(i); 34 | } 35 | 36 | @Override 37 | public long getItemId(int i) { 38 | return i; 39 | } 40 | 41 | @Override 42 | public View getView(int position, View convertView, ViewGroup parent) { 43 | ViewHolder holder = ViewHolder.getHolder(mContext,convertView,mLayoutId,parent,position); 44 | convert(holder,position); 45 | return holder.getConvertView(); 46 | } 47 | 48 | /** 49 | * get holder convert 50 | */ 51 | public abstract void convert(ViewHolder holder,int position); 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/java/com/yetwish/customsearchdemo/activity/util/ViewHolder.java: -------------------------------------------------------------------------------- 1 | package com.yetwish.customsearchdemo.activity.util; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.util.SparseArray; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.ImageView; 10 | import android.widget.TextView; 11 | 12 | /** 13 | * Created by yetwish on 2015-05-11 14 | */ 15 | 16 | public class ViewHolder { 17 | 18 | private SparseArray mViews; 19 | private Context mContext; 20 | private View mConvertView; 21 | private int mPosition; 22 | /** 23 | * init holder 24 | */ 25 | public ViewHolder(Context context, int layoutId, ViewGroup parent, int position) { 26 | mConvertView = LayoutInflater.from(context).inflate(layoutId,parent,false); 27 | mViews = new SparseArray<>(); 28 | mPosition = position; 29 | mConvertView.setTag(this); 30 | } 31 | 32 | /** 33 | * 获取viewHolder 34 | */ 35 | public static ViewHolder getHolder(Context context, View convertView, 36 | int layoutId, ViewGroup parent, int position) { 37 | if(convertView == null){ 38 | return new ViewHolder(context,layoutId,parent,position); 39 | }else{ 40 | ViewHolder holder = (ViewHolder)convertView.getTag(); 41 | holder.mPosition = position; 42 | return holder; 43 | } 44 | } 45 | 46 | public View getConvertView(){ 47 | return mConvertView; 48 | } 49 | 50 | /** 51 | * get view 52 | */ 53 | public T getView(int viewId){ 54 | View view = mViews.get(viewId); 55 | if(view == null){ 56 | view = mConvertView.findViewById(viewId); 57 | mViews.put(viewId,view); 58 | } 59 | return (T)view; 60 | } 61 | 62 | /** 63 | * set text 64 | */ 65 | public ViewHolder setText(int viewId, String text){ 66 | TextView tv = getView(viewId); 67 | tv.setText(text); 68 | return this; 69 | } 70 | 71 | /** 72 | * set image res 73 | */ 74 | public ViewHolder setImageResource(int viewId,int resId){ 75 | ImageView iv = getView(viewId); 76 | iv.setImageResource(resId); 77 | return this; 78 | } 79 | 80 | /** 81 | * set image bitmap 82 | */ 83 | public ViewHolder setImageBitmap(int viewId,Bitmap bitmap){ 84 | ImageView iv = getView(viewId); 85 | iv.setImageBitmap(bitmap); 86 | return this; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /app/src/main/java/com/yetwish/customsearchdemo/activity/widge/SearchView.java: -------------------------------------------------------------------------------- 1 | package com.yetwish.customsearchdemo.activity.widge; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.text.Editable; 6 | import android.text.TextWatcher; 7 | import android.util.AttributeSet; 8 | import android.view.KeyEvent; 9 | import android.view.LayoutInflater; 10 | import android.view.View; 11 | import android.view.inputmethod.EditorInfo; 12 | import android.view.inputmethod.InputMethodManager; 13 | import android.widget.AdapterView; 14 | import android.widget.ArrayAdapter; 15 | import android.widget.Button; 16 | import android.widget.EditText; 17 | import android.widget.ImageView; 18 | import android.widget.LinearLayout; 19 | import android.widget.ListView; 20 | import android.widget.TextView; 21 | 22 | import com.yetwish.customsearchdemo.R; 23 | 24 | 25 | /** 26 | * Created by yetwish on 2015-05-11 27 | */ 28 | 29 | public class SearchView extends LinearLayout implements View.OnClickListener { 30 | 31 | /** 32 | * 输入框 33 | */ 34 | private EditText etInput; 35 | 36 | /** 37 | * 删除键 38 | */ 39 | private ImageView ivDelete; 40 | 41 | /** 42 | * 返回按钮 43 | */ 44 | private Button btnBack; 45 | 46 | /** 47 | * 上下文对象 48 | */ 49 | private Context mContext; 50 | 51 | /** 52 | * 弹出列表 53 | */ 54 | private ListView lvTips; 55 | 56 | /** 57 | * 提示adapter (推荐adapter) 58 | */ 59 | private ArrayAdapter mHintAdapter; 60 | 61 | /** 62 | * 自动补全adapter 只显示名字 63 | */ 64 | private ArrayAdapter mAutoCompleteAdapter; 65 | 66 | /** 67 | * 搜索回调接口 68 | */ 69 | private SearchViewListener mListener; 70 | 71 | /** 72 | * 设置搜索回调接口 73 | * 74 | * @param listener 监听者 75 | */ 76 | public void setSearchViewListener(SearchViewListener listener) { 77 | mListener = listener; 78 | } 79 | 80 | public SearchView(Context context, AttributeSet attrs) { 81 | super(context, attrs); 82 | mContext = context; 83 | LayoutInflater.from(context).inflate(R.layout.search_layout, this); 84 | initViews(); 85 | } 86 | 87 | private void initViews() { 88 | etInput = (EditText) findViewById(R.id.search_et_input); 89 | ivDelete = (ImageView) findViewById(R.id.search_iv_delete); 90 | btnBack = (Button) findViewById(R.id.search_btn_back); 91 | lvTips = (ListView) findViewById(R.id.search_lv_tips); 92 | 93 | lvTips.setOnItemClickListener(new AdapterView.OnItemClickListener() { 94 | @Override 95 | public void onItemClick(AdapterView adapterView, View view, int i, long l) { 96 | //set edit text 97 | String text = lvTips.getAdapter().getItem(i).toString(); 98 | etInput.setText(text); 99 | etInput.setSelection(text.length()); 100 | //hint list view gone and result list view show 101 | lvTips.setVisibility(View.GONE); 102 | notifyStartSearching(text); 103 | } 104 | }); 105 | 106 | ivDelete.setOnClickListener(this); 107 | btnBack.setOnClickListener(this); 108 | 109 | etInput.addTextChangedListener(new EditChangedListener()); 110 | etInput.setOnClickListener(this); 111 | etInput.setOnEditorActionListener(new TextView.OnEditorActionListener() { 112 | @Override 113 | public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) { 114 | if (actionId == EditorInfo.IME_ACTION_SEARCH) { 115 | lvTips.setVisibility(GONE); 116 | notifyStartSearching(etInput.getText().toString()); 117 | } 118 | return true; 119 | } 120 | }); 121 | } 122 | 123 | /** 124 | * 通知监听者 进行搜索操作 125 | * @param text 126 | */ 127 | private void notifyStartSearching(String text){ 128 | if (mListener != null) { 129 | mListener.onSearch(etInput.getText().toString()); 130 | } 131 | //隐藏软键盘 132 | InputMethodManager imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE); 133 | imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS); 134 | } 135 | 136 | /** 137 | * 设置热搜版提示 adapter 138 | */ 139 | public void setTipsHintAdapter(ArrayAdapter adapter) { 140 | this.mHintAdapter = adapter; 141 | if (lvTips.getAdapter() == null) { 142 | lvTips.setAdapter(mHintAdapter); 143 | } 144 | } 145 | 146 | /** 147 | * 设置自动补全adapter 148 | */ 149 | public void setAutoCompleteAdapter(ArrayAdapter adapter) { 150 | this.mAutoCompleteAdapter = adapter; 151 | } 152 | 153 | private class EditChangedListener implements TextWatcher { 154 | @Override 155 | public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { 156 | 157 | } 158 | 159 | @Override 160 | public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) { 161 | if (!"".equals(charSequence.toString())) { 162 | ivDelete.setVisibility(VISIBLE); 163 | lvTips.setVisibility(VISIBLE); 164 | if (mAutoCompleteAdapter != null && lvTips.getAdapter() != mAutoCompleteAdapter) { 165 | lvTips.setAdapter(mAutoCompleteAdapter); 166 | } 167 | //更新autoComplete数据 168 | if (mListener != null) { 169 | mListener.onRefreshAutoComplete(charSequence + ""); 170 | } 171 | } else { 172 | ivDelete.setVisibility(GONE); 173 | if (mHintAdapter != null) { 174 | lvTips.setAdapter(mHintAdapter); 175 | } 176 | lvTips.setVisibility(GONE); 177 | } 178 | 179 | } 180 | 181 | @Override 182 | public void afterTextChanged(Editable editable) { 183 | } 184 | } 185 | 186 | @Override 187 | public void onClick(View view) { 188 | switch (view.getId()) { 189 | case R.id.search_et_input: 190 | lvTips.setVisibility(VISIBLE); 191 | break; 192 | case R.id.search_iv_delete: 193 | etInput.setText(""); 194 | ivDelete.setVisibility(GONE); 195 | break; 196 | case R.id.search_btn_back: 197 | ((Activity) mContext).finish(); 198 | break; 199 | } 200 | } 201 | 202 | /** 203 | * search view回调方法 204 | */ 205 | public interface SearchViewListener { 206 | 207 | /** 208 | * 更新自动补全内容 209 | * 210 | * @param text 传入补全后的文本 211 | */ 212 | void onRefreshAutoComplete(String text); 213 | 214 | /** 215 | * 开始搜索 216 | * 217 | * @param text 传入输入框的文本 218 | */ 219 | void onSearch(String text); 220 | 221 | // /** 222 | // * 提示列表项点击时回调方法 (提示/自动补全) 223 | // */ 224 | // void onTipsItemClick(String text); 225 | } 226 | 227 | } 228 | 229 | 230 | // 231 | //import android.app.Activity; 232 | //import android.content.Context; 233 | //import android.text.Editable; 234 | //import android.text.TextWatcher; 235 | //import android.util.AttributeSet; 236 | //import android.view.KeyEvent; 237 | //import android.view.LayoutInflater; 238 | //import android.view.View; 239 | //import android.view.inputmethod.EditorInfo; 240 | //import android.widget.AdapterView; 241 | //import android.widget.Button; 242 | //import android.widget.EditText; 243 | //import android.widget.ImageView; 244 | //import android.widget.LinearLayout; 245 | //import android.widget.ListView; 246 | //import android.widget.TextView; 247 | // 248 | //import com.yetwish.customsearchdemo.R; 249 | //import com.yetwish.customsearchdemo.activity.adapter.SearchAdapter; 250 | //import com.yetwish.customsearchdemo.activity.model.Bean; 251 | // 252 | ///** 253 | // * Created by yetwish on 2015-05-11 254 | // */ 255 | // 256 | //public class SearchView extends LinearLayout implements View.OnClickListener { 257 | // 258 | // private EditText etInput; 259 | // private ImageView ivDelete; 260 | // private Button btnBack; 261 | // private Context mContext; 262 | // 263 | // private ListView lvTips; 264 | // private SearchAdapter mHintAdapter; 265 | // private SearchAdapter mAutoCompleteAdapter; 266 | // 267 | // private SearchViewListener mListener; 268 | // 269 | // public void setSearchViewListener(SearchViewListener listener) { 270 | // mListener = listener; 271 | // } 272 | // 273 | // public SearchView(Context context, AttributeSet attrs) { 274 | // super(context, attrs); 275 | // mContext = context; 276 | // LayoutInflater.from(context).inflate(R.layout.search_layout, this); 277 | // initViews(); 278 | // } 279 | // 280 | // private void initViews() { 281 | // etInput = (EditText) findViewById(R.id.search_et_input); 282 | // ivDelete = (ImageView) findViewById(R.id.search_iv_delete); 283 | // btnBack = (Button) findViewById(R.id.search_btn_back); 284 | // lvTips = (ListView) findViewById(R.id.search_lv_tips); 285 | // 286 | // lvTips.setOnItemClickListener(new AdapterView.OnItemClickListener() { 287 | // @Override 288 | // public void onItemClick(AdapterView adapterView, View view, int i, long l) { 289 | // //set edit text 290 | // Bean currentBean = (Bean) lvTips.getAdapter().getItem(i); 291 | // etInput.setText(currentBean.getTitle()); 292 | // //hint list view gone and result list view show 293 | // lvTips.setVisibility(View.GONE); 294 | // if (mListener != null) { 295 | // mListener.onTipsItemClick(); 296 | // } 297 | // } 298 | // }); 299 | // 300 | // ivDelete.setOnClickListener(this); 301 | // btnBack.setOnClickListener(this); 302 | // 303 | // etInput.addTextChangedListener(new EditChangedListener()); 304 | // etInput.setOnClickListener(this); 305 | // etInput.setOnEditorActionListener(new TextView.OnEditorActionListener() { 306 | // @Override 307 | // public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) { 308 | // if (actionId == EditorInfo.IME_ACTION_SEARCH) { 309 | // if (mListener != null) { 310 | // mListener.onSearch(etInput.getText().toString()); 311 | // } 312 | // } 313 | // return true; 314 | // } 315 | // }); 316 | // } 317 | // 318 | // /** 319 | // * 设置热搜版提示 adapter 320 | // */ 321 | // public void setTipsHintAdapter(SearchAdapter adapter) { 322 | // this.mHintAdapter = adapter; 323 | // if (lvTips.getAdapter() == null) { 324 | // lvTips.setAdapter(mHintAdapter); 325 | // } 326 | // } 327 | // 328 | // /** 329 | // * 设置自动补全adapter 330 | // */ 331 | // public void setAutoCompleteAdapter(SearchAdapter adapter) { 332 | // this.mAutoCompleteAdapter = adapter; 333 | // } 334 | // 335 | // private class EditChangedListener implements TextWatcher { 336 | // @Override 337 | // public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { 338 | // 339 | // } 340 | // 341 | // @Override 342 | // public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) { 343 | // if (!"".equals(charSequence + "")) { 344 | // ivDelete.setVisibility(VISIBLE); 345 | // lvTips.setVisibility(VISIBLE); 346 | // if (mAutoCompleteAdapter != null && lvTips.getAdapter() != mAutoCompleteAdapter) { 347 | // lvTips.setAdapter(mAutoCompleteAdapter); 348 | // } else { 349 | // //更新autoComplete数据 350 | // if (mListener != null) { 351 | // mListener.onRefreshAutoComplete(charSequence + ""); 352 | // } 353 | // } 354 | // } else { 355 | // ivDelete.setVisibility(GONE); 356 | // if (mHintAdapter != null) { 357 | // lvTips.setAdapter(mHintAdapter); 358 | // } 359 | // lvTips.setVisibility(GONE); 360 | // } 361 | // 362 | // } 363 | // 364 | // @Override 365 | // public void afterTextChanged(Editable editable) { 366 | // 367 | // } 368 | // } 369 | // 370 | // @Override 371 | // public void onClick(View view) { 372 | // switch (view.getId()) { 373 | // case R.id.search_et_input: 374 | // lvTips.setVisibility(VISIBLE); 375 | // break; 376 | // case R.id.search_iv_delete: 377 | // etInput.setText(""); 378 | // ivDelete.setVisibility(GONE); 379 | // break; 380 | // case R.id.search_btn_back: 381 | // ((Activity) mContext).finish(); 382 | // break; 383 | // } 384 | // } 385 | // 386 | // /** 387 | // * search view回调方法 388 | // */ 389 | // public interface SearchViewListener { 390 | // 391 | // void onRefreshAutoComplete(String text); 392 | // 393 | // void onSearch(String text); 394 | // 395 | // void onTipsItemClick(); 396 | // } 397 | // 398 | //} 399 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yetwish/CustomSearchView/7964b6e36546864c55bfbbadb9fe341d1a152bb6/app/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yetwish/CustomSearchView/7964b6e36546864c55bfbbadb9fe341d1a152bb6/app/src/main/res/drawable-hdpi/icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/search_clear_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yetwish/CustomSearchView/7964b6e36546864c55bfbbadb9fe341d1a152bb6/app/src/main/res/drawable-hdpi/search_clear_normal.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/search_clear_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yetwish/CustomSearchView/7964b6e36546864c55bfbbadb9fe341d1a152bb6/app/src/main/res/drawable-hdpi/search_clear_pressed.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/search_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yetwish/CustomSearchView/7964b6e36546864c55bfbbadb9fe341d1a152bb6/app/src/main/res/drawable-hdpi/search_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yetwish/CustomSearchView/7964b6e36546864c55bfbbadb9fe341d1a152bb6/app/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yetwish/CustomSearchView/7964b6e36546864c55bfbbadb9fe341d1a152bb6/app/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yetwish/CustomSearchView/7964b6e36546864c55bfbbadb9fe341d1a152bb6/app/src/main/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/btn_search_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/iv_delete_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/lv_search_tips_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/search_edittext_shape.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 12 | 13 | 14 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_bean_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 12 | 22 | 34 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /app/src/main/res/layout/search_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | 15 | 19 | 20 | 33 | 34 | 42 | 43 | 44 |