├── .gitignore ├── LICENSE ├── README-cn.md ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── baiiu │ │ └── dropdownmenu │ │ ├── DropMenuAdapter.java │ │ ├── MainActivity.java │ │ ├── entity │ │ ├── FilterType.java │ │ └── FilterUrl.java │ │ ├── fragmentSample │ │ ├── FilterActivity.java │ │ └── FilterFragment.java │ │ └── view │ │ ├── betterDoubleGrid │ │ ├── BetterDoubleGridView.java │ │ ├── DoubleGridAdapter.java │ │ └── holder │ │ │ ├── ItemViewHolder.java │ │ │ └── TitleViewHolder.java │ │ └── doubleGrid │ │ ├── DoubleGridView.java │ │ └── GridViewInScrollView.java │ └── res │ ├── drawable │ ├── news_article_icon_gray_line_4.xml │ ├── rect_blue_stroke.xml │ ├── rect_grey_stroke.xml │ ├── selector_double_grid.xml │ └── selector_filter_grid.xml │ ├── layout │ ├── activity_main.xml │ ├── holder_item.xml │ ├── holder_title.xml │ ├── merge_filter_double_grid.xml │ └── merge_filter_third.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ ├── values-v21 │ └── styles.xml │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── filter-lib ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── baiiu │ │ └── filter │ │ ├── DropDownMenu.java │ │ ├── adapter │ │ ├── BaseBaseAdapter.java │ │ ├── MenuAdapter.java │ │ └── SimpleTextAdapter.java │ │ ├── interfaces │ │ ├── OnFilterDoneListener.java │ │ └── OnFilterItemClickListener.java │ │ ├── typeview │ │ ├── DoubleListView.java │ │ ├── SingleGridView.java │ │ └── SingleListView.java │ │ ├── util │ │ ├── CommonUtil.java │ │ ├── SimpleAnimationListener.java │ │ └── UIUtil.java │ │ └── view │ │ ├── FilterCheckedTextView.java │ │ └── FixedTabIndicator.java │ └── res │ ├── anim │ ├── alpha_to_one.xml │ ├── alpha_to_zero.xml │ ├── top_in.xml │ └── top_out.xml │ ├── drawable-xxhdpi │ ├── common_filter_arrow_down.png │ └── common_filter_arrow_up.png │ ├── drawable │ ├── layer_filter_checked.xml │ ├── layer_filter_unchecked.xml │ ├── level_filter.xml │ ├── selector_filter_left.xml │ └── selector_tv_filter.xml │ ├── layout │ ├── lv_item_filter.xml │ └── merge_filter_list.xml │ └── values │ ├── color.xml │ ├── ids.xml │ └── strings.xml ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── images └── dropDownMenu.gif └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | .idea 4 | /local.properties 5 | .DS_Store 6 | /build 7 | /captures 8 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /README-cn.md: -------------------------------------------------------------------------------- 1 | ##DropDownMenu 2 | [![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-DropDownMenu-green.svg?style=true)](https://android-arsenal.com/details/1/3803) 3 | 4 | 5 | 6 | 筛选器. 尽管之前有很多人写,站在别人基础上重新写了一版,适配各种数据model. 7 | 现在的代码已经很清晰明了,模块分明. 8 | 9 | ##特点 10 | 1. 使用 Adapter模式 添加筛选器条目.使代码清晰可见,便于维护. 11 | 2. 使用泛型支持各种数据数据model. 提供三种泛型View类, 单列ListView,双列ListView 和 单个GridView, sample中还提供了两个GridView的示例. 12 | 3. 自己写FilterCheckedView,支持checked属性,使用selector就可配置选中样式.配合AbsListView.setChecked()使用 13 | 4. 使用FilterUrl作为中介,toString()方法获取到所拼接url,隔离了数据和View,使代码更清晰. 14 | 15 | ##ScreenShot 16 | ![DropDownMenu](images/dropDownMenu.gif "Gif Example") 17 | 18 | 19 | 20 | ##使用 21 | 布局文件 22 | ``` 23 | 27 | 28 | 34 | 35 | ``` 36 | 37 | 代码中: 38 | ```java 39 | //代码中设置Adapter. 40 | dropDownView.setMenuAdapter(new DropMenuAdapter(this, titleList)); 41 | ``` 42 | 43 | DropMenuAdapter中: 44 | ``` 45 | @Override 46 | public int getMenuCount() { 47 | return titles.length; 48 | } 49 | 50 | @Override 51 | public String getMenuTitle(int position) { 52 | return titles[position]; 53 | } 54 | 55 | @Override 56 | public int getBottomMargin(int position) { 57 | return 0; 58 | } 59 | 60 | @Override 61 | public View getView(int position, FrameLayout parentContainer) { 62 | ... 63 | return createSingleListView(); 64 | } 65 | ``` 66 | 67 | 添加SingleListView 68 | ```java 69 | private View createSingleListView() { 70 | SingleListView singleListView = new SingleListView(mContext) 71 | .adapter(new SimpleTextAdapter(null, mContext) { 72 | @Override 73 | public String provideText(String string) { 74 | return string; 75 | } 76 | }) 77 | .onItemClick(new OnFilterItemClickListener() { 78 | @Override 79 | public void onItemClick(String item) { 80 | FilterUrl.instance().singleListPosition = item; 81 | 82 | FilterUrl.instance().position = 0; 83 | FilterUrl.instance().positionTitle = item; 84 | 85 | if (onFilterDoneListener != null) { 86 | onFilterDoneListener.onFilterDone(0, "", ""); 87 | } 88 | } 89 | }); 90 | 91 | //初始化数据 92 | singleListView.setList(list, -1);//默认不选中 93 | } 94 | ``` 95 | 96 | 97 | ## License 98 | Copyright (C) 2016 zhe zhu 99 | 100 | Licensed under the Apache License, Version 2.0 (the "License"); 101 | you may not use this file except in compliance with the License. 102 | You may obtain a copy of the License at 103 | 104 | http://www.apache.org/licenses/LICENSE-2.0 105 | 106 | Unless required by applicable law or agreed to in writing, software 107 | distributed under the License is distributed on an "AS IS" BASIS, 108 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 109 | See the License for the specific language governing permissions and 110 | limitations under the License. 111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## DropDownMenu 2 | [![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-DropDownMenu-green.svg?style=true)](https://android-arsenal.com/details/1/3803) 3 | 4 | 5 | This is a DropDownMenu with the advantage of all the dropDownMenus by others before, 6 | I have written it for several times, Now the code is most clearly. 7 | 8 | [中文文档](README-cn.md) 9 | 10 | ##Feature 11 | 1. use Adapter to add the SubDropDownMenu. Override the `getView()` method to supply the wantted view. 12 | 2. use Generic to make all kinds of model(pojo,javabean...) can be used. 13 | 3. use FilterCheckedView which implements `Checkable`, so you can use selector to respond to all user action. 14 | 4. use FilterUrl to save the current choosen data, only override `toString()` you will get the url. 15 | 16 | ##ScreenShot 17 | ![DropDownMenu](images/dropDownMenu.gif "Gif Example") 18 | 19 | ## Usage 20 | the xml: 21 | ```xml 22 | 26 | 27 | 33 | 34 | ``` 35 | 36 | the JavaCode: 37 | ```java 38 | //set the Adapter. 39 | dropDownView.setMenuAdapter(new DropMenuAdapter(this, titleList)); 40 | ``` 41 | 42 | the DropMenuAdapter: 43 | ```java 44 | @Override 45 | public int getMenuCount() { 46 | return titles.length; 47 | } 48 | 49 | @Override 50 | public String getMenuTitle(int position) { 51 | return titles[position]; 52 | } 53 | 54 | @Override 55 | public int getBottomMargin(int position) { 56 | return 0; 57 | } 58 | 59 | @Override 60 | public View getView(int position, FrameLayout parentContainer) { 61 | ... 62 | return createSingleListView(); 63 | } 64 | ``` 65 | 66 | add a SingleListView: 67 | ```java 68 | private View createSingleListView() { 69 | 70 | SingleListView singleListView = new SingleListView(mContext) 71 | .adapter(new SimpleTextAdapter(null, mContext) { 72 | @Override 73 | public String provideText(String string) { 74 | return string; 75 | } 76 | }) 77 | .onItemClick(new OnFilterItemClickListener() { 78 | @Override 79 | public void onItemClick(String item) { 80 | FilterUrl.instance().singleListPosition = item; 81 | 82 | FilterUrl.instance().position = 0; 83 | FilterUrl.instance().positionTitle = item; 84 | 85 | if (onFilterDoneListener != null) { 86 | onFilterDoneListener.onFilterDone(0, "", ""); 87 | } 88 | } 89 | }); 90 | 91 | //初始化数据 92 | singleListView.setList(list, -1);//默认不选中 93 | } 94 | ``` 95 | 96 | 97 | ## License 98 | Copyright (C) 2016 zhe zhu 99 | 100 | Licensed under the Apache License, Version 2.0 (the "License"); 101 | you may not use this file except in compliance with the License. 102 | You may obtain a copy of the License at 103 | 104 | http://www.apache.org/licenses/LICENSE-2.0 105 | 106 | Unless required by applicable law or agreed to in writing, software 107 | distributed under the License is distributed on an "AS IS" BASIS, 108 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 109 | See the License for the specific language governing permissions and 110 | limitations under the License. 111 | 112 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 25 5 | 6 | defaultConfig { 7 | applicationId "com.baiiu.dropdownmenu" 8 | minSdkVersion 15 9 | targetSdkVersion 25 10 | versionCode 1 11 | versionName "1.0" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | implementation fileTree(include: ['*.jar'], dir: 'libs') 23 | implementation project(':filter-lib') 24 | testImplementation 'junit:junit:4.12' 25 | implementation 'com.android.support:appcompat-v7:25.4.0' 26 | implementation 'com.jakewharton:butterknife:8.8.1' 27 | annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1' 28 | implementation 'com.android.support:recyclerview-v7:25.4.0' 29 | } 30 | -------------------------------------------------------------------------------- /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 /Users/baiiu/Library/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 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/baiiu/dropdownmenu/DropMenuAdapter.java: -------------------------------------------------------------------------------- 1 | package com.baiiu.dropdownmenu; 2 | 3 | import android.content.Context; 4 | import android.view.Gravity; 5 | import android.view.View; 6 | import android.widget.FrameLayout; 7 | 8 | import com.baiiu.dropdownmenu.view.betterDoubleGrid.BetterDoubleGridView; 9 | import com.baiiu.filter.adapter.MenuAdapter; 10 | import com.baiiu.filter.adapter.SimpleTextAdapter; 11 | import com.baiiu.filter.interfaces.OnFilterDoneListener; 12 | import com.baiiu.filter.interfaces.OnFilterItemClickListener; 13 | import com.baiiu.filter.typeview.DoubleListView; 14 | import com.baiiu.filter.typeview.SingleGridView; 15 | import com.baiiu.filter.typeview.SingleListView; 16 | import com.baiiu.filter.util.CommonUtil; 17 | import com.baiiu.filter.util.UIUtil; 18 | import com.baiiu.filter.view.FilterCheckedTextView; 19 | import com.baiiu.dropdownmenu.entity.FilterType; 20 | import com.baiiu.dropdownmenu.entity.FilterUrl; 21 | import com.baiiu.dropdownmenu.view.doubleGrid.DoubleGridView; 22 | 23 | import java.util.ArrayList; 24 | import java.util.List; 25 | 26 | /** 27 | * author: baiiu 28 | * date: on 16/1/17 21:14 29 | * description: 30 | */ 31 | public class DropMenuAdapter implements MenuAdapter { 32 | private final Context mContext; 33 | private OnFilterDoneListener onFilterDoneListener; 34 | private String[] titles; 35 | 36 | public DropMenuAdapter(Context context, String[] titles, OnFilterDoneListener onFilterDoneListener) { 37 | this.mContext = context; 38 | this.titles = titles; 39 | this.onFilterDoneListener = onFilterDoneListener; 40 | } 41 | 42 | @Override 43 | public int getMenuCount() { 44 | return titles.length; 45 | } 46 | 47 | @Override 48 | public String getMenuTitle(int position) { 49 | return titles[position]; 50 | } 51 | 52 | @Override 53 | public int getBottomMargin(int position) { 54 | if (position == 3) { 55 | return 0; 56 | } 57 | 58 | return UIUtil.dp(mContext, 140); 59 | } 60 | 61 | @Override 62 | public View getView(int position, FrameLayout parentContainer) { 63 | View view = parentContainer.getChildAt(position); 64 | 65 | switch (position) { 66 | case 0: 67 | view = createSingleListView(); 68 | break; 69 | case 1: 70 | view = createDoubleListView(); 71 | break; 72 | case 2: 73 | view = createSingleGridView(); 74 | break; 75 | case 3: 76 | // view = createDoubleGrid(); 77 | view = createBetterDoubleGrid(); 78 | break; 79 | } 80 | 81 | return view; 82 | } 83 | 84 | private View createSingleListView() { 85 | SingleListView singleListView = new SingleListView(mContext) 86 | .adapter(new SimpleTextAdapter(null, mContext) { 87 | @Override 88 | public String provideText(String string) { 89 | return string; 90 | } 91 | 92 | @Override 93 | protected void initCheckedTextView(FilterCheckedTextView checkedTextView) { 94 | int dp = UIUtil.dp(mContext, 15); 95 | checkedTextView.setPadding(dp, dp, 0, dp); 96 | } 97 | }) 98 | .onItemClick(new OnFilterItemClickListener() { 99 | @Override 100 | public void onItemClick(String item) { 101 | FilterUrl.instance().singleListPosition = item; 102 | 103 | FilterUrl.instance().position = 0; 104 | FilterUrl.instance().positionTitle = item; 105 | 106 | onFilterDone(); 107 | } 108 | }); 109 | 110 | List list = new ArrayList<>(); 111 | for (int i = 0; i < 10; ++i) { 112 | list.add("" + i); 113 | } 114 | singleListView.setList(list, -1); 115 | 116 | return singleListView; 117 | } 118 | 119 | 120 | private View createDoubleListView() { 121 | DoubleListView comTypeDoubleListView = new DoubleListView(mContext) 122 | .leftAdapter(new SimpleTextAdapter(null, mContext) { 123 | @Override 124 | public String provideText(FilterType filterType) { 125 | return filterType.desc; 126 | } 127 | 128 | @Override 129 | protected void initCheckedTextView(FilterCheckedTextView checkedTextView) { 130 | checkedTextView.setPadding(UIUtil.dp(mContext, 44), UIUtil.dp(mContext, 15), 0, UIUtil.dp(mContext, 15)); 131 | } 132 | }) 133 | .rightAdapter(new SimpleTextAdapter(null, mContext) { 134 | @Override 135 | public String provideText(String s) { 136 | return s; 137 | } 138 | 139 | @Override 140 | protected void initCheckedTextView(FilterCheckedTextView checkedTextView) { 141 | checkedTextView.setPadding(UIUtil.dp(mContext, 30), UIUtil.dp(mContext, 15), 0, UIUtil.dp(mContext, 15)); 142 | checkedTextView.setBackgroundResource(android.R.color.white); 143 | } 144 | }) 145 | .onLeftItemClickListener(new DoubleListView.OnLeftItemClickListener() { 146 | @Override 147 | public List provideRightList(FilterType item, int position) { 148 | List child = item.child; 149 | if (CommonUtil.isEmpty(child)) { 150 | FilterUrl.instance().doubleListLeft = item.desc; 151 | FilterUrl.instance().doubleListRight = ""; 152 | 153 | FilterUrl.instance().position = 1; 154 | FilterUrl.instance().positionTitle = item.desc; 155 | 156 | onFilterDone(); 157 | } 158 | 159 | return child; 160 | } 161 | }) 162 | .onRightItemClickListener(new DoubleListView.OnRightItemClickListener() { 163 | @Override 164 | public void onRightItemClick(FilterType item, String string) { 165 | FilterUrl.instance().doubleListLeft = item.desc; 166 | FilterUrl.instance().doubleListRight = string; 167 | 168 | FilterUrl.instance().position = 1; 169 | FilterUrl.instance().positionTitle = string; 170 | 171 | onFilterDone(); 172 | } 173 | }); 174 | 175 | 176 | List list = new ArrayList<>(); 177 | 178 | //第一项 179 | FilterType filterType = new FilterType(); 180 | filterType.desc = "10"; 181 | list.add(filterType); 182 | 183 | //第二项 184 | filterType = new FilterType(); 185 | filterType.desc = "11"; 186 | List childList = new ArrayList<>(); 187 | for (int i = 0; i < 13; ++i) { 188 | childList.add("11" + i); 189 | } 190 | filterType.child = childList; 191 | list.add(filterType); 192 | 193 | //第三项 194 | filterType = new FilterType(); 195 | filterType.desc = "12"; 196 | childList = new ArrayList<>(); 197 | for (int i = 0; i < 3; ++i) { 198 | childList.add("12" + i); 199 | } 200 | filterType.child = childList; 201 | list.add(filterType); 202 | 203 | //初始化选中. 204 | comTypeDoubleListView.setLeftList(list, 1); 205 | comTypeDoubleListView.setRightList(list.get(1).child, -1); 206 | comTypeDoubleListView.getLeftListView().setBackgroundColor(mContext.getResources().getColor(R.color.b_c_fafafa)); 207 | 208 | return comTypeDoubleListView; 209 | } 210 | 211 | 212 | private View createSingleGridView() { 213 | SingleGridView singleGridView = new SingleGridView(mContext) 214 | .adapter(new SimpleTextAdapter(null, mContext) { 215 | @Override 216 | public String provideText(String s) { 217 | return s; 218 | } 219 | 220 | @Override 221 | protected void initCheckedTextView(FilterCheckedTextView checkedTextView) { 222 | checkedTextView.setPadding(0, UIUtil.dp(context, 3), 0, UIUtil.dp(context, 3)); 223 | checkedTextView.setGravity(Gravity.CENTER); 224 | checkedTextView.setBackgroundResource(R.drawable.selector_filter_grid); 225 | } 226 | }) 227 | .onItemClick(new OnFilterItemClickListener() { 228 | @Override 229 | public void onItemClick(String item) { 230 | FilterUrl.instance().singleGridPosition = item; 231 | 232 | FilterUrl.instance().position = 2; 233 | FilterUrl.instance().positionTitle = item; 234 | 235 | onFilterDone(); 236 | 237 | } 238 | }); 239 | 240 | List list = new ArrayList<>(); 241 | for (int i = 20; i < 39; ++i) { 242 | list.add(String.valueOf(i)); 243 | } 244 | singleGridView.setList(list, -1); 245 | 246 | 247 | return singleGridView; 248 | } 249 | 250 | 251 | private View createBetterDoubleGrid() { 252 | 253 | List phases = new ArrayList<>(); 254 | for (int i = 0; i < 10; ++i) { 255 | phases.add("3top" + i); 256 | } 257 | List areas = new ArrayList<>(); 258 | for (int i = 0; i < 10; ++i) { 259 | areas.add("3bottom" + i); 260 | } 261 | 262 | 263 | return new BetterDoubleGridView(mContext) 264 | .setmTopGridData(phases) 265 | .setmBottomGridList(areas) 266 | .setOnFilterDoneListener(onFilterDoneListener) 267 | .build(); 268 | } 269 | 270 | 271 | private View createDoubleGrid() { 272 | DoubleGridView doubleGridView = new DoubleGridView(mContext); 273 | doubleGridView.setOnFilterDoneListener(onFilterDoneListener); 274 | 275 | 276 | List phases = new ArrayList<>(); 277 | for (int i = 0; i < 10; ++i) { 278 | phases.add("3top" + i); 279 | } 280 | doubleGridView.setTopGridData(phases); 281 | 282 | List areas = new ArrayList<>(); 283 | for (int i = 0; i < 10; ++i) { 284 | areas.add("3bottom" + i); 285 | } 286 | doubleGridView.setBottomGridList(areas); 287 | 288 | return doubleGridView; 289 | } 290 | 291 | 292 | private void onFilterDone() { 293 | if (onFilterDoneListener != null) { 294 | onFilterDoneListener.onFilterDone(0, "", ""); 295 | } 296 | } 297 | 298 | } 299 | -------------------------------------------------------------------------------- /app/src/main/java/com/baiiu/dropdownmenu/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.baiiu.dropdownmenu; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.support.v7.widget.Toolbar; 7 | import android.view.View; 8 | import android.widget.TextView; 9 | import butterknife.BindView; 10 | import butterknife.ButterKnife; 11 | import com.baiiu.dropdownmenu.entity.FilterUrl; 12 | import com.baiiu.dropdownmenu.fragmentSample.FilterActivity; 13 | import com.baiiu.filter.DropDownMenu; 14 | import com.baiiu.filter.interfaces.OnFilterDoneListener; 15 | 16 | public class MainActivity extends AppCompatActivity implements OnFilterDoneListener, View.OnClickListener { 17 | 18 | @BindView(R.id.dropDownMenu) DropDownMenu dropDownMenu; 19 | @BindView(R.id.mFilterContentView) TextView mFilterContentView; 20 | 21 | @Override protected void onCreate(Bundle savedInstanceState) { 22 | super.onCreate(savedInstanceState); 23 | setContentView(R.layout.activity_main); 24 | ButterKnife.bind(this); 25 | 26 | Toolbar toolbar = ButterKnife.findById(this, R.id.toolbar); 27 | setSupportActionBar(toolbar); 28 | 29 | initFilterDropDownView(); 30 | 31 | mFilterContentView.setOnClickListener(this); 32 | } 33 | 34 | private void initFilterDropDownView() { 35 | String[] titleList = new String[] { "第一个", "第二个", "第三个", "第四个" }; 36 | dropDownMenu.setMenuAdapter(new DropMenuAdapter(this, titleList, this)); 37 | } 38 | 39 | @Override public void onFilterDone(int position, String positionTitle, String urlValue) { 40 | if (position != 3) { 41 | dropDownMenu.setPositionIndicatorText(FilterUrl.instance().position, FilterUrl.instance().positionTitle); 42 | } 43 | 44 | dropDownMenu.close(); 45 | mFilterContentView.setText(FilterUrl.instance() 46 | .toString()); 47 | } 48 | 49 | @Override protected void onDestroy() { 50 | super.onDestroy(); 51 | FilterUrl.instance() 52 | .clear(); 53 | } 54 | 55 | @Override public void onClick(View view) { 56 | startActivity(new Intent(this, FilterActivity.class)); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/java/com/baiiu/dropdownmenu/entity/FilterType.java: -------------------------------------------------------------------------------- 1 | package com.baiiu.dropdownmenu.entity; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * author: baiiu 7 | * date: on 16/2/19 18:09 8 | * description: 9 | */ 10 | public class FilterType { 11 | public String desc; 12 | public List child; 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/baiiu/dropdownmenu/entity/FilterUrl.java: -------------------------------------------------------------------------------- 1 | package com.baiiu.dropdownmenu.entity; 2 | 3 | import android.text.TextUtils; 4 | 5 | /** 6 | * 描述: 7 | */ 8 | public class FilterUrl { 9 | private volatile static FilterUrl filterUrl; 10 | 11 | private FilterUrl() { 12 | } 13 | 14 | public static FilterUrl instance() { 15 | if (filterUrl == null) { 16 | synchronized (FilterUrl.class) { 17 | if (filterUrl == null) { 18 | filterUrl = new FilterUrl(); 19 | } 20 | } 21 | } 22 | return filterUrl; 23 | } 24 | 25 | public String singleListPosition; 26 | public String doubleListLeft; 27 | public String doubleListRight; 28 | public String singleGridPosition; 29 | public String doubleGridTop; 30 | public String doubleGridBottom; 31 | 32 | public int position; 33 | public String positionTitle; 34 | 35 | @Override 36 | public String toString() { 37 | StringBuilder buffer = new StringBuilder(); 38 | 39 | if (!TextUtils.isEmpty(singleListPosition)) { 40 | buffer.append("singleListPosition="); 41 | buffer.append(singleListPosition); 42 | buffer.append("\n"); 43 | } 44 | 45 | 46 | if (!TextUtils.isEmpty(doubleListLeft)) { 47 | buffer.append("doubleListLeft="); 48 | buffer.append(doubleListLeft); 49 | buffer.append("\n"); 50 | } 51 | 52 | if (!TextUtils.isEmpty(doubleListRight)) { 53 | buffer.append("doubleListRight="); 54 | buffer.append(doubleListRight); 55 | buffer.append("\n"); 56 | } 57 | 58 | if (!TextUtils.isEmpty(singleGridPosition)) { 59 | buffer.append("singleGridPosition="); 60 | buffer.append(singleGridPosition); 61 | buffer.append("\n"); 62 | } 63 | 64 | if (!TextUtils.isEmpty(doubleGridTop)) { 65 | buffer.append("doubleGridTop="); 66 | buffer.append(doubleGridTop); 67 | buffer.append("\n"); 68 | } 69 | 70 | if (!TextUtils.isEmpty(doubleGridBottom)) { 71 | buffer.append("doubleGridBottom="); 72 | buffer.append(doubleGridBottom); 73 | buffer.append("\n"); 74 | } 75 | 76 | return buffer.toString(); 77 | } 78 | 79 | public void clear() { 80 | filterUrl = null; 81 | } 82 | 83 | 84 | } -------------------------------------------------------------------------------- /app/src/main/java/com/baiiu/dropdownmenu/fragmentSample/FilterActivity.java: -------------------------------------------------------------------------------- 1 | package com.baiiu.dropdownmenu.fragmentSample; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.app.AppCompatActivity; 6 | 7 | /** 8 | * author: baiiu 9 | * date: on 18/1/8 11:56 10 | * description: 11 | */ 12 | public class FilterActivity extends AppCompatActivity { 13 | 14 | @Override protected void onCreate(@Nullable Bundle savedInstanceState) { 15 | super.onCreate(savedInstanceState); 16 | 17 | getSupportFragmentManager().beginTransaction() 18 | .replace(android.R.id.content, new FilterFragment(), FilterFragment.class.getCanonicalName()) 19 | .commitAllowingStateLoss(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/baiiu/dropdownmenu/fragmentSample/FilterFragment.java: -------------------------------------------------------------------------------- 1 | package com.baiiu.dropdownmenu.fragmentSample; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v4.app.Fragment; 6 | import android.support.v7.widget.Toolbar; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.widget.TextView; 11 | import butterknife.BindView; 12 | import butterknife.ButterKnife; 13 | import com.baiiu.dropdownmenu.DropMenuAdapter; 14 | import com.baiiu.dropdownmenu.R; 15 | import com.baiiu.dropdownmenu.entity.FilterUrl; 16 | import com.baiiu.filter.DropDownMenu; 17 | import com.baiiu.filter.interfaces.OnFilterDoneListener; 18 | 19 | /** 20 | * author: baiiu 21 | * date: on 18/1/8 11:52 22 | * description: 23 | */ 24 | public class FilterFragment extends Fragment implements OnFilterDoneListener { 25 | 26 | @BindView(R.id.dropDownMenu) DropDownMenu dropDownMenu; 27 | @BindView(R.id.mFilterContentView) TextView mFilterContentView; 28 | @BindView(R.id.toolbar) Toolbar mToolbar; 29 | 30 | @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, 31 | @Nullable Bundle savedInstanceState) { 32 | 33 | View view = inflater.inflate(R.layout.activity_main, container, false); 34 | ButterKnife.bind(this, view); 35 | 36 | mToolbar.setTitle(R.string.app_name); 37 | 38 | return view; 39 | } 40 | 41 | @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { 42 | super.onActivityCreated(savedInstanceState); 43 | initFilterDropDownView(); 44 | } 45 | 46 | private void initFilterDropDownView() { 47 | String[] titleList = new String[] { "第一个", "第二个", "第三个", "第四个" }; 48 | dropDownMenu.setMenuAdapter(new DropMenuAdapter(getContext(), titleList, this)); 49 | } 50 | 51 | @Override public void onFilterDone(int position, String positionTitle, String urlValue) { 52 | if (position != 3) { 53 | dropDownMenu.setPositionIndicatorText(FilterUrl.instance().position, FilterUrl.instance().positionTitle); 54 | } 55 | 56 | dropDownMenu.close(); 57 | mFilterContentView.setText(FilterUrl.instance() 58 | .toString()); 59 | } 60 | 61 | @Override public void onDestroy() { 62 | super.onDestroy(); 63 | FilterUrl.instance() 64 | .clear(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/java/com/baiiu/dropdownmenu/view/betterDoubleGrid/BetterDoubleGridView.java: -------------------------------------------------------------------------------- 1 | package com.baiiu.dropdownmenu.view.betterDoubleGrid; 2 | 3 | import android.annotation.TargetApi; 4 | import android.content.Context; 5 | import android.graphics.Color; 6 | import android.os.Build; 7 | import android.support.v7.widget.GridLayoutManager; 8 | import android.support.v7.widget.RecyclerView; 9 | import android.util.AttributeSet; 10 | import android.view.View; 11 | import android.widget.LinearLayout; 12 | import android.widget.TextView; 13 | import butterknife.BindView; 14 | import butterknife.ButterKnife; 15 | import butterknife.OnClick; 16 | import com.baiiu.dropdownmenu.R; 17 | import com.baiiu.dropdownmenu.entity.FilterUrl; 18 | import com.baiiu.filter.interfaces.OnFilterDoneListener; 19 | import java.util.List; 20 | 21 | /** 22 | * auther: baiiu 23 | * time: 16/6/5 05 23:03 24 | * description: 25 | */ 26 | public class BetterDoubleGridView extends LinearLayout implements View.OnClickListener { 27 | 28 | @BindView(R.id.recyclerView) RecyclerView recyclerView; 29 | 30 | private List mTopGridData; 31 | private List mBottomGridList; 32 | private OnFilterDoneListener mOnFilterDoneListener; 33 | 34 | 35 | public BetterDoubleGridView(Context context) { 36 | this(context, null); 37 | } 38 | 39 | public BetterDoubleGridView(Context context, AttributeSet attrs) { 40 | super(context, attrs); 41 | init(context); 42 | } 43 | 44 | public BetterDoubleGridView(Context context, AttributeSet attrs, int defStyleAttr) { 45 | super(context, attrs, defStyleAttr); 46 | init(context); 47 | } 48 | 49 | @TargetApi(Build.VERSION_CODES.LOLLIPOP) 50 | public BetterDoubleGridView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 51 | super(context, attrs, defStyleAttr, defStyleRes); 52 | init(context); 53 | } 54 | 55 | private void init(Context context) { 56 | setBackgroundColor(Color.WHITE); 57 | inflate(context, R.layout.merge_filter_double_grid, this); 58 | ButterKnife.bind(this, this); 59 | } 60 | 61 | 62 | public BetterDoubleGridView setmTopGridData(List mTopGridData) { 63 | this.mTopGridData = mTopGridData; 64 | return this; 65 | } 66 | 67 | public BetterDoubleGridView setmBottomGridList(List mBottomGridList) { 68 | this.mBottomGridList = mBottomGridList; 69 | return this; 70 | } 71 | 72 | public BetterDoubleGridView build() { 73 | 74 | GridLayoutManager gridLayoutManager = new GridLayoutManager(this.getContext(), 4); 75 | gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { 76 | @Override public int getSpanSize(int position) { 77 | if (position == 0 || position == mTopGridData.size() + 1) { 78 | return 4; 79 | } 80 | return 1; 81 | } 82 | }); 83 | recyclerView.setLayoutManager(gridLayoutManager); 84 | recyclerView.setAdapter(new DoubleGridAdapter(getContext(), mTopGridData, mBottomGridList, this)); 85 | 86 | return this; 87 | } 88 | 89 | private TextView mTopSelectedTextView; 90 | private TextView mBottomSelectedTextView; 91 | 92 | @Override public void onClick(View v) { 93 | 94 | TextView textView = (TextView) v; 95 | String text = (String) textView.getTag(); 96 | 97 | if (textView == mTopSelectedTextView) { 98 | mTopSelectedTextView = null; 99 | textView.setSelected(false); 100 | } else if (textView == mBottomSelectedTextView) { 101 | mBottomSelectedTextView = null; 102 | textView.setSelected(false); 103 | } else if (mTopGridData.contains(text)) { 104 | if (mTopSelectedTextView != null) { 105 | mTopSelectedTextView.setSelected(false); 106 | } 107 | mTopSelectedTextView = textView; 108 | textView.setSelected(true); 109 | } else { 110 | if (mBottomSelectedTextView != null) { 111 | mBottomSelectedTextView.setSelected(false); 112 | } 113 | mBottomSelectedTextView = textView; 114 | textView.setSelected(true); 115 | } 116 | } 117 | 118 | 119 | public BetterDoubleGridView setOnFilterDoneListener(OnFilterDoneListener listener) { 120 | mOnFilterDoneListener = listener; 121 | return this; 122 | } 123 | 124 | @OnClick(R.id.bt_confirm) public void clickDone() { 125 | 126 | FilterUrl.instance().doubleGridTop = mTopSelectedTextView == null ? "" : (String) mTopSelectedTextView.getTag(); 127 | FilterUrl.instance().doubleGridBottom = 128 | mBottomSelectedTextView == null ? "" : (String) mBottomSelectedTextView.getTag(); 129 | 130 | if (mOnFilterDoneListener != null) { 131 | mOnFilterDoneListener.onFilterDone(3, "", ""); 132 | } 133 | } 134 | 135 | } 136 | -------------------------------------------------------------------------------- /app/src/main/java/com/baiiu/dropdownmenu/view/betterDoubleGrid/DoubleGridAdapter.java: -------------------------------------------------------------------------------- 1 | package com.baiiu.dropdownmenu.view.betterDoubleGrid; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | 8 | import com.baiiu.dropdownmenu.view.betterDoubleGrid.holder.ItemViewHolder; 9 | import com.baiiu.dropdownmenu.view.betterDoubleGrid.holder.TitleViewHolder; 10 | 11 | import java.util.List; 12 | 13 | /** 14 | * auther: baiiu 15 | * time: 16/6/5 05 23:28 16 | * description: 17 | */ 18 | public class DoubleGridAdapter extends RecyclerView.Adapter { 19 | private static final int TYPE_TITLE = 0; 20 | private static final int TYPE_ITEM = 1; 21 | 22 | private Context mContext; 23 | private List topGridData; 24 | private List bottomGridData; 25 | private View.OnClickListener mListener; 26 | 27 | public DoubleGridAdapter(Context context, List topGridData, List bottomGridList, View.OnClickListener listener) { 28 | this.mContext = context; 29 | this.topGridData = topGridData; 30 | this.bottomGridData = bottomGridList; 31 | this.mListener = listener; 32 | } 33 | 34 | @Override 35 | public int getItemViewType(int position) { 36 | if (position == 0 || position == topGridData.size() + 1) { 37 | return TYPE_TITLE; 38 | } 39 | 40 | return TYPE_ITEM; 41 | } 42 | 43 | @Override 44 | public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 45 | RecyclerView.ViewHolder holder = null; 46 | 47 | switch (viewType) { 48 | case TYPE_TITLE: 49 | holder = new TitleViewHolder(mContext, parent); 50 | break; 51 | case TYPE_ITEM: 52 | holder = new ItemViewHolder(mContext, parent, mListener); 53 | break; 54 | } 55 | 56 | 57 | return holder; 58 | } 59 | 60 | @Override 61 | public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { 62 | int itemViewType = getItemViewType(position); 63 | switch (itemViewType) { 64 | case TYPE_TITLE: 65 | TitleViewHolder titleViewHolder = (TitleViewHolder) holder; 66 | if (position == 0) { 67 | titleViewHolder.bind("Top"); 68 | } else { 69 | titleViewHolder.bind("Bottom"); 70 | } 71 | break; 72 | case TYPE_ITEM: 73 | ItemViewHolder itemViewHolder = (ItemViewHolder) holder; 74 | if (position < topGridData.size() + 1) { 75 | itemViewHolder.bind(topGridData.get(position - 1)); 76 | } else { 77 | itemViewHolder.bind(bottomGridData.get(position - topGridData.size() - 2)); 78 | } 79 | break; 80 | } 81 | } 82 | 83 | @Override 84 | public int getItemCount() { 85 | return topGridData.size() + bottomGridData.size() + 2; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /app/src/main/java/com/baiiu/dropdownmenu/view/betterDoubleGrid/holder/ItemViewHolder.java: -------------------------------------------------------------------------------- 1 | package com.baiiu.dropdownmenu.view.betterDoubleGrid.holder; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | 8 | import com.baiiu.dropdownmenu.R; 9 | import com.baiiu.filter.util.UIUtil; 10 | import com.baiiu.filter.view.FilterCheckedTextView; 11 | 12 | import butterknife.ButterKnife; 13 | 14 | /** 15 | * auther: baiiu 16 | * time: 16/6/5 05 23:35 17 | * description: 18 | */ 19 | public class ItemViewHolder extends RecyclerView.ViewHolder { 20 | 21 | private final FilterCheckedTextView textView; 22 | private View.OnClickListener mListener; 23 | 24 | public ItemViewHolder(Context mContext, ViewGroup parent, View.OnClickListener mListener) { 25 | super(UIUtil.infalte(mContext, R.layout.holder_item, parent)); 26 | textView = ButterKnife.findById(itemView, R.id.tv_item); 27 | this.mListener = mListener; 28 | } 29 | 30 | 31 | public void bind(String s) { 32 | textView.setText(s); 33 | textView.setTag(s); 34 | textView.setOnClickListener(mListener); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/baiiu/dropdownmenu/view/betterDoubleGrid/holder/TitleViewHolder.java: -------------------------------------------------------------------------------- 1 | package com.baiiu.dropdownmenu.view.betterDoubleGrid.holder; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.view.ViewGroup; 6 | import android.widget.TextView; 7 | 8 | import com.baiiu.dropdownmenu.R; 9 | import com.baiiu.filter.util.UIUtil; 10 | 11 | /** 12 | * auther: baiiu 13 | * time: 16/6/5 05 23:30 14 | * description: 15 | */ 16 | public class TitleViewHolder extends RecyclerView.ViewHolder { 17 | 18 | public TitleViewHolder(Context mContext, ViewGroup parent) { 19 | super(UIUtil.infalte(mContext, R.layout.holder_title, parent)); 20 | } 21 | 22 | 23 | public void bind(String s) { 24 | ((TextView) itemView).setText(s); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/baiiu/dropdownmenu/view/doubleGrid/DoubleGridView.java: -------------------------------------------------------------------------------- 1 | package com.baiiu.dropdownmenu.view.doubleGrid; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.view.Gravity; 6 | import android.view.View; 7 | import android.widget.AbsListView; 8 | import android.widget.AdapterView; 9 | import android.widget.Button; 10 | import android.widget.ScrollView; 11 | import butterknife.BindView; 12 | import butterknife.ButterKnife; 13 | import com.baiiu.dropdownmenu.R; 14 | import com.baiiu.dropdownmenu.entity.FilterUrl; 15 | import com.baiiu.filter.adapter.SimpleTextAdapter; 16 | import com.baiiu.filter.interfaces.OnFilterDoneListener; 17 | import com.baiiu.filter.util.CommonUtil; 18 | import com.baiiu.filter.util.UIUtil; 19 | import com.baiiu.filter.view.FilterCheckedTextView; 20 | import java.util.List; 21 | 22 | /** 23 | * Created by baiiu on 15/12/22. 24 | * 筛选器GridView 25 | */ 26 | public class DoubleGridView extends ScrollView implements View.OnClickListener { 27 | 28 | @BindView(R.id.grid_top) GridViewInScrollView mTopGrid; 29 | @BindView(R.id.grid_bottom) GridViewInScrollView mBottomGrid; 30 | @BindView(R.id.bt_confirm) Button bt_confirm; 31 | 32 | private SimpleTextAdapter mTopAdapter; 33 | private SimpleTextAdapter mBottomAdapter; 34 | 35 | private OnFilterDoneListener onFilterDoneListener; 36 | 37 | public DoubleGridView(Context context) { 38 | this(context, null); 39 | } 40 | 41 | public DoubleGridView(Context context, AttributeSet attrs) { 42 | super(context, attrs); 43 | init(context); 44 | } 45 | 46 | private void init(Context context) { 47 | inflate(context, R.layout.merge_filter_third, this); 48 | setBackgroundResource(android.R.color.white); 49 | 50 | ButterKnife.bind(this, this); 51 | 52 | bt_confirm.setOnClickListener(this); 53 | 54 | initAdapter(context); 55 | 56 | mTopGrid.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE); 57 | mBottomGrid.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE); 58 | 59 | mTopGrid.setAdapter(mTopAdapter); 60 | mBottomGrid.setAdapter(mBottomAdapter); 61 | } 62 | 63 | private void initAdapter(Context context) { 64 | 65 | mTopAdapter = new SimpleTextAdapter(null, context) { 66 | @Override public String provideText(String phase) { 67 | return phase; 68 | } 69 | 70 | @Override protected void initCheckedTextView(FilterCheckedTextView checkedTextView) { 71 | checkedTextView.setPadding(0, UIUtil.dp(context, 3), 0, UIUtil.dp(context, 3)); 72 | checkedTextView.setGravity(Gravity.CENTER); 73 | checkedTextView.setBackgroundResource(R.drawable.selector_filter_grid); 74 | } 75 | }; 76 | 77 | mBottomAdapter = new SimpleTextAdapter(null, context) { 78 | @Override public String provideText(String area) { 79 | return area; 80 | } 81 | 82 | @Override protected void initCheckedTextView(FilterCheckedTextView checkedTextView) { 83 | checkedTextView.setPadding(0, UIUtil.dp(context, 3), 0, UIUtil.dp(context, 3)); 84 | checkedTextView.setBackgroundResource(R.drawable.selector_filter_grid); 85 | checkedTextView.setGravity(Gravity.CENTER); 86 | } 87 | }; 88 | 89 | mTopGrid.setOnItemClickListener(new AdapterView.OnItemClickListener() { 90 | @Override public void onItemClick(AdapterView parent, View view, int position, long id) { 91 | } 92 | }); 93 | } 94 | 95 | public void setTopGridData(List list) { 96 | if (CommonUtil.isEmpty(list)) { 97 | return; 98 | } 99 | 100 | mTopAdapter.setList(list); 101 | } 102 | 103 | public void setBottomGridList(List list) { 104 | if (CommonUtil.isEmpty(list)) { 105 | return; 106 | } 107 | 108 | mBottomAdapter.setList(list); 109 | } 110 | 111 | @Override public void onClick(View v) { 112 | int topPosition = mTopGrid.getCheckedItemPosition(); 113 | topPosition = topPosition == -1 ? 0 : topPosition; 114 | 115 | int bottomPosition = mBottomGrid.getCheckedItemPosition(); 116 | bottomPosition = bottomPosition == -1 ? 0 : bottomPosition; 117 | 118 | String financePhase = mTopAdapter.getItem(topPosition); 119 | String area = mBottomAdapter.getItem(bottomPosition); 120 | 121 | FilterUrl.instance().doubleGridTop = financePhase; 122 | FilterUrl.instance().doubleGridBottom = area; 123 | 124 | if (onFilterDoneListener != null) { 125 | onFilterDoneListener.onFilterDone(3, "", ""); 126 | } 127 | } 128 | 129 | public void setOnFilterDoneListener(OnFilterDoneListener listener) { 130 | onFilterDoneListener = listener; 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /app/src/main/java/com/baiiu/dropdownmenu/view/doubleGrid/GridViewInScrollView.java: -------------------------------------------------------------------------------- 1 | package com.baiiu.dropdownmenu.view.doubleGrid; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.widget.GridView; 6 | 7 | /** 8 | * 描述:嵌套在ScrollView中的GridView,使得数据完全展示 9 | */ 10 | public class GridViewInScrollView extends GridView { 11 | 12 | public GridViewInScrollView(Context context) { 13 | super(context); 14 | } 15 | 16 | public GridViewInScrollView(Context context, AttributeSet attrs) { 17 | super(context, attrs); 18 | } 19 | 20 | public GridViewInScrollView(Context context, AttributeSet attrs, int defStyleAttr) { 21 | super(context, attrs, defStyleAttr); 22 | } 23 | 24 | @Override 25 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 26 | if (isInEditMode()) { 27 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 28 | return; 29 | } 30 | 31 | int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); 32 | super.onMeasure(widthMeasureSpec, expandSpec); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/news_article_icon_gray_line_4.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/rect_blue_stroke.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/rect_grey_stroke.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_double_grid.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_filter_grid.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 15 | 16 | 21 | 22 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /app/src/main/res/layout/holder_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/layout/holder_title.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/layout/merge_filter_double_grid.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 13 | 14 | 15 |