├── .gitignore
├── .idea
├── codeStyles
│ └── Project.xml
├── gradle.xml
├── misc.xml
├── runConfigurations.xml
└── vcs.xml
├── LICENSE
├── README.md
├── README_1.x.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── cn
│ │ └── mtjsoft
│ │ └── www
│ │ └── gridviewpager
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── cn
│ │ │ └── mtjsoft
│ │ │ └── www
│ │ │ └── gridviewpager
│ │ │ ├── CoordinatorActivity.java
│ │ │ ├── ListActivity.java
│ │ │ ├── ListAdapter.java
│ │ │ └── MainActivity.java
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ ├── ic_arrow_white_24dp.xml
│ │ ├── ic_launcher_background.xml
│ │ └── ic_launcher_background_red.xml
│ │ ├── layout
│ │ ├── activity_coordinatorlayout.xml
│ │ ├── activity_list.xml
│ │ ├── activity_main.xml
│ │ └── item_text.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_category_0.png
│ │ ├── ic_category_1.png
│ │ ├── ic_category_10.png
│ │ ├── ic_category_11.png
│ │ ├── ic_category_12.png
│ │ ├── ic_category_13.png
│ │ ├── ic_category_14.png
│ │ ├── ic_category_15.png
│ │ ├── ic_category_16.png
│ │ ├── ic_category_17.png
│ │ ├── ic_category_18.png
│ │ ├── ic_category_19.png
│ │ ├── ic_category_2.png
│ │ ├── ic_category_20.png
│ │ ├── ic_category_21.png
│ │ ├── ic_category_22.png
│ │ ├── ic_category_23.png
│ │ ├── ic_category_24.png
│ │ ├── ic_category_25.png
│ │ ├── ic_category_26.png
│ │ ├── ic_category_27.png
│ │ ├── ic_category_28.png
│ │ ├── ic_category_29.png
│ │ ├── ic_category_3.png
│ │ ├── ic_category_30.png
│ │ ├── ic_category_31.png
│ │ ├── ic_category_32.png
│ │ ├── ic_category_33.png
│ │ ├── ic_category_4.png
│ │ ├── ic_category_5.png
│ │ ├── ic_category_6.png
│ │ ├── ic_category_7.png
│ │ ├── ic_category_8.png
│ │ ├── ic_category_9.png
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── cn
│ └── mtjsoft
│ └── www
│ └── gridviewpager
│ └── ExampleUnitTest.java
├── build.gradle
├── gif.gif
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── gridviewpager_recycleview
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── cn
│ │ └── mtjsoft
│ │ └── www
│ │ └── gridviewpager_recycleview
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── cn
│ │ │ └── mtjsoft
│ │ │ └── www
│ │ │ └── gridviewpager_recycleview
│ │ │ ├── GridViewPager.java
│ │ │ ├── transformer
│ │ │ ├── CoverPageTransformer.java
│ │ │ ├── GalleryPageTransformer.java
│ │ │ └── TopOrDownPageTransformer.java
│ │ │ └── view
│ │ │ ├── AndDensityUtils.java
│ │ │ └── AndSelectCircleView.java
│ └── res
│ │ ├── layout
│ │ ├── gridpager_item.xml
│ │ ├── gridpager_item_layout.xml
│ │ ├── gridpager_item_text.xml
│ │ └── gridpager_layout.xml
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ └── values
│ │ ├── attrs.xml
│ │ └── strings.xml
│ └── test
│ └── java
│ └── cn
│ └── mtjsoft
│ └── www
│ └── gridviewpager_recycleview
│ └── ExampleUnitTest.java
├── settings.gradle
├── show.mp4
└── wxqrcode.jpg
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches/build_file_checksums.ser
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | .DS_Store
9 | /build
10 | /captures
11 | .externalNativeBuild
12 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | xmlns:android
11 |
12 | ^$
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | xmlns:.*
22 |
23 | ^$
24 |
25 |
26 | BY_NAME
27 |
28 |
29 |
30 |
31 |
32 |
33 | .*:id
34 |
35 | http://schemas.android.com/apk/res/android
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | .*:name
45 |
46 | http://schemas.android.com/apk/res/android
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | name
56 |
57 | ^$
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | style
67 |
68 | ^$
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | .*
78 |
79 | ^$
80 |
81 |
82 | BY_NAME
83 |
84 |
85 |
86 |
87 |
88 |
89 | .*
90 |
91 | http://schemas.android.com/apk/res/android
92 |
93 |
94 | ANDROID_ATTRIBUTE_ORDER
95 |
96 |
97 |
98 |
99 |
100 |
101 | .*
102 |
103 | .*
104 |
105 |
106 | BY_NAME
107 |
108 |
109 |
110 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
20 |
21 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/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 2019-2021 mtjsoft
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.md:
--------------------------------------------------------------------------------
1 |
2 | # GridViewPager3.x
3 |
4 | GridViewPager3.0组件:采用RecycleView + FlexBoxLayout + PagerSnapHelper实现方式,轻松实现类似美团首页分类多页展示。也可用于表情面板的展示。
5 | 链式调用,属性配置,几行代码轻松搞定。
6 |
7 | v3.3.0 开始采用 viewpager2 + FlexBoxLayout 实现
8 |
9 | ① 应用的首页经常需要用到这样的分类**多页展示**的效果,还有些消息输入框需要这样的**表情面板**。
10 |
11 | ② 既然是常用的,作为懒惰的我,肯定不会每次都去写一遍。网上也找了很多类似的例子,但始终不是我想要的**简洁接入**使用的方式。要么就是加载图片有限制,要么就是样式限制的太死,还得改源码,我不喜欢,我得造一个轮子。。。必须封装一个简单好用的组件,做到几行代码就可实现效果才行。于是乎,**GridViewPager组件**就诞生了。
12 |
13 | # GridViewPager组件效果
14 |
15 | 
16 |
17 | # 内置了3个覆盖翻页的效果(这是其中一)
18 |
19 | 
20 |
21 | # 如何使用GridViewPager组件
22 |
23 | # 1、在根目录 build.gradle 添加:
24 |
25 | ```
26 | allprojects {
27 | repositories {
28 | ...
29 | maven { url 'https://jitpack.io' }
30 | }
31 | }
32 | ```
33 |
34 | # 2、在app项目下的build.gradle中添加:
35 |
36 | [](https://jitpack.io/#mtjsoft/GridPager)
37 |
38 | ```
39 | dependencies {
40 | implementation 'com.github.mtjsoft:GridPager:v3.7.0'
41 | }
42 | ```
43 |
44 |
45 | # 3、在需要使用的布局xml中添加GridViewPager组件,根据需要设置相关属性
46 |
47 | ```
48 |
73 |
74 |
75 |
80 |
81 | ```
82 | # 4、GridViewPager组件的版本及属性说明
83 |
84 | V3.7.0
85 | --------------------------
86 | 新增方法 setAlignContent() 设置Item行的对齐方式。等同FLEX布局的AlignContent,可设置以下6个值:
87 | ```
88 | AlignContent.FLEX_START //(默认值)
89 | AlignContent.FLEX_END
90 | AlignContent.CENTER
91 | AlignContent.SPACE_BETWEEN
92 | AlignContent.SPACE_AROUND
93 | AlignContent.STRETCH
94 | ```
95 | 新增属性 | 属性说明
96 | ------------- | -------------
97 | text_is_show | 是否需要显示文本,默认true显示(一般作为表情面板时,可以直接设置false不显示)。也可通过方法setIsShowText()设置
98 |
99 | V3.6.0
100 | --------------------------
101 |
102 | 新增方法 setGridItemLongClickListener() 设置Item长按监听
103 |
104 | 3.6.0 新增属性 | 属性说明
105 | ------------- | -------------
106 | pager_loop | 是否开启无限循环滑动 默认 false 不开启
107 |
108 | V3.5.0
109 | --------------------------
110 | 修复已知问题
111 |
112 | 新增 setTopOrDownPageTransformer(TopOrDownPageTransformer.ModeType.MODE_DOWN)方法,设置内置的上下进入翻页效果
113 |
114 | 新增 setGalleryPageTransformer()方法,设置内置的画廊翻页效果
115 |
116 | V3.4.0
117 | --------------------------
118 | 修复已知问题
119 |
120 | 新增 setCoverPageTransformer()方法,设置内置的覆盖渐变翻页效果
121 |
122 | 新增 setCustomPageTransformer()方法,用于设置自定义的翻页效果
123 |
124 | V3.3.0
125 | --------------------------
126 | 更换 viewpager2 + FlexBoxLayout 实现
127 |
128 | V3.2.0
129 | --------------------------
130 | 修复已知问题
131 |
132 | V3.1.0
133 | --------------------------
134 | 修复布局设置margin显示不全的问题
135 |
136 |
137 | V3.0.0
138 | --------------------------
139 |
140 | 3.0.0 属性 | 属性说明
141 | ------------- | -------------
142 | pager_MarginTop | 设置每页的上边距 默认10dp 单位dp
143 | pager_MarginBottom | 设置每页的下边距 默认10dp 单位dp
144 | verticalSpacing | 设置item的纵向间距 默认10dp 单位dp
145 | img_width | 设置图片宽度 默认50dp 单位dp
146 | img_height | 设置图片高度 默认50dp 单位dp
147 | text_color | 设置文字颜色 默认黑色
148 | imgtext_margin | 设置文字与图片的间距 默认5dp 单位dp
149 | text_size | 设置文字大小 默认10sp 单位sp
150 | row_count | 设置每页行数 默认2
151 | column_count | 设置每页列数 默认4
152 | point_is_show | 是否展示指示器,默认true展示
153 | point_width | 设置指示器的item宽度 默认8dp 单位dp
154 | point_height | 设置指示器的item高度 默认8dp 单位dp
155 | point_margin | 设置指示器的item的间距 默认8dp 单位dp
156 | point_normal_color | 指示器item未选中的颜色 默认灰色
157 | point_select_color | 指示器item选中的颜色 默认红色
158 | point_is_circle | 指示器的item是否为圆形,默认圆形直径取宽高的最小值
159 | point_margin_page | 设置指示器与page的间距,默认是verticalSpacing的值
160 | point_margin_bottom | 设置指示器与底部的间距,默认是verticalSpacing的值
161 | background_color | 设置组件背景颜色,默认白色
162 | notifyItemChanged(int position) | 刷新指定页数据
163 |
164 |
165 | # 5、代码实现。链式调用,只需要设置总数量即可。数据绑定完全自定义,不受任何图片加载框架限制,更加自由。
166 |
167 | ```
168 | GridViewPager gridViewPager = findViewById(R.id.gridviewpager);
169 | gridViewPager
170 | // 设置数据总数量
171 | .setDataAllCount(titles.length)
172 | // 设置背景图片(此时设置的背景色无效,以背景图片为主)
173 | .setBackgroundImageLoader(new GridViewPager.BackgroundImageLoaderInterface() {
174 | @Override
175 | public void setBackgroundImg(ImageView bgImageView) {
176 | bgImageView.setImageResource(R.drawable.ic_launcher_background);
177 | }
178 | })
179 | // 数据绑定
180 | .setImageTextLoaderInterface(new GridViewPager.ImageTextLoaderInterface() {
181 | @Override
182 | public void displayImageText(ImageView imageView, TextView textView, int position) {
183 | // 自己进行数据的绑定,灵活度更高,不受任何限制
184 | imageView.setImageResource(iconS[position]);
185 | textView.setText(titles[position]);
186 | }
187 | })
188 | // Item点击
189 | .setGridItemClickListener(new GridViewPager.GridItemClickListener() {
190 | @Override
191 | public void click(int position) {
192 | Toast.makeText(getBaseContext(), "点击了" + titles[position] + position, Toast.LENGTH_SHORT).show();
193 | }
194 | })
195 | .show();
196 | ```
197 |
198 | # 6、代码中也可直接设置属性(如果xml与代码都设置了, 最终以代码设置为准)
199 |
200 | ```
201 | GridViewPager gridViewPager2 = findViewById(R.id.gridviewpager2);
202 | gridViewPager2
203 | // 设置数据总数量
204 | .setDataAllCount(titles.length)
205 | // 设置背景色,默认白色
206 | .setGridViewPagerBackgroundColor(ContextCompat.getColor(getBaseContext(), R.color.white))
207 | // 设置item的纵向间距
208 | .setVerticalSpacing(10)
209 | // 设置上边距
210 | .setPagerMarginTop(10)
211 | // 设置下边距
212 | .setPagerMarginBottom(10)
213 | // 设置图片宽度
214 | .setImageWidth(50)
215 | // 设置图片高度
216 | .setImageHeight(50)
217 | // 设置文字与图片的间距
218 | .setTextImgMargin(5)
219 | // 设置文字颜色
220 | .setTextColor(ContextCompat.getColor(getBaseContext(), R.color.white))
221 | // 设置文字大小
222 | .setTextSize(12)
223 | // 设置每页行数
224 | .setRowCount(2)
225 | // 设置每页列数
226 | .setColumnCount(5)
227 | // 设置无限循环
228 | .setPageLoop(true)
229 | // 设置是否显示指示器
230 | .setPointIsShow(true)
231 | // 设置指示器与page的间距
232 | .setPointMarginPage(10)
233 | // 设置指示器与底部的间距
234 | .setPointMarginBottom(10)
235 | // 设置指示器的item宽度
236 | .setPointChildWidth(8)
237 | // 设置指示器的item高度
238 | .setPointChildHeight(8)
239 | // 设置指示器的item的间距
240 | .setPointChildMargin(8)
241 | // 指示器的item是否为圆形,默认圆形直径取宽高的最小值
242 | .setPointIsCircle(true)
243 | // 指示器item未选中的颜色
244 | .setPointNormalColor(ContextCompat.getColor(getBaseContext(), R.color.white))
245 | // 指示器item选中的颜色
246 | .setPointSelectColor(ContextCompat.getColor(getBaseContext(), R.color.black_text))
247 | // 设置背景图片(此时设置的背景色无效,以背景图片为主)
248 | .setBackgroundImageLoader(new GridViewPager.BackgroundImageLoaderInterface() {
249 | @Override
250 | public void setBackgroundImg(ImageView bgImageView) {
251 | bgImageView.setImageResource(R.drawable.ic_launcher_background_red);
252 | }
253 | })
254 | // 数据绑定
255 | .setImageTextLoaderInterface(new GridViewPager.ImageTextLoaderInterface() {
256 | @Override
257 | public void displayImageText(ImageView imageView, TextView textView, int position) {
258 | // 自己进行数据的绑定,灵活度更高,不受任何限制
259 | imageView.setImageResource(iconS[position]);
260 | textView.setText(titles[position]);
261 | }
262 | })
263 | // Item点击
264 | .setGridItemClickListener(new GridViewPager.GridItemClickListener() {
265 | @Override
266 | public void click(int position) {
267 | Toast.makeText(getBaseContext(), "点击了" + titles[position] + position, Toast.LENGTH_SHORT).show();
268 | }
269 | })
270 | // 设置Item长按
271 | .setGridItemLongClickListener(new GridViewPager.GridItemLongClickListener() {
272 | @Override
273 | public void longClick(int position) {
274 | Toast.makeText(getBaseContext(), "长按了" + titles[position].split("_")[0], Toast.LENGTH_SHORT).show();
275 | }
276 | })
277 | .show();
278 | ```
279 | # 7、刷新数据
280 |
281 | **设置新属性,刷新**
282 |
283 | ```
284 | gridViewPager
285 | // 数据大小有变化时,得设置
286 | .setDataAllCount(titles.length)
287 | // 动态改变其他属性
288 | .setRowCount(3)
289 | .setColumnCount(3)
290 | // 再次show(),gridViewPager不为空时,走notifyDataSetChanged()刷新数据
291 | .show();
292 | ```
293 |
294 | **刷新指定页码数据(每页行列数、数据总数不变,只有某个数据的值改变时使用)**
295 |
296 | ```
297 | // 页码从0开始,例如下面是只刷新第二页数据
298 | gridViewPager.notifyItemChanged(1)
299 | ```
300 |
301 | ## 实现就是如此简单
302 |
303 | **添加我个人微信号交流,记得添加时备注一下哦**
304 |
305 | 
306 |
307 | **本人公众号,也可关注一波,共同交流吧。**
308 |
309 | 
310 |
311 |
--------------------------------------------------------------------------------
/README_1.x.md:
--------------------------------------------------------------------------------
1 |
2 | # GridPager
3 |
4 | GridPager组件:ViewPager结合GridView,轻松实现类似美团首页分类多页展示。也可用于表情面板的展示。
5 | 链式调用,属性配置,几行代码轻松搞定。
6 |
7 | ① 应用的首页经常需要用到这样的分类**多页展示**的效果,还有些消息输入框需要这样的**表情面板**。
8 |
9 | ② 既然是常用的,作为懒惰的我,肯定不会每次都去写一遍。网上也找了很多类似的例子,但始终不是我想要的**简洁接入**使用的方式。要么就是加载图片有限制,要么就是样式限制的太死,还得改源码,我不喜欢,我得造一个轮子。。。必须封装一个简单好用的组件,做到几行代码就可实现效果才行。于是乎,**GridPager组件**就诞生了。
10 |
11 | # GridPager组件效果
12 |
13 | 
14 |
15 | # 如何使用GridPager组件
16 |
17 | # 1、在根目录 build.gradle 添加:
18 |
19 | ```
20 | allprojects {
21 | repositories {
22 | ...
23 | maven { url 'https://jitpack.io' }
24 | }
25 | }
26 | ```
27 |
28 | # 2、在app项目下的build.gradle中添加:
29 |
30 | ```
31 | dependencies {
32 | implementation 'com.github.mtjsoft:GridPager:v1.3.2'
33 | }
34 | ```
35 |
36 |
37 | # 3、在需要使用的布局xml中添加GridPager组件,根据需要设置相关属性
38 |
39 | ```
40 |
62 |
63 | ```
64 | # 4、GridPager组件的版本及属性说明
65 |
66 | V1.3.2
67 | --------------------------
68 |
69 | 新增方法 | 属性说明 | 备注
70 | ------------- | ------------- | -------------
71 | setGridPagersetBackgroundImage() | 支持设置背景图片,不再是单一的背景颜色了 | 2019-11-8 17:52:08
72 |
73 | V1.3.1
74 | --------------------------
75 |
76 | 说明 | 备注
77 | ------------- | -------------
78 | 优化自动计算高度方法。不手动设置setViewPageHeight()固定高度时,默认自动计算,自适应高度。 | 2019-9-28 20:48:57
79 |
80 | V1.2.2
81 | --------------------------
82 |
83 | 新增方法 | 属性说明 | 备注
84 | ------------- | ------------- | -------------
85 | setViewPageHeight(152) | 手动设置ViewPager为固定的高度,单位dp。 | 2019-9-27 17:47:31
86 |
87 | V1.2.1
88 | --------------------------
89 |
90 | 新增属性 | 属性说明 | 备注
91 | ------------- | ------------- | -------------
92 | background_color | 设置组件背景颜色,默认白色 | 2019-9-23 22:20:05
93 |
94 | V1.2.0
95 | --------------------------
96 |
97 | 新增属性 | 属性说明 | 备注
98 | ------------- | ------------- | -------------
99 | point_margin_page | 设置指示器与page的间距,默认是verticalSpacing的值 | 2019-9-11 13:20:45
100 | point_margin_bottom | 设置指示器与底部的间距,默认是verticalSpacing的值
101 | point_is_show | 是否展示指示器,默认true展示
102 |
103 | V1.1.0
104 | --------------------------
105 |
106 | 1.1.0 属性 | 属性说明 | 备注
107 | ------------- | ------------- | -------------
108 | verticalSpacing | 设置item的纵向间距 默认10dp 单位dp | 2019-8-22 16:09:55
109 | img_width | 设置图片宽度 默认50dp 单位dp
110 | img_height | 设置图片高度 默认50dp 单位dp
111 | text_color | 设置文字颜色 默认黑色
112 | imgtext_margin | 设置文字与图片的间距 默认5dp 单位dp
113 | text_size | 设置文字大小 默认10sp 单位sp
114 | row_count | 设置每页行数 默认2
115 | column_count | 设置每页列数 默认4
116 | point_width | 设置指示器的item宽度 默认8dp 单位dp
117 | point_height | 设置指示器的item高度 默认8dp 单位dp
118 | point_margin | 设置指示器的item的间距 默认8dp 单位dp
119 | point_normal_color | 指示器item未选中的颜色 默认灰色
120 | point_select_color | 指示器item选中的颜色 默认红色
121 | point_is_circle | 指示器的item是否为圆形,默认圆形直径取宽高的最小值
122 |
123 |
124 | # 5、代码实现。链式调用,只需要设置总数量即可。数据绑定完全自定义,不受任何图片加载框架限制,更加自由。
125 |
126 | ```
127 | GridPager gridPager = findViewById(R.id.gridpager);
128 | gridPager
129 | // 设置数量总条数
130 | .setDataAllCount(titles.length)
131 | // 数据绑定
132 | .setItemBindDataListener(new GridPager.ItemBindDataListener() {
133 | @Override
134 | public void BindData(ImageView imageView, TextView textView, int position) {
135 | // 自己进行数据的绑定,灵活度更高,不受任何限制
136 | imageView.setImageResource(iconS[position]);
137 | textView.setText(titles[position]);
138 | }
139 | })
140 | // Item点击
141 | .setGridItemClickListener(new GridPager.GridItemClickListener() {
142 | @Override
143 | public void click(int position) {
144 | Toast.makeText(getBaseContext(), "点击了" + titles[position], Toast.LENGTH_SHORT).show();
145 | }
146 | })
147 | .show();
148 | ```
149 |
150 | # 6、代码中也可直接设置属性(如果xml与代码都设置了, 最终以代码设置为准)
151 |
152 | ```
153 | gridPager
154 | // 设置数量总条数
155 | .setDataAllCount(titles.length)
156 | // 设置背景图片(有背景图片时,设置背景颜色无效,采用的Glide加载)
157 | .setGridPagersetBackgroundImage("https://huilife.api.luoyangzixun.cn/XiaoFile/index-miandan-bg.png")
158 | // 手动设置ViewPager为固定的高度,单位dp。(可以不设置,默认是自动计算高度)
159 | //.setViewPageHeight(152)
160 | // 设置背景色,默认白色
161 | .setGridPagerBackgroundColor(ContextCompat.getColor(getBaseContext(),R.color.colorBg))
162 | // 设置item的纵向间距
163 | .setVerticalSpacing(20)
164 | // 设置图片宽度
165 | .setImageWidth(80)
166 | // 设置图片高度
167 | .setImageHeight(80)
168 | // 设置文字与图片的间距
169 | .setTextImgMargin(10)
170 | // 设置文字颜色
171 | .setTextColor(ContextCompat.getColor(getBaseContext(),R.color.colorPrimaryDark))
172 | // 设置文字大小
173 | .setTextSize(12)
174 | // 设置每页行数
175 | .setRowCount(2)
176 | // 设置每页列数
177 | .setColumnCount(4)
178 | // 设置是否显示指示器
179 | .setPointIsShow(true)
180 | // 设置指示器与page的间距
181 | .setPointMarginPage(10)
182 | // 设置指示器与底部的间距
183 | .setPointMarginBottom(10)
184 | // 设置指示器的item宽度
185 | .setPointChildWidth(15)
186 | // 设置指示器的item高度
187 | .setPointChildHeight(3)
188 | // 设置指示器的item的间距
189 | .setPointChildMargin(5)
190 | // 指示器的item是否为圆形,默认圆形直径取宽高的最小值
191 | .setPointIsCircle(false)
192 | // 指示器item未选中的颜色
193 | .setPointNormalColor(ContextCompat.getColor(getBaseContext(),R.color.colorPrimary))
194 | // 指示器item选中的颜色
195 | .setPointSelectColor(ContextCompat.getColor(getBaseContext(),R.color.colorAccent))
196 | // 数据绑定
197 | .setItemBindDataListener(new GridPager.ItemBindDataListener() {
198 | @Override
199 | public void BindData(ImageView imageView, TextView textView, int position) {
200 | // 自己进行数据的绑定,灵活度更高,不受任何限制
201 | imageView.setImageResource(iconS[position]);
202 | textView.setText(titles[position]);
203 | }
204 | })
205 | // Item点击
206 | .setGridItemClickListener(new GridPager.GridItemClickListener() {
207 | @Override
208 | public void click(int position) {
209 | Toast.makeText(getBaseContext(), "点击了" + titles[position], Toast.LENGTH_SHORT).show();
210 | }
211 | })
212 | .show();
213 | ```
214 | ## 实现就是如此简单
215 |
216 | **添加我个人微信号交流,记得添加时备注一下哦**
217 |
218 |
219 |
220 | **本人公众号,也可关注一波,共同交流吧。**
221 |
222 | 
223 |
224 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 28
5 | buildToolsVersion "28.0.2"
6 | defaultConfig {
7 | applicationId "cn.mtjsoft.www.gridviewpager"
8 | minSdkVersion 19
9 | targetSdkVersion 28
10 | versionCode 1
11 | versionName "1.0"
12 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | implementation fileTree(include: ['*.jar'], dir: 'libs')
24 | implementation 'androidx.appcompat:appcompat:1.1.0'
25 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
26 | implementation 'com.google.android.material:material:1.1.0'
27 | implementation 'androidx.legacy:legacy-support-v4:1.0.0'
28 | testImplementation 'junit:junit:4.12'
29 | androidTestImplementation 'androidx.test.ext:junit:1.1.1'
30 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
31 | implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.4'
32 | implementation project(':gridviewpager_recycleview')
33 | // implementation 'com.github.mtjsoft:GridPager:v3.4.0'
34 | }
35 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/cn/mtjsoft/www/gridviewpager/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package cn.mtjsoft.www.gridviewpager;
2 |
3 | import android.content.Context;
4 |
5 | import org.junit.Test;
6 | import org.junit.runner.RunWith;
7 |
8 | import androidx.test.InstrumentationRegistry;
9 | import androidx.test.runner.AndroidJUnit4;
10 |
11 | import static org.junit.Assert.*;
12 |
13 | /**
14 | * Instrumented test, which will execute on an Android device.
15 | *
16 | * @see Testing documentation
17 | */
18 | @RunWith(AndroidJUnit4.class)
19 | public class ExampleInstrumentedTest {
20 | @Test
21 | public void useAppContext() {
22 | // Context of the app under test.
23 | Context appContext = InstrumentationRegistry.getTargetContext();
24 |
25 | assertEquals("cn.mtjsoft.www.gridviewpager", appContext.getPackageName());
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/mtjsoft/www/gridviewpager/CoordinatorActivity.java:
--------------------------------------------------------------------------------
1 | package cn.mtjsoft.www.gridviewpager;
2 |
3 | import android.content.Context;
4 | import android.os.Bundle;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.ImageView;
9 | import android.widget.TextView;
10 | import android.widget.Toast;
11 |
12 | import androidx.annotation.NonNull;
13 | import androidx.annotation.Nullable;
14 | import androidx.appcompat.app.AppCompatActivity;
15 | import androidx.recyclerview.widget.RecyclerView;
16 | import androidx.viewpager2.widget.ViewPager2;
17 |
18 | import cn.mtjsoft.www.gridviewpager_recycleview.GridViewPager;
19 |
20 | public class CoordinatorActivity extends AppCompatActivity {
21 |
22 | private String[] titles = {"美食", "电影", "酒店住宿", "休闲娱乐", "外卖", "自助餐", "KTV", "机票/火车票", "周边游", "美甲美睫",
23 | "火锅", "生日蛋糕", "甜品饮品", "水上乐园", "汽车服务", "美发", "丽人", "景点", "足疗按摩", "运动健身", "健身", "超市", "买菜",
24 | "今日新单", "小吃快餐", "面膜", "洗浴/汗蒸", "母婴亲子", "生活服务", "婚纱摄影", "学习培训", "家装", "结婚", "全部分配"};
25 |
26 | private int[] iconS = new int[titles.length];
27 |
28 | @Override
29 | protected void onCreate(@Nullable Bundle savedInstanceState) {
30 | super.onCreate(savedInstanceState);
31 | setContentView(R.layout.activity_coordinatorlayout);
32 | initData();
33 | GridViewPager gridViewPager2 = findViewById(R.id.gridviewpager2);
34 | gridViewPager2
35 | // 设置数据总数量
36 | .setDataAllCount(titles.length)
37 | // 设置内置的覆盖翻页效果
38 | .setCoverPageTransformer()
39 | // 数据绑定
40 | .setImageTextLoaderInterface(new GridViewPager.ImageTextLoaderInterface() {
41 | @Override
42 | public void displayImageText(ImageView imageView, TextView textView, int position) {
43 | // 自己进行数据的绑定,灵活度更高,不受任何限制
44 | imageView.setImageResource(iconS[position]);
45 | textView.setText(titles[position]);
46 | }
47 | })
48 | // Item点击
49 | .setGridItemClickListener(new GridViewPager.GridItemClickListener() {
50 | @Override
51 | public void click(int position) {
52 | Toast.makeText(getBaseContext(), "点击了" + titles[position] + position, Toast.LENGTH_SHORT).show();
53 | }
54 | })
55 | .show();
56 | ViewPager2 viewPager2 = findViewById(R.id.viewPager);
57 | viewPager2.setAdapter(new PagerAdapter(getBaseContext()));
58 | }
59 |
60 | private class PagerAdapter extends RecyclerView.Adapter {
61 | private Context context;
62 |
63 | public PagerAdapter(Context context) {
64 | this.context = context;
65 | }
66 |
67 | @NonNull
68 | @Override
69 | public PagerAdapter.Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
70 | View view = LayoutInflater.from(context).inflate(R.layout.item_text, parent, false);
71 | ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
72 | view.setLayoutParams(lp);
73 | return new PagerAdapter.Holder(view);
74 | }
75 |
76 | @Override
77 | public void onBindViewHolder(@NonNull PagerAdapter.Holder holder, int position) {
78 | holder.textView.setText("ViewPager_" + (position + 1));
79 | }
80 |
81 | @Override
82 | public int getItemCount() {
83 | return 10;
84 | }
85 |
86 | public class Holder extends RecyclerView.ViewHolder {
87 | private TextView textView;
88 |
89 | public Holder(@NonNull View itemView) {
90 | super(itemView);
91 | textView = itemView.findViewById(R.id.tv_name);
92 | }
93 | }
94 | }
95 |
96 | /**
97 | * 初始化数据源,这里使用本地图标作为示例
98 | */
99 | private void initData() {
100 | for (int i = 0; i < titles.length; i++) {
101 | //动态获取资源ID,第一个参数是资源名,第二个参数是资源类型例如drawable,string等,第三个参数包名
102 | int imageId = getResources().getIdentifier("ic_category_" + i, "mipmap", getPackageName());
103 | iconS[i] = imageId;
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/mtjsoft/www/gridviewpager/ListActivity.java:
--------------------------------------------------------------------------------
1 | package cn.mtjsoft.www.gridviewpager;
2 |
3 | import android.os.Bundle;
4 | import android.widget.ImageView;
5 | import android.widget.TextView;
6 | import android.widget.Toast;
7 |
8 | import java.util.Arrays;
9 |
10 | import androidx.annotation.Nullable;
11 | import androidx.appcompat.app.AppCompatActivity;
12 | import androidx.core.content.ContextCompat;
13 | import androidx.recyclerview.widget.LinearLayoutManager;
14 | import androidx.recyclerview.widget.RecyclerView;
15 | import cn.mtjsoft.www.gridviewpager_recycleview.GridViewPager;
16 |
17 | public class ListActivity extends AppCompatActivity {
18 |
19 | private String[] datas = {"美食", "电影", "酒店住宿", "休闲娱乐", "外卖", "自助餐", "KTV", "机票/火车票", "周边游", "美甲美睫",
20 | "火锅", "生日蛋糕", "甜品饮品", "水上乐园", "汽车服务", "美发", "丽人", "景点", "足疗按摩", "运动健身", "健身", "超市", "买菜",
21 | "今日新单", "小吃快餐", "面膜", "洗浴/汗蒸", "母婴亲子", "生活服务", "婚纱摄影", "学习培训", "家装", "结婚", "全部分配"};
22 |
23 | private int[] iconS = new int[datas.length];
24 |
25 | @Override
26 | protected void onCreate(@Nullable Bundle savedInstanceState) {
27 | super.onCreate(savedInstanceState);
28 | setContentView(R.layout.activity_list);
29 |
30 | RecyclerView recyclerView = findViewById(R.id.rlv);
31 | recyclerView.setLayoutManager(new LinearLayoutManager(getBaseContext()));
32 |
33 | for (int i = 0; i < datas.length; i++) {
34 | //动态获取资源ID,第一个参数是资源名,第二个参数是资源类型例如drawable,string等,第三个参数包名
35 | int imageId = getResources().getIdentifier("ic_category_" + i, "mipmap", getPackageName());
36 | iconS[i] = imageId;
37 | }
38 |
39 |
40 | ListAdapter adapter = new ListAdapter(Arrays.asList(datas));
41 | adapter.addHeaderView(getGridViewPager());
42 | recyclerView.setAdapter(adapter);
43 | }
44 |
45 |
46 | private GridViewPager getGridViewPager(){
47 | GridViewPager gridViewPager = new GridViewPager(getBaseContext());
48 | gridViewPager
49 | // 设置数据总数量
50 | .setDataAllCount(datas.length)
51 | // 设置背景色,默认白色
52 | .setGridViewPagerBackgroundColor(ContextCompat.getColor(getBaseContext(), R.color.white))
53 | // 设置item的纵向间距
54 | .setVerticalSpacing(10)
55 | // 设置上边距
56 | .setPagerMarginTop(10)
57 | // 设置下边距
58 | .setPagerMarginBottom(10)
59 | // 设置图片宽度
60 | .setImageWidth(50)
61 | // 设置图片高度
62 | .setImageHeight(50)
63 | // 设置文字与图片的间距
64 | .setTextImgMargin(5)
65 | // 设置文字颜色
66 | .setTextColor(ContextCompat.getColor(getBaseContext(), R.color.white))
67 | // 设置文字大小
68 | .setTextSize(12)
69 | // 设置每页行数
70 | .setRowCount(3)
71 | // 设置每页列数
72 | .setColumnCount(3)
73 | // 设置是否显示指示器
74 | .setPointIsShow(true)
75 | // 设置指示器与page的间距
76 | .setPointMarginPage(10)
77 | // 设置指示器与底部的间距
78 | .setPointMarginBottom(10)
79 | // 设置指示器的item宽度
80 | .setPointChildWidth(8)
81 | // 设置指示器的item高度
82 | .setPointChildHeight(8)
83 | // 设置指示器的item的间距
84 | .setPointChildMargin(8)
85 | // 指示器的item是否为圆形,默认圆形直径取宽高的最小值
86 | .setPointIsCircle(true)
87 | // 指示器item未选中的颜色
88 | .setPointNormalColor(ContextCompat.getColor(getBaseContext(), R.color.white))
89 | // 指示器item选中的颜色
90 | .setPointSelectColor(ContextCompat.getColor(getBaseContext(), R.color.black_text))
91 | // 设置背景图片(此时设置的背景色无效,以背景图片为主)
92 | .setBackgroundImageLoader(new GridViewPager.BackgroundImageLoaderInterface() {
93 | @Override
94 | public void setBackgroundImg(ImageView bgImageView) {
95 | bgImageView.setImageResource(R.drawable.ic_launcher_background_red);
96 | }
97 | })
98 | // 数据绑定
99 | .setImageTextLoaderInterface(new GridViewPager.ImageTextLoaderInterface() {
100 | @Override
101 | public void displayImageText(ImageView imageView, TextView textView, int position) {
102 | // 自己进行数据的绑定,灵活度更高,不受任何限制
103 | imageView.setImageResource(iconS[position]);
104 | textView.setText(datas[position]);
105 | }
106 | })
107 | // Item点击
108 | .setGridItemClickListener(new GridViewPager.GridItemClickListener() {
109 | @Override
110 | public void click(int position) {
111 | Toast.makeText(getBaseContext(), "点击了" + datas[position] + position, Toast.LENGTH_SHORT).show();
112 | }
113 | })
114 | .show();
115 | return gridViewPager;
116 | }
117 | }
--------------------------------------------------------------------------------
/app/src/main/java/cn/mtjsoft/www/gridviewpager/ListAdapter.java:
--------------------------------------------------------------------------------
1 | package cn.mtjsoft.www.gridviewpager;
2 |
3 | import com.chad.library.adapter.base.BaseQuickAdapter;
4 | import com.chad.library.adapter.base.viewholder.BaseViewHolder;
5 |
6 | import org.jetbrains.annotations.NotNull;
7 | import org.jetbrains.annotations.Nullable;
8 |
9 | import java.util.List;
10 |
11 | public class ListAdapter extends BaseQuickAdapter {
12 |
13 | public ListAdapter(@Nullable List data) {
14 | super(R.layout.item_text, data);
15 | }
16 |
17 | @Override
18 | protected void convert(@NotNull BaseViewHolder baseViewHolder, String s) {
19 | baseViewHolder.setText(R.id.tv_name, s);
20 | }
21 | }
--------------------------------------------------------------------------------
/app/src/main/java/cn/mtjsoft/www/gridviewpager/MainActivity.java:
--------------------------------------------------------------------------------
1 | package cn.mtjsoft.www.gridviewpager;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.view.View;
6 | import android.widget.Button;
7 | import android.widget.ImageView;
8 | import android.widget.RadioGroup;
9 | import android.widget.SeekBar;
10 | import android.widget.TextView;
11 | import android.widget.Toast;
12 |
13 | import com.google.android.flexbox.AlignContent;
14 |
15 | import androidx.appcompat.app.AppCompatActivity;
16 | import androidx.core.content.ContextCompat;
17 |
18 | import java.util.Random;
19 |
20 | import cn.mtjsoft.www.gridviewpager_recycleview.GridViewPager;
21 | import cn.mtjsoft.www.gridviewpager_recycleview.transformer.TopOrDownPageTransformer;
22 |
23 | public class MainActivity extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener {
24 |
25 | private String[] titles = {"美食", "电影", "酒店住宿", "休闲娱乐", "外卖", "自助餐", "KTV", "机票/火车票", "周边游", "美甲美睫",
26 | "火锅", "生日蛋糕", "甜品饮品", "水上乐园", "汽车服务", "美发", "丽人", "景点", "足疗按摩", "运动健身", "健身", "超市", "买菜",
27 | "今日新单", "小吃快餐", "面膜", "洗浴/汗蒸", "母婴亲子", "生活服务", "婚纱摄影", "学习培训", "家装", "结婚", "全部分配"};
28 |
29 | private int[] iconS = new int[titles.length];
30 |
31 | private int rowCount = 3;
32 | private int columnCount = 4;
33 | // 指定刷新某一页数据
34 | private int page = 0;
35 |
36 | //
37 | private GridViewPager gridViewPager;
38 | private TextView tv_row;
39 | private TextView tv_column;
40 | private TextView tv_page;
41 |
42 |
43 | private Random random = new Random();
44 |
45 | @Override
46 | protected void onCreate(Bundle savedInstanceState) {
47 | super.onCreate(savedInstanceState);
48 | setContentView(R.layout.activity_main);
49 |
50 | initData();
51 |
52 |
53 | gridViewPager = findViewById(R.id.gridviewpager);
54 | gridViewPager
55 | // 设置数据总数量
56 | .setDataAllCount(18)
57 | // 设置背景色,默认白色
58 | .setGridViewPagerBackgroundColor(ContextCompat.getColor(getBaseContext(), R.color.white))
59 | // 设置item的纵向间距
60 | .setVerticalSpacing(10)
61 | // 设置上边距
62 | .setPagerMarginTop(10)
63 | // 设置下边距
64 | .setPagerMarginBottom(10)
65 | // 设置图片宽度
66 | .setImageWidth(50)
67 | // 设置图片高度
68 | .setImageHeight(50)
69 | // 设置是否显示文本
70 | .setIsShowText(true)
71 | // 设置子VIEW对齐方式
72 | .setAlignContent(AlignContent.FLEX_START)
73 | // 设置文字与图片的间距
74 | .setTextImgMargin(5)
75 | // 设置文字颜色
76 | .setTextColor(ContextCompat.getColor(getBaseContext(), R.color.white))
77 | // 设置文字大小
78 | .setTextSize(12)
79 | // 设置每页行数
80 | .setRowCount(rowCount)
81 | // 设置每页列数
82 | .setColumnCount(columnCount)
83 | // 设置无限循环
84 | .setPageLoop(true)
85 | // 设置是否显示指示器
86 | .setPointIsShow(true)
87 | // 设置指示器与page的间距
88 | .setPointMarginPage(0)
89 | // 设置指示器与底部的间距
90 | .setPointMarginBottom(10)
91 | // 设置指示器的item宽度
92 | .setPointChildWidth(8)
93 | // 设置指示器的item高度
94 | .setPointChildHeight(8)
95 | // 设置指示器的item的间距
96 | .setPointChildMargin(8)
97 | // 指示器的item是否为圆形,默认圆形直径取宽高的最小值
98 | .setPointIsCircle(true)
99 | // 指示器item未选中的颜色
100 | .setPointNormalColor(ContextCompat.getColor(getBaseContext(), R.color.white))
101 | // 指示器item选中的颜色
102 | .setPointSelectColor(ContextCompat.getColor(getBaseContext(), R.color.black_text))
103 | // 设置背景图片(此时设置的背景色无效,以背景图片为主)
104 | .setBackgroundImageLoader(new GridViewPager.BackgroundImageLoaderInterface() {
105 | @Override
106 | public void setBackgroundImg(ImageView bgImageView) {
107 | bgImageView.setImageResource(R.drawable.ic_launcher_background_red);
108 | }
109 | })
110 | // 数据绑定
111 | .setImageTextLoaderInterface(new GridViewPager.ImageTextLoaderInterface() {
112 | @Override
113 | public void displayImageText(ImageView imageView, TextView textView, int position) {
114 | // 自己进行数据的绑定,灵活度更高,不受任何限制
115 | imageView.setImageResource(iconS[position]);
116 | if (textView != null) {
117 | textView.setText(titles[position]);
118 | }
119 | }
120 | })
121 | // Item点击
122 | .setGridItemClickListener(new GridViewPager.GridItemClickListener() {
123 | @Override
124 | public void click(int position) {
125 | Toast.makeText(getBaseContext(), "点击了" + titles[position].split("_")[0], Toast.LENGTH_SHORT).show();
126 | }
127 | })
128 | // 设置Item长按
129 | .setGridItemLongClickListener(new GridViewPager.GridItemLongClickListener() {
130 | @Override
131 | public void longClick(int position) {
132 | Toast.makeText(getBaseContext(), "长按了" + titles[position].split("_")[0], Toast.LENGTH_SHORT).show();
133 | }
134 | })
135 | .show();
136 |
137 | //
138 | tv_row = findViewById(R.id.tv_row);
139 | tv_column = findViewById(R.id.tv_column);
140 | tv_page = findViewById(R.id.tv_page);
141 | SeekBar sb_row = findViewById(R.id.sb_row);
142 | SeekBar sb_column = findViewById(R.id.sb_column);
143 | SeekBar sb_page = findViewById(R.id.sb_page);
144 | sb_row.setOnSeekBarChangeListener(this);
145 | sb_column.setOnSeekBarChangeListener(this);
146 | sb_page.setOnSeekBarChangeListener(this);
147 |
148 | // 刷新
149 | Button button = findViewById(R.id.btu_page);
150 | button.setOnClickListener(new View.OnClickListener() {
151 | @Override
152 | public void onClick(View v) {
153 | // 改变数据
154 | int x = random.nextInt(5);
155 | for (int i = 0; i < titles.length; i++) {
156 | titles[i] = titles[i].split("_")[0] + "_" + x;
157 | }
158 | // 刷新
159 | gridViewPager.setDataAllCount(titles.length).setRowCount(rowCount).setColumnCount(columnCount).show();
160 | }
161 | });
162 | // 刷新指定的第page页
163 | Button button2 = findViewById(R.id.btu_page2);
164 | button2.setOnClickListener(new View.OnClickListener() {
165 | @Override
166 | public void onClick(View v) {
167 | int pageSize = gridViewPager.getOnePageSize();
168 | int x = random.nextInt(5) + 5;
169 | // 改变第page页的数据
170 | for (int i = 0; i < titles.length; i++) {
171 | if (i >= pageSize * page && i < pageSize * (page + 1)) {
172 | titles[i] = titles[i].split("_")[0] + "_" + x;
173 | }
174 | }
175 | // 刷新第page页的数据
176 | gridViewPager.notifyItemChanged(page);
177 | }
178 | });
179 |
180 | // 测试翻页效果
181 | final GridViewPager gridViewPager2 = findViewById(R.id.gridviewpager2);
182 | gridViewPager2
183 | // 设置数据总数量
184 | .setDataAllCount(titles.length)
185 | // 设置内置的覆盖翻页效果
186 | .setCoverPageTransformer()
187 | // 设置内置的上下进入效果
188 | // .setTopOrDownPageTransformer(TopOrDownPageTransformer.ModeType.MODE_DOWN)
189 | // 设置内置的画廊效果
190 | // .setGalleryPageTransformer()
191 | // 数据绑定
192 | .setImageTextLoaderInterface(new GridViewPager.ImageTextLoaderInterface() {
193 | @Override
194 | public void displayImageText(ImageView imageView, TextView textView, int position) {
195 | // 自己进行数据的绑定,灵活度更高,不受任何限制
196 | imageView.setImageResource(iconS[position]);
197 | textView.setText(titles[position].split("_")[0]);
198 | }
199 | })
200 | // Item点击
201 | .setGridItemClickListener(new GridViewPager.GridItemClickListener() {
202 | @Override
203 | public void click(int position) {
204 | Toast.makeText(getBaseContext(), "点击了" + titles[position].split("_")[0], Toast.LENGTH_SHORT).show();
205 | }
206 | })
207 | // 设置Item长按
208 | .setGridItemLongClickListener(new GridViewPager.GridItemLongClickListener() {
209 | @Override
210 | public void longClick(int position) {
211 | Toast.makeText(getBaseContext(), "长按了" + titles[position].split("_")[0], Toast.LENGTH_SHORT).show();
212 | }
213 | })
214 | .show();
215 |
216 | // 测试列表
217 | Button button3 = findViewById(R.id.btu_list);
218 | button3.setOnClickListener(new View.OnClickListener() {
219 | @Override
220 | public void onClick(View v) {
221 | startActivity(new Intent(getBaseContext(), ListActivity.class));
222 | }
223 | });
224 |
225 | // 测试嵌套滑动
226 | findViewById(R.id.btu_list2).setOnClickListener(new View.OnClickListener() {
227 | @Override
228 | public void onClick(View v) {
229 | startActivity(new Intent(getBaseContext(), CoordinatorActivity.class));
230 | }
231 | });
232 | }
233 |
234 |
235 | /**
236 | * 初始化数据源,这里使用本地图标作为示例
237 | */
238 | private void initData() {
239 | for (int i = 0; i < titles.length; i++) {
240 | //动态获取资源ID,第一个参数是资源名,第二个参数是资源类型例如drawable,string等,第三个参数包名
241 | int imageId = getResources().getIdentifier("ic_category_" + i, "mipmap", getPackageName());
242 | iconS[i] = imageId;
243 | }
244 | }
245 |
246 | @Override
247 | public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
248 | switch (seekBar.getId()) {
249 | case R.id.sb_row:
250 | if (i < 1) {
251 | Toast.makeText(getBaseContext(), "最少设置一行", Toast.LENGTH_SHORT).show();
252 | } else {
253 | tv_row.setText("设置行数:" + i);
254 | rowCount = i;
255 | }
256 | break;
257 | case R.id.sb_column:
258 | if (i < 1) {
259 | Toast.makeText(getBaseContext(), "最少设置一列", Toast.LENGTH_SHORT).show();
260 | } else {
261 | tv_column.setText("设置列数:" + i);
262 | columnCount = i;
263 | }
264 | break;
265 | case R.id.sb_page:
266 | if (i > gridViewPager.getPageSize() - 1) {
267 | Toast.makeText(getBaseContext(), "超出页码", Toast.LENGTH_SHORT).show();
268 | } else {
269 | tv_page.setText("指定刷新页:" + i);
270 | page = i;
271 | }
272 | break;
273 | }
274 | }
275 |
276 | @Override
277 | public void onStartTrackingTouch(SeekBar seekBar) {
278 |
279 | }
280 |
281 | @Override
282 | public void onStopTrackingTouch(SeekBar seekBar) {
283 |
284 | }
285 | }
286 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_arrow_white_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background_red.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_coordinatorlayout.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
12 |
13 |
17 |
18 |
23 |
24 |
30 |
31 |
32 |
33 |
34 |
35 |
40 |
41 |
45 |
46 |
70 |
71 |
78 |
79 |
88 |
89 |
98 |
99 |
108 |
109 |
118 |
119 |
128 |
129 |
138 |
139 |
140 |
141 |
142 |
143 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
15 |
16 |
40 |
41 |
46 |
47 |
53 |
54 |
61 |
62 |
63 |
64 |
69 |
70 |
76 |
77 |
84 |
85 |
86 |
87 |
92 |
93 |
99 |
100 |
106 |
107 |
108 |
109 |
116 |
117 |
125 |
126 |
134 |
135 |
160 |
161 |
169 |
170 |
178 |
179 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_text.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_0.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_1.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_10.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_11.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_12.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_13.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_14.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_14.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_15.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_15.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_16.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_17.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_17.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_18.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_18.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_19.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_19.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_2.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_20.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_21.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_21.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_22.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_22.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_23.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_23.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_24.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_25.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_25.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_26.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_26.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_27.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_27.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_28.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_28.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_29.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_29.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_3.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_30.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_30.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_31.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_31.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_32.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_33.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_33.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_4.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_5.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_6.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_7.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_8.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_category_9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_category_9.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #008577
4 | #00574B
5 | #D81B60
6 |
7 | #FFFFFF
8 |
9 | #000000
10 |
11 | #333333
12 |
13 | #646464
14 |
15 | #A6AAAD
16 | #9F9F9F
17 | #CDCDCD
18 |
19 | #F8B9C0
20 |
21 | #F5F5F5
22 | #80cccccc
23 |
24 | #151A15
25 | #EE3A3E3C
26 | #929392
27 | #cc000000
28 | #3E403E
29 |
30 | #32323232
31 |
32 | #60000000
33 |
34 | #00000000
35 |
36 | #DBD9D8
37 |
38 |
39 | #D6D6D6
40 |
41 | #eeffffff
42 |
43 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | GridViewPager
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
17 |
18 |
19 |
22 |
23 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/test/java/cn/mtjsoft/www/gridviewpager/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package cn.mtjsoft.www.gridviewpager;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 |
5 | repositories {
6 | google()
7 | jcenter()
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.2.0'
11 | classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' // Add this line
12 |
13 | // NOTE: Do not place your application dependencies here; they belong
14 | // in the individual module build.gradle files
15 | }
16 | }
17 |
18 | allprojects {
19 | repositories {
20 | google()
21 | jcenter()
22 | maven { url "https://jitpack.io" }
23 | }
24 | }
25 |
26 | task clean(type: Delete) {
27 | delete rootProject.buildDir
28 | }
29 |
--------------------------------------------------------------------------------
/gif.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/gif.gif
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/gradle.properties
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/gridviewpager_recycleview/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/gridviewpager_recycleview/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'com.github.dcendents.android-maven'
3 | group = 'com.github.mtjsoft'
4 | android {
5 | compileSdkVersion 28
6 |
7 | defaultConfig {
8 | minSdkVersion 19
9 | targetSdkVersion 28
10 | versionCode 1
11 | versionName "1.0"
12 |
13 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
14 |
15 | }
16 |
17 | buildTypes {
18 | release {
19 | minifyEnabled false
20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
21 | }
22 | }
23 | }
24 |
25 | dependencies {
26 | implementation fileTree(dir: 'libs', include: ['*.jar'])
27 | implementation 'androidx.appcompat:appcompat:1.1.0'
28 | implementation 'androidx.recyclerview:recyclerview:1.1.0'
29 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
30 | implementation 'com.google.android.material:material:1.1.0'
31 | testImplementation 'junit:junit:4.12'
32 | androidTestImplementation 'androidx.test.ext:junit:1.1.1'
33 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
34 | // 弹性布局
35 | api 'com.google.android:flexbox:2.0.1'
36 | // viewpager2
37 | api "androidx.viewpager2:viewpager2:1.0.0"
38 | }
39 |
--------------------------------------------------------------------------------
/gridviewpager_recycleview/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/gridviewpager_recycleview/src/androidTest/java/cn/mtjsoft/www/gridviewpager_recycleview/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package cn.mtjsoft.www.gridviewpager_recycleview;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("cn.mtjsoft.www.gridviewpager_recycleview.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/gridviewpager_recycleview/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/gridviewpager_recycleview/src/main/java/cn/mtjsoft/www/gridviewpager_recycleview/GridViewPager.java:
--------------------------------------------------------------------------------
1 | package cn.mtjsoft.www.gridviewpager_recycleview;
2 |
3 | import android.content.Context;
4 | import android.content.res.TypedArray;
5 | import android.graphics.Color;
6 | import android.graphics.Paint;
7 | import android.util.AttributeSet;
8 | import android.util.TypedValue;
9 | import android.view.LayoutInflater;
10 | import android.view.MotionEvent;
11 | import android.view.View;
12 | import android.view.ViewGroup;
13 | import android.view.ViewStub;
14 | import android.widget.FrameLayout;
15 | import android.widget.ImageView;
16 | import android.widget.LinearLayout;
17 | import android.widget.RelativeLayout;
18 | import android.widget.TextView;
19 |
20 | import androidx.annotation.NonNull;
21 | import androidx.recyclerview.widget.RecyclerView;
22 | import androidx.viewpager2.widget.ViewPager2;
23 |
24 | import com.google.android.flexbox.AlignContent;
25 | import com.google.android.flexbox.FlexboxLayout;
26 |
27 | import java.util.ArrayList;
28 | import java.util.List;
29 |
30 | import cn.mtjsoft.www.gridviewpager_recycleview.transformer.CoverPageTransformer;
31 | import cn.mtjsoft.www.gridviewpager_recycleview.transformer.GalleryPageTransformer;
32 | import cn.mtjsoft.www.gridviewpager_recycleview.transformer.TopOrDownPageTransformer;
33 | import cn.mtjsoft.www.gridviewpager_recycleview.view.AndDensityUtils;
34 | import cn.mtjsoft.www.gridviewpager_recycleview.view.AndSelectCircleView;
35 |
36 |
37 | /**
38 | * recycleview的方式来实现美团app的首页标签效果
39 | */
40 | public class GridViewPager extends FrameLayout {
41 |
42 | private ViewPager2 viewPager2;
43 | private ImageView bgImageView;
44 |
45 | private PagerAdapter pagerAdapter;
46 |
47 | private int widthPixels = 0;
48 | /**
49 | * 指示点
50 | */
51 | private AndSelectCircleView andSelectCircleView;
52 | //子控件显示的宽度
53 | private int mChildWidth = 8;
54 | //子控件显示的高度
55 | private int mChildHeight = 8;
56 | //两个子控件之间的间距
57 | private int mChildMargin = 8;
58 | //正常情况下显示的颜色
59 | private int mNormalColor = Color.GRAY;
60 | //选中的时候现实的颜色
61 | private int mSelectColor = Color.RED;
62 | // 是否是圆形的指示点
63 | private boolean mIsCircle = true;
64 | // 是否需要显示指示器
65 | private boolean mIsShow = true;
66 | // 指示器与page间距
67 | private int pointMarginPage = 10;
68 | // 指示器与底部间距
69 | private int pointMarginBottom = 10;
70 |
71 | /**
72 | * GridViewPager
73 | */
74 | // page上间距
75 | private int pagerMarginTop = 10;
76 | // page下间距
77 | private int pagerMarginBottom = 10;
78 | // 行间距间距
79 | private int verticalSpacing = 10;
80 | // icon 宽度
81 | private int imageWidth = 50;
82 | // icon 高度
83 | private int imageHeight = 50;
84 | // 文字颜色
85 | private int textColor = Color.BLACK;
86 | // 文字大小
87 | private int textSize = 10;
88 | // icon 文字 的间距
89 | private int textImgMargin = 5;
90 | // 行数
91 | private int rowCount = 2;
92 | // 列数
93 | private int columnCount = 4;
94 | // 每页大小
95 | private int pageSize = 8;
96 | // 数据总数
97 | private int dataAllCount = 0;
98 | // 背景颜色
99 | private int backgroundColor = Color.WHITE;
100 | // item背景颜色
101 | private int itemBackgroundColor = Color.TRANSPARENT;
102 | // 是否开启无限循环(页数大于1才有效)
103 | private boolean pageLoop = false;
104 | // 是否显示文本,默认显示
105 | private boolean mIsShowText = true;
106 |
107 | // 子项对齐方式
108 | private int alignContent = AlignContent.FLEX_START;
109 |
110 | // 用于切换动画
111 | private ViewPager2.PageTransformer pageTransformer;
112 |
113 | /**
114 | * item点击监听
115 | */
116 | private GridItemClickListener gridItemClickListener;
117 | /**
118 | * item长按监听
119 | */
120 | private GridItemLongClickListener gridItemLongClickListener;
121 |
122 | private ImageTextLoaderInterface imageTextLoaderInterface;
123 |
124 | private BackgroundImageLoaderInterface backgroundImageLoaderInterface;
125 |
126 | private float startX;
127 | private float startY;
128 |
129 | public GridViewPager(Context context) {
130 | this(context, null);
131 | }
132 |
133 | public GridViewPager(Context context, AttributeSet attrs) {
134 | this(context, attrs, 0);
135 | }
136 |
137 | public GridViewPager(Context context, AttributeSet attrs, int defStyleAttr) {
138 | super(context, attrs, defStyleAttr);
139 | widthPixels = getResources().getDisplayMetrics().widthPixels;
140 | handleTypedArray(context, attrs);
141 | initView();
142 | setBackgroundColor(backgroundColor);
143 | }
144 |
145 | /**
146 | * 添加布局
147 | */
148 |
149 | private void initView() {
150 | View view = View.inflate(getContext(), R.layout.gridpager_layout, null);
151 | bgImageView = view.findViewById(R.id.iv_bg);
152 | viewPager2 = view.findViewById(R.id.viewPager2);
153 | andSelectCircleView = view.findViewById(R.id.scv);
154 | addView(view);
155 | viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
156 | @Override
157 | public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
158 | super.onPageScrolled(position, positionOffset, positionOffsetPixels);
159 | }
160 |
161 | @Override
162 | public void onPageSelected(int position) {
163 | super.onPageSelected(position);
164 | int page = getPageSize();
165 | if (pageLoop && page > 1) {
166 | if (position == 0) {
167 | viewPager2.setCurrentItem(integerList.size() - 2, false);
168 | } else if (position == integerList.size() - 1) {
169 | viewPager2.setCurrentItem(1, false);
170 | }
171 | andSelectCircleView.setSelectPosition(position - 1);
172 | } else {
173 | andSelectCircleView.setSelectPosition(position);
174 | }
175 | }
176 |
177 | @Override
178 | public void onPageScrollStateChanged(int state) {
179 | super.onPageScrollStateChanged(state);
180 | }
181 | });
182 | }
183 |
184 | private void handleTypedArray(Context context, AttributeSet attrs) {
185 | if (attrs == null) {
186 | return;
187 | }
188 | TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.GridViewPager);
189 | pagerMarginTop = typedArray.getDimensionPixelSize(R.styleable.GridViewPager_pager_MarginTop, AndDensityUtils.dip2px(getContext(), pagerMarginTop));
190 | pagerMarginBottom = typedArray.getDimensionPixelSize(R.styleable.GridViewPager_pager_MarginBottom, AndDensityUtils.dip2px(getContext(), pagerMarginBottom));
191 | verticalSpacing = typedArray.getDimensionPixelSize(R.styleable.GridViewPager_verticalSpacing, AndDensityUtils.dip2px(getContext(), verticalSpacing));
192 | backgroundColor = typedArray.getColor(R.styleable.GridViewPager_background_color, Color.WHITE);
193 | itemBackgroundColor = typedArray.getColor(R.styleable.GridViewPager_item_background_color, Color.TRANSPARENT);
194 | imageWidth = typedArray.getDimensionPixelSize(R.styleable.GridViewPager_img_width, AndDensityUtils.dip2px(getContext(), imageWidth));
195 | imageHeight = typedArray.getDimensionPixelSize(R.styleable.GridViewPager_img_height, AndDensityUtils.dip2px(getContext(), imageHeight));
196 | textColor = typedArray.getColor(R.styleable.GridViewPager_text_color, Color.BLACK);
197 | textSize = typedArray.getDimensionPixelSize(R.styleable.GridViewPager_text_size, AndDensityUtils.sp2px(getContext(), textSize));
198 | textImgMargin = typedArray.getDimensionPixelSize(R.styleable.GridViewPager_imgtext_margin, AndDensityUtils.dip2px(getContext(), textImgMargin));
199 | rowCount = typedArray.getInt(R.styleable.GridViewPager_row_count, rowCount);
200 | columnCount = typedArray.getInt(R.styleable.GridViewPager_column_count, columnCount);
201 | pageLoop = typedArray.getBoolean(R.styleable.GridViewPager_pager_loop, false);
202 | mIsShowText = typedArray.getBoolean(R.styleable.GridViewPager_text_is_show, true);
203 | // 指示点
204 | mChildWidth = typedArray.getDimensionPixelSize(R.styleable.GridViewPager_point_width, AndDensityUtils.dip2px(getContext(), mChildWidth));
205 | mChildHeight = typedArray.getDimensionPixelSize(R.styleable.GridViewPager_point_height, AndDensityUtils.dip2px(getContext(), mChildHeight));
206 | mChildMargin = typedArray.getDimensionPixelSize(R.styleable.GridViewPager_point_margin, AndDensityUtils.dip2px(getContext(), mChildMargin));
207 | mNormalColor = typedArray.getColor(R.styleable.GridViewPager_point_normal_color, Color.GRAY);
208 | mSelectColor = typedArray.getColor(R.styleable.GridViewPager_point_select_color, Color.RED);
209 | mIsCircle = typedArray.getBoolean(R.styleable.GridViewPager_point_is_circle, true);
210 | mIsShow = typedArray.getBoolean(R.styleable.GridViewPager_point_is_show, true);
211 | pointMarginPage = typedArray.getDimensionPixelSize(R.styleable.GridViewPager_point_margin_page, verticalSpacing);
212 | pointMarginBottom = typedArray.getDimensionPixelSize(R.styleable.GridViewPager_point_margin_bottom, verticalSpacing);
213 | typedArray.recycle();
214 | }
215 |
216 | @Override
217 | public boolean dispatchTouchEvent(MotionEvent ev) {
218 | switch (ev.getAction()) {
219 | case MotionEvent.ACTION_DOWN:
220 | startX = ev.getX();
221 | startY = ev.getY();
222 | break;
223 | case MotionEvent.ACTION_MOVE:
224 | if (Math.abs(ev.getX() - startX) < Math.abs(ev.getY() - startY)) {
225 | return false;
226 | } else {
227 | return super.dispatchTouchEvent(ev);
228 | }
229 | }
230 | return super.dispatchTouchEvent(ev);
231 | }
232 |
233 | /**
234 | * 设置数据总数
235 | *
236 | * @param dataAllCount
237 | * @return
238 | */
239 | public GridViewPager setDataAllCount(int dataAllCount) {
240 | if (dataAllCount > 0) {
241 | this.dataAllCount = dataAllCount;
242 | }
243 | return this;
244 | }
245 |
246 | /**
247 | * 设置列数
248 | *
249 | * @param columnCount
250 | * @return
251 | */
252 | public GridViewPager setColumnCount(int columnCount) {
253 | if (columnCount > 0) {
254 | this.columnCount = columnCount;
255 | }
256 | return this;
257 | }
258 |
259 | /**
260 | * 设置是否无限循环(true 页码大于1时才有效)
261 | *
262 | * @param pageLoop
263 | * @return
264 | */
265 | public GridViewPager setPageLoop(boolean pageLoop) {
266 | this.pageLoop = pageLoop;
267 | return this;
268 | }
269 |
270 | /**
271 | * 是否显示文本控件
272 | *
273 | * @param mIsShowText
274 | * @return
275 | */
276 | public GridViewPager setIsShowText(boolean mIsShowText) {
277 | this.mIsShowText = mIsShowText;
278 | return this;
279 | }
280 |
281 | /**
282 | * 设置行数
283 | *
284 | * @param rowCount
285 | * @return
286 | */
287 | public GridViewPager setRowCount(int rowCount) {
288 | if (rowCount > 0) {
289 | this.rowCount = rowCount;
290 | }
291 | return this;
292 | }
293 |
294 | /**
295 | * 上下边距
296 | *
297 | * @param pagerMarginTop
298 | */
299 | public GridViewPager setPagerMarginTop(int pagerMarginTop) {
300 | this.pagerMarginTop = AndDensityUtils.dip2px(getContext(), pagerMarginTop);
301 | return this;
302 | }
303 |
304 | public GridViewPager setPagerMarginBottom(int pagerMarginBottom) {
305 | this.pagerMarginBottom = AndDensityUtils.dip2px(getContext(), pagerMarginBottom);
306 | return this;
307 | }
308 |
309 | /**
310 | * 设置 纵向间距
311 | *
312 | * @param verticalSpacing
313 | * @return
314 | */
315 | public GridViewPager setVerticalSpacing(int verticalSpacing) {
316 | this.verticalSpacing = AndDensityUtils.dip2px(getContext(), verticalSpacing);
317 | return this;
318 | }
319 |
320 | /**
321 | * 设置 icon 宽度
322 | *
323 | * @param imageWidth
324 | * @return
325 | */
326 | public GridViewPager setImageWidth(int imageWidth) {
327 | this.imageWidth = AndDensityUtils.dip2px(getContext(), imageWidth);
328 | return this;
329 | }
330 |
331 | /**
332 | * 设置 icon 高度
333 | *
334 | * @param imageHeight
335 | * @return
336 | */
337 | public GridViewPager setImageHeight(int imageHeight) {
338 | this.imageHeight = AndDensityUtils.dip2px(getContext(), imageHeight);
339 | return this;
340 | }
341 |
342 | /**
343 | * 设置 字体颜色
344 | *
345 | * @param textColor
346 | * @return
347 | */
348 | public GridViewPager setTextColor(int textColor) {
349 | this.textColor = textColor;
350 | return this;
351 | }
352 |
353 | /**
354 | * 设置 背景颜色
355 | *
356 | * @param backgroundColor
357 | * @return
358 | */
359 | public GridViewPager setGridViewPagerBackgroundColor(int backgroundColor) {
360 | setBackgroundColor(backgroundColor);
361 | return this;
362 | }
363 |
364 | /**
365 | * 单独设置item的背景
366 | *
367 | * @param itemBackgroundColor
368 | * @return
369 | */
370 | public GridViewPager setItemBackgroundColor(int itemBackgroundColor) {
371 | this.itemBackgroundColor = itemBackgroundColor;
372 | return this;
373 | }
374 |
375 | /**
376 | * 设置字体大小
377 | *
378 | * @param textSize
379 | * @return
380 | */
381 | public GridViewPager setTextSize(int textSize) {
382 | this.textSize = AndDensityUtils.sp2px(getContext(), textSize);
383 | return this;
384 | }
385 |
386 | /**
387 | * 设置字体与icon的间距
388 | *
389 | * @param textImgMargin
390 | * @return
391 | */
392 | public GridViewPager setTextImgMargin(int textImgMargin) {
393 | this.textImgMargin = AndDensityUtils.dip2px(getContext(), textImgMargin);
394 | return this;
395 | }
396 |
397 | /**
398 | * 设置指示器的宽度
399 | *
400 | * @param mChildWidth
401 | * @return
402 | */
403 | public GridViewPager setPointChildWidth(int mChildWidth) {
404 | this.mChildWidth = AndDensityUtils.dip2px(getContext(), mChildWidth);
405 | return this;
406 | }
407 |
408 | /**
409 | * 设置指示器的高度
410 | *
411 | * @param mChildHeight
412 | * @return
413 | */
414 | public GridViewPager setPointChildHeight(int mChildHeight) {
415 | this.mChildHeight = AndDensityUtils.dip2px(getContext(), mChildHeight);
416 | return this;
417 | }
418 |
419 | /**
420 | * 设置指示器的间距
421 | *
422 | * @param mChildMargin
423 | * @return
424 | */
425 | public GridViewPager setPointChildMargin(int mChildMargin) {
426 | this.mChildMargin = AndDensityUtils.dip2px(getContext(), mChildMargin);
427 | return this;
428 | }
429 |
430 | /**
431 | * 设置指示器是否为圆形
432 | *
433 | * @param mIsCircle
434 | * @return
435 | */
436 | public GridViewPager setPointIsCircle(boolean mIsCircle) {
437 | this.mIsCircle = mIsCircle;
438 | return this;
439 | }
440 |
441 | /**
442 | * 设置指示器未选中颜色
443 | *
444 | * @param mNormalColor
445 | * @return
446 | */
447 | public GridViewPager setPointNormalColor(int mNormalColor) {
448 | this.mNormalColor = mNormalColor;
449 | return this;
450 | }
451 |
452 | /**
453 | * 设置指示器选中的颜色
454 | *
455 | * @param mSelectColor
456 | * @return
457 | */
458 | public GridViewPager setPointSelectColor(int mSelectColor) {
459 | this.mSelectColor = mSelectColor;
460 | return this;
461 | }
462 |
463 | /**
464 | * 设置指示器是否显示
465 | *
466 | * @param mIsShow
467 | * @return
468 | */
469 | public GridViewPager setPointIsShow(boolean mIsShow) {
470 | this.mIsShow = mIsShow;
471 | return this;
472 | }
473 |
474 | /**
475 | * 设置指示器与page的间距
476 | *
477 | * @param pointMarginPage
478 | * @return
479 | */
480 | public GridViewPager setPointMarginPage(int pointMarginPage) {
481 | this.pointMarginPage = AndDensityUtils.dip2px(getContext(), pointMarginPage);
482 | return this;
483 | }
484 |
485 | /**
486 | * 设置指示器与底部的间距
487 | *
488 | * @param pointMarginBottom
489 | * @return
490 | */
491 | public GridViewPager setPointMarginBottom(int pointMarginBottom) {
492 | this.pointMarginBottom = AndDensityUtils.dip2px(getContext(), pointMarginBottom);
493 | return this;
494 | }
495 |
496 | /**
497 | * 设置子项对其方式
498 | *
499 | * @param alignContent
500 | * @return
501 | */
502 | public GridViewPager setAlignContent(@AlignContent int alignContent) {
503 | this.alignContent = alignContent;
504 | return this;
505 | }
506 |
507 | /**
508 | * 设置 Item 点击监听
509 | *
510 | * @param gridItemClickListener
511 | */
512 | public GridViewPager setGridItemClickListener(GridItemClickListener gridItemClickListener) {
513 | this.gridItemClickListener = gridItemClickListener;
514 | return this;
515 | }
516 |
517 | /**
518 | * 设置 Item 长按监听
519 | *
520 | * @param gridItemLongClickListener
521 | */
522 | public GridViewPager setGridItemLongClickListener(GridItemLongClickListener gridItemLongClickListener) {
523 | this.gridItemLongClickListener = gridItemLongClickListener;
524 | return this;
525 | }
526 |
527 | /**
528 | * 设置 图片加载
529 | *
530 | * @param imageTextLoaderInterface
531 | */
532 | public GridViewPager setImageTextLoaderInterface(ImageTextLoaderInterface
533 | imageTextLoaderInterface) {
534 | this.imageTextLoaderInterface = imageTextLoaderInterface;
535 | return this;
536 | }
537 |
538 | /**
539 | * 设置背景图片
540 | *
541 | * @param backgroundImageLoaderInterface
542 | * @return
543 | */
544 | public GridViewPager setBackgroundImageLoader(BackgroundImageLoaderInterface
545 | backgroundImageLoaderInterface) {
546 | this.backgroundImageLoaderInterface = backgroundImageLoaderInterface;
547 | return this;
548 | }
549 |
550 | /**
551 | * 设置自定义 PageTransformer
552 | *
553 | * @param pageTransformer
554 | * @return
555 | */
556 | public GridViewPager setCustomPageTransformer(ViewPager2.PageTransformer pageTransformer) {
557 | this.pageTransformer = pageTransformer;
558 | if (pageTransformer != null) {
559 | viewPager2.setPageTransformer(pageTransformer);
560 | }
561 | return this;
562 | }
563 |
564 | /**
565 | * 设置内置的覆盖效果的 PageTransformer
566 | *
567 | * @return
568 | */
569 | public GridViewPager setCoverPageTransformer() {
570 | this.pageTransformer = new CoverPageTransformer();
571 | viewPager2.setPageTransformer(pageTransformer);
572 | return this;
573 | }
574 |
575 | /**
576 | * 设置内置的画廊效果的 PageTransformer
577 | *
578 | * @return
579 | */
580 | public GridViewPager setGalleryPageTransformer() {
581 | this.pageTransformer = new GalleryPageTransformer();
582 | viewPager2.setPageTransformer(pageTransformer);
583 | return this;
584 | }
585 |
586 | /**
587 | * 设置内置的上下进入效果的 PageTransformer
588 | *
589 | * @return
590 | */
591 | public GridViewPager setTopOrDownPageTransformer(TopOrDownPageTransformer.ModeType modeType) {
592 | this.pageTransformer = new TopOrDownPageTransformer(modeType);
593 | viewPager2.setPageTransformer(pageTransformer);
594 | return this;
595 | }
596 |
597 | /**
598 | * 获取页码大小
599 | *
600 | * @return
601 | */
602 | public int getPageSize() {
603 | pageSize = rowCount * columnCount;
604 | return dataAllCount / pageSize + (dataAllCount % pageSize > 0 ? 1 : 0);
605 | }
606 |
607 | /**
608 | * 获取一页大小
609 | *
610 | * @return
611 | */
612 | public int getOnePageSize() {
613 | return pageSize;
614 | }
615 |
616 | /**
617 | * 显示
618 | */
619 | public void show() {
620 | if (dataAllCount == 0) {
621 | return;
622 | }
623 | // 设置高度
624 | RelativeLayout.LayoutParams rl = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, getAutoHeight());
625 | rl.topMargin = pagerMarginTop;
626 | rl.bottomMargin = pagerMarginBottom;
627 | viewPager2.setLayoutParams(rl);
628 | // 总页数
629 | final int page = getPageSize();
630 | // 显示指示器
631 | andSelectCircleView.setVisibility((mIsShow && page > 1) ? View.VISIBLE : View.GONE);
632 | if (mIsShow && page > 1) {
633 | RelativeLayout.LayoutParams pointParams = (RelativeLayout.LayoutParams) andSelectCircleView.getLayoutParams();
634 | pointParams.topMargin = pointMarginPage;
635 | pointParams.bottomMargin = pointMarginBottom;
636 | andSelectCircleView.setLayoutParams(pointParams);
637 | // 设置指示点
638 | andSelectCircleView
639 | .setmChildWidth(mChildWidth)
640 | .setmChildHeight(mChildHeight)
641 | .setmChildMargin(mChildMargin)
642 | .setmIsCircle(mIsCircle)
643 | .setmNormalColor(mNormalColor)
644 | .setmSelectColor(mSelectColor)
645 | .setPointCheckedChangeListener(new AndSelectCircleView.PointCheckedChangeListener() {
646 | @Override
647 | public void checkedChange(int position) {
648 | if (position >= 0 && position < page) {
649 | // 指示点点击,滚动到对应的页
650 | if (pageLoop) {
651 | viewPager2.setCurrentItem(position + 1, true);
652 | } else {
653 | viewPager2.setCurrentItem(position, true);
654 | }
655 | }
656 | }
657 | })
658 | .addChild(page);
659 | }
660 | // 设置背景图片
661 | if (backgroundImageLoaderInterface != null) {
662 | RelativeLayout.LayoutParams bgImageViewRl = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, getAllHeight());
663 | bgImageView.setLayoutParams(bgImageViewRl);
664 | backgroundImageLoaderInterface.setBackgroundImg(bgImageView);
665 | }
666 | // 设置数据
667 | setAdapter(page);
668 | }
669 |
670 | /**
671 | * 设置数据
672 | */
673 | private List integerList = new ArrayList<>();
674 |
675 | private void setAdapter(final int page) {
676 | integerList.clear();
677 | for (int i = 0; i < page; i++) {
678 | integerList.add(i);
679 | }
680 | // 如果开启了循环模式,首位各多添加一页
681 | if (pageLoop && page > 1) {
682 | integerList.add(0, integerList.get(integerList.size() - 1));
683 | integerList.add(0);
684 | }
685 | if (pagerAdapter == null) {
686 | this.post(new Runnable() {
687 | @Override
688 | public void run() {
689 | // post最后调用,可获取测量后的宽度
690 | widthPixels = getMeasuredWidth();
691 | pagerAdapter = new PagerAdapter(viewPager2.getContext(), R.layout.gridpager_item_layout, integerList);
692 | viewPager2.setAdapter(pagerAdapter);
693 | viewPager2.setOffscreenPageLimit(1);
694 | if (pageLoop && page > 1) {
695 | viewPager2.setCurrentItem(1, false);
696 | }
697 | }
698 | });
699 | } else {
700 | notifyDataSetChanged();
701 | }
702 | }
703 |
704 | /**
705 | * 刷新数据
706 | */
707 | private void notifyDataSetChanged() {
708 | if (pagerAdapter != null) {
709 | pagerAdapter.setChanged();
710 | pagerAdapter.notifyDataSetChanged();
711 | if (pageLoop && getPageSize() > 1) {
712 | viewPager2.setCurrentItem(1, false);
713 | }
714 | }
715 | }
716 |
717 | /**
718 | * 刷新指定页码数据(每页行列数、数据总数不变,只有某个数据的值改变时使用)
719 | *
720 | * @param position
721 | */
722 | public void notifyItemChanged(int position) {
723 | // 总页数
724 | int page = getPageSize();
725 | if (position >= 0 && position < page && pagerAdapter != null) {
726 | if (pageLoop && page > 1) {
727 | pagerAdapter.notifyItemChanged(position + 1);
728 | } else {
729 | pagerAdapter.notifyItemChanged(position);
730 | }
731 | }
732 | }
733 |
734 | /**
735 | * 计算recycleview高度
736 | *
737 | * @return
738 | */
739 | private int getAutoHeight() {
740 | return getOnesHeight() * rowCount + (rowCount - 1) * verticalSpacing;
741 | }
742 |
743 | /**
744 | * 获取一行的高度
745 | *
746 | * @return
747 | */
748 | private int getOnesHeight() {
749 | if (mIsShowText) {
750 | return (int) (imageHeight + textImgMargin + getFontHeight(textSize)); // textSize * 1.133
751 | }
752 | return imageHeight;
753 | }
754 |
755 | /**
756 | * 计算字体高度
757 | *
758 | * @param fontSize
759 | * @return
760 | */
761 | private int getFontHeight(float fontSize) {
762 | Paint paint = new Paint();
763 | paint.setTextSize(fontSize);
764 | Paint.FontMetrics fm = paint.getFontMetrics();
765 | return (int) Math.ceil(fm.descent - fm.ascent);
766 | }
767 |
768 | /**
769 | * 计算总高度
770 | *
771 | * @return
772 | */
773 | private int getAllHeight() {
774 | // 总高
775 | int page = dataAllCount / pageSize + (dataAllCount % pageSize > 0 ? 1 : 0);
776 | int recycleviewH = getAutoHeight();
777 | if (mIsShow && page > 1) {
778 | recycleviewH += pagerMarginTop + pagerMarginBottom + pointMarginPage + pointMarginBottom + mChildHeight;
779 | } else {
780 | recycleviewH += pagerMarginTop + pagerMarginBottom;
781 | }
782 | return recycleviewH;
783 | }
784 |
785 | /**
786 | * item点击回调
787 | */
788 | public interface GridItemClickListener {
789 | void click(int position);
790 | }
791 |
792 | /**
793 | * item点击回调
794 | */
795 | public interface GridItemLongClickListener {
796 | void longClick(int position);
797 | }
798 |
799 | /**
800 | * 图片加载
801 | */
802 | public interface ImageTextLoaderInterface {
803 | void displayImageText(ImageView imageView, TextView textView, int position);
804 | }
805 |
806 | public interface BackgroundImageLoaderInterface {
807 | void setBackgroundImg(ImageView bgImageView);
808 | }
809 |
810 | /**
811 | * PagerAdapter
812 | */
813 | public class PagerAdapter extends RecyclerView.Adapter {
814 |
815 | private Context context;
816 | private int layoutResId;
817 | private List data;
818 | private ViewGroup.LayoutParams layoutParamsMatch;
819 | // private LinearLayout.LayoutParams imageLp;
820 | private LinearLayout.LayoutParams textLp;
821 |
822 | public PagerAdapter(Context context, int layoutResId, List data) {
823 | this.context = context;
824 | this.layoutResId = layoutResId;
825 | this.data = data;
826 | setChanged();
827 | }
828 |
829 | public void setChanged() {
830 | layoutParamsMatch = new ViewGroup.LayoutParams(widthPixels / columnCount, ViewGroup.LayoutParams.WRAP_CONTENT);
831 | // imageLp = new LinearLayout.LayoutParams(imageWidth, imageHeight);
832 | textLp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
833 | textLp.topMargin = textImgMargin;
834 | }
835 |
836 | @Override
837 | public int getItemCount() {
838 | return data == null || data.size() == 0 ? 0 : data.size();
839 | }
840 |
841 | @NonNull
842 | @Override
843 | public PagerAdapter.Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
844 | View view = LayoutInflater.from(context).inflate(layoutResId, parent, false);
845 | return new Holder(view);
846 | }
847 |
848 | @Override
849 | public void onBindViewHolder(@NonNull PagerAdapter.Holder holder, int position) {
850 | holder.flexboxLayout.removeAllViews();
851 | int posi = position;
852 | int page = getPageSize();
853 | if (pageLoop && page > 1) {
854 | if (position == 0) { // 第一页,展示实际最后一页的内容
855 | posi = page - 1;
856 | } else if (position == getItemCount() - 1) { // 最后一页,展示实际第一页的内容
857 | posi = 0;
858 | } else { // 否则展示 position - 1 的实际内容
859 | posi = posi - 1;
860 | }
861 | }
862 | // 循环添加每页数据
863 | int pageSizeCount = pageSize;
864 | // 如果是最后一页,判断最后一页是否够每页的大小
865 | if (posi == page - 1) {
866 | pageSizeCount = dataAllCount % pageSize > 0 ? dataAllCount % pageSize : pageSize;
867 | }
868 | for (int i = 0; i < pageSizeCount; i++) {
869 | View view = View.inflate(getContext(), R.layout.gridpager_item, null);
870 | LinearLayout layout = view.findViewById(R.id.ll_layout);
871 | layout.setLayoutParams(layoutParamsMatch);
872 | layout.setBackgroundColor(itemBackgroundColor);
873 | ImageView imageView = view.findViewById(R.id.item_image);
874 | LinearLayout.LayoutParams imageLp = new LinearLayout.LayoutParams(imageWidth, imageHeight);
875 | if (i < columnCount) {
876 | imageLp.topMargin = 0;
877 | } else {
878 | imageLp.topMargin = verticalSpacing;
879 | }
880 | imageView.setLayoutParams(imageLp);
881 | TextView textView = null;
882 | if (mIsShowText) { // 显示文本,初始化文本textView
883 | ViewStub viewStub = view.findViewById(R.id.vs_text);
884 | textView = (TextView) viewStub.inflate(); //view.findViewById(R.id.item_text);
885 | textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
886 | textView.setTextColor(textColor);
887 | textView.setLayoutParams(textLp);
888 | }
889 | if (imageTextLoaderInterface != null) {
890 | imageTextLoaderInterface.displayImageText(imageView, textView, posi * pageSize + i);
891 | }
892 | layout.setOnClickListener(new myClick(posi, i));
893 | layout.setOnLongClickListener(new myLongClick(posi, i));
894 | holder.flexboxLayout.addView(view);
895 | }
896 | }
897 |
898 | public class Holder extends RecyclerView.ViewHolder {
899 | private FlexboxLayout flexboxLayout;
900 |
901 | public Holder(@NonNull View itemView) {
902 | super(itemView);
903 | flexboxLayout = itemView.findViewById(R.id.flex_layout);
904 | flexboxLayout.setAlignContent(alignContent);
905 | }
906 | }
907 | }
908 |
909 | private class myClick implements OnClickListener {
910 | private int position;
911 | private int pageCount;
912 |
913 | public myClick(int position, int pageCount) {
914 | this.position = position;
915 | this.pageCount = pageCount;
916 | }
917 |
918 | @Override
919 | public void onClick(View v) {
920 | if (gridItemClickListener != null) {
921 | gridItemClickListener.click(position * pageSize + pageCount);
922 | }
923 | }
924 | }
925 |
926 | private class myLongClick implements OnLongClickListener {
927 |
928 | private int position;
929 | private int pageCount;
930 |
931 | public myLongClick(int position, int pageCount) {
932 | this.position = position;
933 | this.pageCount = pageCount;
934 | }
935 |
936 | @Override
937 | public boolean onLongClick(View v) {
938 | if (gridItemLongClickListener != null) {
939 | gridItemLongClickListener.longClick(position * pageSize + pageCount);
940 | }
941 | return true;
942 | }
943 | }
944 | }
945 |
--------------------------------------------------------------------------------
/gridviewpager_recycleview/src/main/java/cn/mtjsoft/www/gridviewpager_recycleview/transformer/CoverPageTransformer.java:
--------------------------------------------------------------------------------
1 | package cn.mtjsoft.www.gridviewpager_recycleview.transformer;
2 |
3 | import android.view.View;
4 |
5 | import androidx.annotation.NonNull;
6 | import androidx.viewpager2.widget.ViewPager2;
7 |
8 | /**
9 | * 页面覆盖效果
10 | */
11 | public class CoverPageTransformer implements ViewPager2.PageTransformer {
12 | //初始
13 | private static final float MIN_SCALE = 0.5f;
14 |
15 | @Override
16 | public void transformPage(@NonNull View view, float position) {
17 | int pageWidth = view.getWidth();
18 | if (position <= 0) { // [-1,0]
19 | view.setTranslationX(0);
20 | view.setAlpha(1 + position);
21 | view.setScaleX(1);
22 | view.setScaleY(1);
23 | } else { // (0,1]
24 | float SCALE = 0.5f - position / 2;
25 | view.setScaleX(MIN_SCALE + SCALE);
26 | view.setScaleY(MIN_SCALE + SCALE);
27 | view.setAlpha(1 - position);
28 | view.setTranslationX(pageWidth * -position);
29 | }
30 | view.setVisibility(position == 1 || position == -1 ? View.GONE : View.VISIBLE);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/gridviewpager_recycleview/src/main/java/cn/mtjsoft/www/gridviewpager_recycleview/transformer/GalleryPageTransformer.java:
--------------------------------------------------------------------------------
1 | package cn.mtjsoft.www.gridviewpager_recycleview.transformer;
2 |
3 | import android.view.View;
4 |
5 | import androidx.annotation.NonNull;
6 | import androidx.viewpager2.widget.ViewPager2;
7 |
8 | /**
9 | * 页面画廊效果
10 | */
11 | public class GalleryPageTransformer implements ViewPager2.PageTransformer {
12 | //初始
13 | private static final float MIN_SCALE = 0.85f;
14 |
15 | @Override
16 | public void transformPage(@NonNull View view, float position) {
17 | float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
18 | float rotate = 25 * Math.abs(position);
19 | if (position > 0) {
20 | view.setScaleX(scaleFactor);
21 | view.setScaleY(scaleFactor);
22 | view.setRotationY(-rotate);
23 | } else {
24 | view.setScaleX(scaleFactor);
25 | view.setScaleY(scaleFactor);
26 | view.setRotationY(rotate);
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/gridviewpager_recycleview/src/main/java/cn/mtjsoft/www/gridviewpager_recycleview/transformer/TopOrDownPageTransformer.java:
--------------------------------------------------------------------------------
1 | package cn.mtjsoft.www.gridviewpager_recycleview.transformer;
2 |
3 | import android.view.View;
4 |
5 | import androidx.annotation.NonNull;
6 | import androidx.viewpager2.widget.ViewPager2;
7 |
8 | /**
9 | * 页面上下进入效果
10 | */
11 | public class TopOrDownPageTransformer implements ViewPager2.PageTransformer {
12 | //初始
13 | private static final float MIN_SCALE = 0.5f;
14 |
15 | private ModeType modeType;
16 |
17 | public TopOrDownPageTransformer(ModeType modeType) {
18 | this.modeType = modeType;
19 | }
20 |
21 | @Override
22 | public void transformPage(@NonNull View view, float position) {
23 | int pageWidth = view.getWidth();
24 | int pageHeight = view.getHeight();
25 | if (position <= 0) { // [-1,0]
26 | view.setTranslationX(0);
27 | view.setTranslationY(0);
28 | view.setAlpha(1 + position);
29 | view.setScaleX(1);
30 | view.setScaleY(1);
31 | } else { // (0,1]
32 | float SCALE = 0.5f - position / 2;
33 | view.setScaleX(MIN_SCALE + SCALE);
34 | view.setScaleY(MIN_SCALE + SCALE);
35 | view.setAlpha(1 - position);
36 | view.setTranslationX(pageWidth * -position);
37 | if (modeType != null) {
38 | if (modeType.getType() == ModeType.MODE_TOP.getType()) {
39 | view.setTranslationY(pageHeight * -position);
40 | } else {
41 | view.setTranslationY(pageHeight * position);
42 | }
43 | }
44 | }
45 | view.setVisibility(position == 1 || position == -1 ? View.GONE : View.VISIBLE);
46 | }
47 |
48 |
49 | public enum ModeType {
50 |
51 | MODE_TOP(1, "自上而下"),
52 | MODE_DOWN(2, "自下而上");
53 |
54 | private int type;
55 | private String name;
56 |
57 | ModeType(int type, String name) {
58 | this.type = type;
59 | this.name = name;
60 | }
61 |
62 |
63 | public int getType() {
64 | return type;
65 | }
66 |
67 | public void setType(int type) {
68 | this.type = type;
69 | }
70 |
71 | public String getName() {
72 | return name;
73 | }
74 |
75 | public void setName(String name) {
76 | this.name = name;
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/gridviewpager_recycleview/src/main/java/cn/mtjsoft/www/gridviewpager_recycleview/view/AndDensityUtils.java:
--------------------------------------------------------------------------------
1 | package cn.mtjsoft.www.gridviewpager_recycleview.view;
2 |
3 | import android.content.Context;
4 |
5 | public class AndDensityUtils {
6 | /**
7 | * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
8 | */
9 | public static int dip2px(Context context, float dpValue) {
10 | final float scale = context.getResources().getDisplayMetrics().density;
11 | return (int) (dpValue * scale + 0.5f);
12 | }
13 |
14 | /**
15 | * 根据手机的分辨率从 px(像素) 的单位 转成为 dp
16 | */
17 | public static int px2dip(Context context, float pxValue) {
18 | final float scale = context.getResources().getDisplayMetrics().density;
19 | return (int) (pxValue / scale + 0.5f);
20 | }
21 |
22 | /**
23 | * 将px值转换为sp值,保证文字大小不变
24 | *
25 | * @param pxValue (DisplayMetrics类中属性scaledDensity)
26 | * @return
27 | */
28 | public static int px2sp(Context context, float pxValue) {
29 | final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
30 | return (int) (pxValue / fontScale + 0.5f);
31 | }
32 |
33 | /**
34 | * 将sp值转换为px值,保证文字大小不变
35 | *
36 | * @param spValue (DisplayMetrics类中属性scaledDensity)
37 | * @return
38 | */
39 | public static int sp2px(Context context, float spValue) {
40 | final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
41 | return (int) (spValue * fontScale + 0.5f);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/gridviewpager_recycleview/src/main/java/cn/mtjsoft/www/gridviewpager_recycleview/view/AndSelectCircleView.java:
--------------------------------------------------------------------------------
1 | package cn.mtjsoft.www.gridviewpager_recycleview.view;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.Context;
5 | import android.content.res.TypedArray;
6 | import android.graphics.Bitmap;
7 | import android.graphics.Bitmap.Config;
8 | import android.graphics.Canvas;
9 | import android.graphics.Color;
10 | import android.graphics.drawable.ColorDrawable;
11 | import android.graphics.drawable.Drawable;
12 | import android.graphics.drawable.StateListDrawable;
13 | import android.util.AttributeSet;
14 | import android.view.Gravity;
15 | import android.widget.LinearLayout;
16 | import android.widget.RadioButton;
17 | import android.widget.RadioGroup;
18 |
19 | import java.security.InvalidParameterException;
20 |
21 | import androidx.core.graphics.drawable.RoundedBitmapDrawable;
22 | import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
23 | import cn.mtjsoft.www.gridviewpager_recycleview.R;
24 |
25 |
26 | /**
27 | * 显示小圆点,表示当前选择的位置
28 | *
29 | * @author yuan
30 | */
31 | @SuppressLint("Recycle")
32 | public class AndSelectCircleView extends RadioGroup {
33 |
34 | private static final String tag = AndSelectCircleView.class.getSimpleName();
35 | //默认的子控件的大小,单位是dp
36 | private static final int DEAFULT_CHILD_SIZE = 8;
37 | //默认情况下子控件之间的间距,单位是dp
38 | private static final int DEFAULT_CHILD_MARGIN = 8;
39 | //默认显示的颜色值
40 | private static final int DEFAULT_NORMAL_COLOR = Color.GRAY;
41 | //默认选中显示的颜色值
42 | private static final int DEFAULT_SELECT_COLOR = Color.RED;
43 | //子控件显示的宽度
44 | private int mChildWidth = 0;
45 | //子控件显示的高度
46 | private int mChildHeight = 0;
47 | //两个子控件之间的间距
48 | private int mChildMargin = 0;
49 | //正常情况下显示的颜色
50 | private int mNormalColor = DEFAULT_NORMAL_COLOR;
51 | //选中的时候现实的颜色
52 | private int mSelectColor = DEFAULT_SELECT_COLOR;
53 | //正常情况下显示的drawable
54 | private Drawable mNormalDrawable = null;
55 | //选中情况下显示的drawable
56 | private Drawable mSelectDrawable = null;
57 | //是否显示圆点
58 | private boolean mIsCircle = true;
59 | //
60 | private PointCheckedChangeListener pointCheckedChangeListener;
61 |
62 | public AndSelectCircleView(Context context, AttributeSet attrs) {
63 | super(context, attrs);
64 | setOrientation(LinearLayout.HORIZONTAL);
65 | setGravity(Gravity.CENTER);
66 | TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.AndSelectCircleView);
67 | mChildWidth = attributes.getDimensionPixelSize(R.styleable.AndSelectCircleView_child_width, AndDensityUtils.dip2px(context, DEAFULT_CHILD_SIZE));
68 | mChildHeight = attributes.getDimensionPixelSize(R.styleable.AndSelectCircleView_child_height, AndDensityUtils.dip2px(context, DEAFULT_CHILD_SIZE));
69 | mChildMargin = attributes.getDimensionPixelSize(R.styleable.AndSelectCircleView_child_margin, AndDensityUtils.dip2px(context, DEFAULT_CHILD_MARGIN));
70 | mIsCircle = attributes.getBoolean(R.styleable.AndSelectCircleView_is_circle, true);
71 | mNormalColor = attributes.getColor(R.styleable.AndSelectCircleView_normal_color, DEFAULT_NORMAL_COLOR);
72 | mSelectColor = attributes.getColor(R.styleable.AndSelectCircleView_select_color, DEFAULT_SELECT_COLOR);
73 | attributes.recycle();
74 | }
75 |
76 | private Drawable getSpecialDrawable(boolean isNormal) {
77 | if (mIsCircle) {
78 | int width = Math.min(mChildHeight, mChildWidth);
79 | RoundedBitmapDrawable create = RoundedBitmapDrawableFactory.create(getResources(), getCircleDrawableBitmap(isNormal, width));
80 | create.setCircular(true);
81 | return create;
82 | } else {
83 | ColorDrawable drawable = new ColorDrawable(isNormal ? mNormalColor : mSelectColor);
84 | drawable.setBounds(0, 0, mChildWidth, mChildHeight);
85 | return drawable;
86 | }
87 | }
88 |
89 | private Bitmap getCircleDrawableBitmap(boolean isNormal, int width) {
90 | Bitmap bitmap = Bitmap.createBitmap(width, width, Config.RGB_565);
91 | Canvas canvas = new Canvas(bitmap);
92 | canvas.drawColor(isNormal ? mNormalColor : mSelectColor);
93 | return bitmap;
94 | }
95 |
96 | public AndSelectCircleView(Context context) {
97 | super(context);
98 | setOrientation(LinearLayout.HORIZONTAL);
99 | initView();
100 | }
101 |
102 | /**
103 | * 初始化控件
104 | */
105 | private void initView() {
106 | mChildHeight = AndDensityUtils.dip2px(getContext(), DEAFULT_CHILD_SIZE);
107 | mChildWidth = AndDensityUtils.dip2px(getContext(), DEAFULT_CHILD_SIZE);
108 | mChildMargin = AndDensityUtils.dip2px(getContext(), DEFAULT_CHILD_MARGIN);
109 | }
110 |
111 | /**
112 | * 设置宽度
113 | *
114 | * @param mChildWidth
115 | * @return
116 | */
117 | public AndSelectCircleView setmChildWidth(int mChildWidth) {
118 | this.mChildWidth = mChildWidth;
119 | return this;
120 | }
121 |
122 | public AndSelectCircleView setmChildHeight(int mChildHeight) {
123 | this.mChildHeight = mChildHeight;
124 | return this;
125 | }
126 |
127 | public AndSelectCircleView setmIsCircle(boolean mIsCircle) {
128 | this.mIsCircle = mIsCircle;
129 | return this;
130 | }
131 |
132 | public AndSelectCircleView setmChildMargin(int mChildMargin) {
133 | this.mChildMargin = mChildMargin;
134 | return this;
135 | }
136 |
137 | public AndSelectCircleView setmNormalColor(int mNormalColor) {
138 | this.mNormalColor = mNormalColor;
139 | return this;
140 | }
141 |
142 | public AndSelectCircleView setmSelectColor(int mSelectColor) {
143 | this.mSelectColor = mSelectColor;
144 | return this;
145 | }
146 |
147 | public AndSelectCircleView setPointCheckedChangeListener(PointCheckedChangeListener pointCheckedChangeListener) {
148 | this.pointCheckedChangeListener = pointCheckedChangeListener;
149 | return this;
150 | }
151 |
152 | /**
153 | * 添加子View
154 | *
155 | * @param count 添加的数量
156 | */
157 | @SuppressWarnings("deprecation")
158 | public void addChild(int count) {
159 | clear();
160 | if (count < 1) {
161 | return;
162 | }
163 | mNormalDrawable = getSpecialDrawable(true);
164 | mSelectDrawable = getSpecialDrawable(false);
165 | for (int index = 0; index < count; index++) {
166 | RadioButton button = new RadioButton(getContext());
167 | button.setId(index);
168 | StateListDrawable drawable = new StateListDrawable();
169 | drawable.addState(new int[]{android.R.attr.state_checked}, mSelectDrawable);
170 | drawable.addState(new int[]{}, mNormalDrawable);
171 | button.setButtonDrawable(new ColorDrawable(Color.TRANSPARENT));
172 | button.setBackgroundDrawable(drawable);
173 | LayoutParams params = new LayoutParams(mChildWidth, mChildHeight);
174 | if (index == 0) {
175 | button.setChecked(true);
176 | params.leftMargin = 0;
177 | } else {
178 | button.setChecked(false);
179 | params.leftMargin = mChildMargin;
180 | }
181 | addView(button, index, params);
182 | }
183 | setOnCheckedChangeListener(new OnCheckedChangeListener() {
184 | @Override
185 | public void onCheckedChanged(RadioGroup group, int checkedId) {
186 | if (pointCheckedChangeListener != null) {
187 | pointCheckedChangeListener.checkedChange(checkedId);
188 | }
189 | }
190 | });
191 | }
192 |
193 | /**
194 | * 设置选中的位置
195 | *
196 | * @param position
197 | */
198 | public void setSelectPosition(int position) {
199 | if (position < getChildCount() && position >= 0) {
200 | RadioButton button = (RadioButton) getChildAt(position);
201 | button.setChecked(true);
202 | }
203 | }
204 |
205 | /**
206 | * 清除所有
207 | */
208 | public void clear() {
209 | removeAllViews();
210 | }
211 |
212 | public interface PointCheckedChangeListener {
213 | void checkedChange(int position);
214 | }
215 |
216 | }
217 |
--------------------------------------------------------------------------------
/gridviewpager_recycleview/src/main/res/layout/gridpager_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
15 |
21 |
22 |
--------------------------------------------------------------------------------
/gridviewpager_recycleview/src/main/res/layout/gridpager_item_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/gridviewpager_recycleview/src/main/res/layout/gridpager_item_text.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/gridviewpager_recycleview/src/main/res/layout/gridpager_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
11 |
12 |
16 |
17 |
23 |
24 |
--------------------------------------------------------------------------------
/gridviewpager_recycleview/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/gridviewpager_recycleview/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/gridviewpager_recycleview/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/gridviewpager_recycleview/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/gridviewpager_recycleview/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
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 |
--------------------------------------------------------------------------------
/gridviewpager_recycleview/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | GridViewPager
3 |
4 |
--------------------------------------------------------------------------------
/gridviewpager_recycleview/src/test/java/cn/mtjsoft/www/gridviewpager_recycleview/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package cn.mtjsoft.www.gridviewpager_recycleview;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':gridviewpager_recycleview'
2 |
--------------------------------------------------------------------------------
/show.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/show.mp4
--------------------------------------------------------------------------------
/wxqrcode.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mtjsoft/GridPager/bc607ffc5024753d7bcea6c311336052cdddd3e0/wxqrcode.jpg
--------------------------------------------------------------------------------