├── .gitignore
├── LICENSE
├── README.md
├── app
├── .DS_Store
├── build.gradle
└── src
│ ├── .DS_Store
│ └── main
│ ├── AndroidManifest.xml
│ ├── assets
│ └── langs.json
│ ├── java
│ └── com
│ │ └── laowch
│ │ └── githubtrends
│ │ ├── Constants.java
│ │ ├── MyApplication.java
│ │ ├── helper
│ │ ├── ItemTouchHelperAdapter.java
│ │ ├── ItemTouchHelperViewHolder.java
│ │ ├── OnStartDragListener.java
│ │ └── SimpleItemTouchHelperCallback.java
│ │ ├── model
│ │ ├── Language.java
│ │ ├── Repo.java
│ │ └── User.java
│ │ ├── request
│ │ └── GsonRequest.java
│ │ ├── ui
│ │ ├── AboutActivity.java
│ │ ├── AddLanguageAdapter.java
│ │ ├── AddLanguagesActivity.java
│ │ ├── BaseActivity.java
│ │ ├── ConfirmDialog.java
│ │ ├── CustomLanguageAdapter.java
│ │ ├── CustomLanguagesActivity.java
│ │ ├── FavoritesActivity.java
│ │ ├── MainActivity.java
│ │ ├── RepoListAdapter.java
│ │ ├── RepoListFragment.java
│ │ └── ThemeDialog.java
│ │ └── utils
│ │ ├── AnalyticsHelper.java
│ │ ├── AsyncImageView.java
│ │ ├── AttrsHelper.java
│ │ ├── FavoReposHelper.java
│ │ ├── IntentUtils.java
│ │ ├── LanguageHelper.java
│ │ ├── PreferenceManager.java
│ │ └── Theme.java
│ ├── res
│ ├── drawable-hdpi
│ │ ├── ic_about.png
│ │ ├── ic_action_add.png
│ │ ├── ic_action_custom.png
│ │ ├── ic_action_favo.png
│ │ ├── ic_action_remove.png
│ │ ├── ic_action_theme.png
│ │ ├── ic_draggable.png
│ │ ├── ic_menu_white_24dp.png
│ │ ├── ic_remove.png
│ │ ├── ic_star_checked.png
│ │ └── ic_star_unchecked.png
│ ├── drawable-mdpi
│ │ ├── ic_about.png
│ │ ├── ic_action_add.png
│ │ ├── ic_action_custom.png
│ │ ├── ic_action_favo.png
│ │ ├── ic_action_remove.png
│ │ ├── ic_action_theme.png
│ │ ├── ic_draggable.png
│ │ ├── ic_menu_white_24dp.png
│ │ ├── ic_remove.png
│ │ ├── ic_star_checked.png
│ │ └── ic_star_unchecked.png
│ ├── drawable-xhdpi
│ │ ├── ic_about.png
│ │ ├── ic_action_add.png
│ │ ├── ic_action_custom.png
│ │ ├── ic_action_favo.png
│ │ ├── ic_action_remove.png
│ │ ├── ic_action_theme.png
│ │ ├── ic_draggable.png
│ │ ├── ic_menu_white_24dp.png
│ │ ├── ic_remove.png
│ │ ├── ic_star_checked.png
│ │ └── ic_star_unchecked.png
│ ├── drawable-xxhdpi
│ │ ├── ic_about.png
│ │ ├── ic_action_add.png
│ │ ├── ic_action_custom.png
│ │ ├── ic_action_favo.png
│ │ ├── ic_action_remove.png
│ │ ├── ic_action_theme.png
│ │ ├── ic_draggable.png
│ │ ├── ic_menu_white_24dp.png
│ │ ├── ic_remove.png
│ │ ├── ic_star_checked.png
│ │ ├── ic_star_unchecked.png
│ │ ├── spinner_triangle.png
│ │ └── spinner_triangle_sub.png
│ ├── drawable-xxxhdpi
│ │ ├── ic_about.png
│ │ ├── ic_action_add.png
│ │ ├── ic_action_custom.png
│ │ ├── ic_action_favo.png
│ │ ├── ic_action_remove.png
│ │ ├── ic_action_theme.png
│ │ ├── ic_draggable.png
│ │ ├── ic_menu_white_24dp.png
│ │ ├── ic_remove.png
│ │ ├── ic_star_checked.png
│ │ └── ic_star_unchecked.png
│ ├── drawable
│ │ └── image_loading_resource.xml
│ ├── layout
│ │ ├── activity_about.xml
│ │ ├── activity_main.xml
│ │ ├── activity_simple_recycler_view.xml
│ │ ├── add_language_grid_item.xml
│ │ ├── custom_language_grid_item.xml
│ │ ├── dialog_theme.xml
│ │ ├── drawer_header.xml
│ │ ├── fragment_main.xml
│ │ ├── fragment_repo_list.xml
│ │ ├── repo_list_item.xml
│ │ ├── toolbar_spinner.xml
│ │ ├── toolbar_spinner_item_actionbar.xml
│ │ └── toolbar_spinner_item_dropdown.xml
│ ├── menu
│ │ ├── menu_add_language.xml
│ │ ├── menu_custom_languages.xml
│ │ ├── menu_drawer.xml
│ │ └── menu_main.xml
│ ├── mipmap-hdpi
│ │ └── ic_launcher.png
│ ├── mipmap-mdpi
│ │ └── ic_launcher.png
│ ├── mipmap-xhdpi
│ │ └── ic_launcher.png
│ ├── mipmap-xxhdpi
│ │ └── ic_launcher.png
│ ├── mipmap-xxxhdpi
│ │ └── ic_launcher.png
│ ├── values-w820dp
│ │ └── dimens.xml
│ ├── values
│ │ ├── attrs.xml
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ ├── styles.xml
│ │ └── themes.xml
│ └── xml
│ │ └── analytics.xml
│ └── web_hi_res_512.png
├── build.gradle
├── screenshot
├── 1.png
├── 2.png
├── 3.png
├── 4.png
└── 5.png
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.ap_
4 |
5 | # Files for the Dalvik VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # Generated files
12 | bin/
13 | gen/
14 |
15 | # Gradle files
16 | .gradle/
17 | build/
18 | /*/build/
19 |
20 | # Local configuration file (sdk path, etc)
21 | local.properties
22 |
23 | # Proguard folder generated by Eclipse
24 | proguard/
25 |
26 | # Log Files
27 | *.log
28 |
29 | # Intellij project files
30 | *.iml
31 |
32 | # Gradle files
33 | gradlew*
34 |
35 | .DS_Store
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
203 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # GithubTrends
2 |
3 | 这是一个用来看查看 Github 热门项目的 Android App, 遵循 Material Design。
4 | (https://github.com/trending)
5 |
6 | 支持订阅 50 多种编程语言,你可以在设置中添加/删除它们,并自定义它们的排序。
7 |
8 | 支持 9 种颜色主题切换,支持收藏喜欢的项目。
9 |
10 | It's a GitHub Trending repositories Viewer with Material Design. (https://github.com/trending)
11 |
12 | It supports more than 50+ program languages and you are free to add/remove/sort them.
13 |
14 | It supports nine kinds of color themes.
15 |
16 | #Downloads
17 | Google Play: [https://play.google.com/store/apps/details?id=com.laowch.githubtrends.play](https://play.google.com/store/apps/details?id=com.laowch.githubtrends.play2&utm=github)
18 |
19 |
20 | 如果喜欢,请给个五星好评,非常感谢!
21 |
22 |
23 | #Screenshots
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/app/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/.DS_Store
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "23.0.1"
6 |
7 | defaultConfig {
8 | applicationId "com.laowch.githubtrends"
9 | minSdkVersion 14
10 | targetSdkVersion 23
11 | versionCode 1
12 | versionName "1.0"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(dir: 'libs', include: ['*.jar'])
24 | compile 'com.android.support:appcompat-v7:23.0.1'
25 | compile 'com.android.support:cardview-v7:23.0.1'
26 | compile 'com.android.support:recyclerview-v7:23.0.1'
27 |
28 | compile 'com.android.support:design:23.0.1'
29 |
30 | compile 'com.google.code.gson:gson:2.3'
31 |
32 | compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.4'
33 |
34 | compile 'com.google.android.gms:play-services:7.5.0'
35 |
36 | compile 'com.mcxiaoke.volley:library:1.0.19'
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/.DS_Store
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
16 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
29 |
30 |
33 |
34 |
37 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/app/src/main/assets/langs.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "path": "",
4 | "name": "All Language",
5 | "short_name": "All"
6 | },
7 | {
8 | "path": "unknown",
9 | "name": "Unknown"
10 | },
11 | {
12 | "path": "as3",
13 | "name": "ActionScript",
14 | "short_name": "AS"
15 | },
16 | {
17 | "path": "apacheconf",
18 | "name": "ApacheConf"
19 | },
20 | {
21 | "path": "arduino",
22 | "name": "Arduino"
23 | },
24 | {
25 | "path": "nasm",
26 | "name": "Assembly",
27 | "short_name": "NASM"
28 | },
29 | {
30 | "path": "bat",
31 | "name": "Batchfile",
32 | "short_name": "BAT"
33 | },
34 | {
35 | "path": "c",
36 | "name": "C"
37 | },
38 | {
39 | "path": "csharp",
40 | "name": "C#"
41 | },
42 | {
43 | "path": "cpp",
44 | "name": "C++"
45 | },
46 | {
47 | "path": "cmake",
48 | "name": "CMake"
49 | },
50 | {
51 | "path": "css",
52 | "name": "CSS"
53 | },
54 | {
55 | "path": "clojure",
56 | "name": "Clojure"
57 | },
58 | {
59 | "path": "coffeescript",
60 | "name": "CoffeeScript"
61 | },
62 | {
63 | "path": "common-lisp",
64 | "short_name": "Lisp",
65 | "name": "Common Lisp"
66 | },
67 | {
68 | "path": "crystal",
69 | "name": "Crystal"
70 | },
71 | {
72 | "path": "d",
73 | "name": "D"
74 | },
75 | {
76 | "path": "dart",
77 | "name": "Dart"
78 | },
79 | {
80 | "path": "elixir",
81 | "name": "Elixir"
82 | },
83 | {
84 | "path": "emacs-lisp",
85 | "short_name": "Lisp",
86 | "name": "Emacs Lisp"
87 | },
88 | {
89 | "path": "erlang",
90 | "name": "Erlang"
91 | },
92 | {
93 | "path": "fsharp",
94 | "name": "F#"
95 | },
96 | {
97 | "path": "game-maker-language",
98 | "short_name": "GML",
99 | "name": "Game Maker Language"
100 | },
101 | {
102 | "path": "go",
103 | "name": "Go"
104 | },
105 | {
106 | "path": "groovy",
107 | "name": "Groovy"
108 | },
109 | {
110 | "path": "html",
111 | "name": "HTML"
112 | },
113 | {
114 | "path": "haskell",
115 | "name": "Haskell"
116 | },
117 | {
118 | "path": "haxe",
119 | "name": "Haxe"
120 | },
121 | {
122 | "path": "inno-setup",
123 | "short_name": "Inno",
124 | "name": "Inno Setup"
125 | },
126 | {
127 | "path": "java",
128 | "name": "Java"
129 | },
130 | {
131 | "path": "javascript",
132 | "short_name": "JS",
133 | "name": "JavaScript"
134 | },
135 | {
136 | "path": "julia",
137 | "name": "Julia"
138 | },
139 | {
140 | "path": "kotlin",
141 | "name": "Kotlin"
142 | },
143 | {
144 | "path": "livescript",
145 | "short_name": "LS",
146 | "name": "LiveScript"
147 | },
148 | {
149 | "path": "lua",
150 | "name": "Lua"
151 | },
152 | {
153 | "path": "makefile",
154 | "name": "Makefile"
155 | },
156 | {
157 | "path": "markdown",
158 | "name": "Markdown"
159 | },
160 | {
161 | "path": "mathematica",
162 | "name": "Mathematica"
163 | },
164 | {
165 | "path": "matlab",
166 | "name": "Matlab"
167 | },
168 | {
169 | "path": "nsis",
170 | "name": "NSIS"
171 | },
172 | {
173 | "path": "nimrod",
174 | "name": "Nimrod"
175 | },
176 | {
177 | "path": "ocaml",
178 | "name": "OCaml"
179 | },
180 | {
181 | "short_name": "Obj-C",
182 | "path": "objective-c",
183 | "name": "Objective-C"
184 | },
185 | {
186 | "short_name": "Obj-C++",
187 | "path": "objective-c%2B%2B",
188 | "name": "Objective-C++"
189 | },
190 | {
191 | "path": "php",
192 | "name": "PHP"
193 | },
194 | {
195 | "path": "plsql",
196 | "name": "PLSQL"
197 | },
198 | {
199 | "path": "pascal",
200 | "name": "Pascal"
201 | },
202 | {
203 | "path": "perl",
204 | "name": "Perl"
205 | },
206 | {
207 | "path": "postscript",
208 | "name": "PostScript"
209 | },
210 | {
211 | "path": "powershell",
212 | "name": "PowerShell"
213 | },
214 | {
215 | "path": "python",
216 | "name": "Python"
217 | },
218 | {
219 | "path": "qml",
220 | "name": "QML"
221 | },
222 | {
223 | "path": "r",
224 | "name": "R"
225 | },
226 | {
227 | "path": "ruby",
228 | "name": "Ruby"
229 | },
230 | {
231 | "path": "rust",
232 | "name": "Rust"
233 | },
234 | {
235 | "path": "scala",
236 | "name": "Scala"
237 | },
238 | {
239 | "path": "scheme",
240 | "name": "Scheme"
241 | },
242 | {
243 | "path": "bash",
244 | "name": "Shell"
245 | },
246 | {
247 | "path": "supercollider",
248 | "name": "SuperCollider"
249 | },
250 | {
251 | "path": "swift",
252 | "name": "Swift"
253 | },
254 | {
255 | "path": "tex",
256 | "name": "TeX"
257 | },
258 | {
259 | "path": "typescript",
260 | "name": "TypeScript"
261 | },
262 | {
263 | "path": "verilog",
264 | "name": "Verilog"
265 | },
266 | {
267 | "path": "vhdl",
268 | "name": "VHDL"
269 | },
270 | {
271 | "path": "vue",
272 | "name": "Vue"
273 | },
274 | {
275 | "path": "xml",
276 | "name": "XML"
277 | }
278 | {
279 | "path": "xslt",
280 | "name": "XSLT"
281 | }
282 | ]
283 |
--------------------------------------------------------------------------------
/app/src/main/java/com/laowch/githubtrends/Constants.java:
--------------------------------------------------------------------------------
1 | package com.laowch.githubtrends;
2 |
3 | /**
4 | * Created by lao on 15/9/23.
5 | */
6 | public class Constants {
7 |
8 | public static final String URL = "http://github.laowch.com/json/";
9 |
10 |
11 | public static final int MODE_DRAGGABLE = 1;
12 |
13 | public static final int MODE_REMOVE = 3;
14 |
15 |
16 | public static final String ACTION_SELECTED_LANGUAGES_CHANGE = "action_selected_languages_change";
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/main/java/com/laowch/githubtrends/MyApplication.java:
--------------------------------------------------------------------------------
1 | package com.laowch.githubtrends;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 |
6 | import com.google.gson.Gson;
7 | import com.google.gson.GsonBuilder;
8 | import com.laowch.githubtrends.utils.AnalyticsHelper;
9 | import com.laowch.githubtrends.utils.FavoReposHelper;
10 | import com.laowch.githubtrends.utils.LanguageHelper;
11 | import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator;
12 | import com.nostra13.universalimageloader.core.ImageLoader;
13 | import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
14 | import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
15 |
16 | /**
17 | * Created by lao on 15/9/23.
18 | */
19 | public class MyApplication extends Application {
20 |
21 | @Override
22 | public void onCreate() {
23 | super.onCreate();
24 | AnalyticsHelper.initialize(this);
25 | LanguageHelper.init(this);
26 | FavoReposHelper.init(this);
27 | initImageLoader(this);
28 | }
29 |
30 |
31 | public void initImageLoader(Context context) {
32 | // This configuration tuning is custom. You can tune every option, you may tune some of them,
33 | // or you can create default configuration by
34 | // ImageLoaderConfiguration.createDefault(this);
35 | // method.
36 | ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
37 | .threadPriority(Thread.NORM_PRIORITY - 2)
38 | .denyCacheImageMultipleSizesInMemory()
39 | .memoryCacheSizePercentage(25)
40 | .diskCacheFileNameGenerator(new Md5FileNameGenerator())
41 | .diskCacheSize(100 * 1024 * 1024)
42 | .tasksProcessingOrder(QueueProcessingType.LIFO)
43 | .writeDebugLogs() // Remove for release app
44 | .build();
45 | // Initialize ImageLoader with configuration.
46 | ImageLoader.getInstance().init(config);
47 | }
48 |
49 |
50 | public static Gson getGson() {
51 | GsonBuilder builder = new GsonBuilder();
52 | // config builder
53 | return builder.create();
54 | }
55 |
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/app/src/main/java/com/laowch/githubtrends/helper/ItemTouchHelperAdapter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Paul Burke
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.laowch.githubtrends.helper;
18 |
19 | import android.support.v7.widget.RecyclerView;
20 | import android.support.v7.widget.helper.ItemTouchHelper;
21 |
22 | /**
23 | * Interface to listen for a move or dismissal event from a {@link ItemTouchHelper.Callback}.
24 | *
25 | * @author Paul Burke (ipaulpro)
26 | */
27 | public interface ItemTouchHelperAdapter {
28 |
29 | /**
30 | * Called when an item has been dragged far enough to trigger a move. This is called every time
31 | * an item is shifted, and not at the end of a "drop" event.
32 | *
33 | * Implementations should call {@link RecyclerView.Adapter#notifyItemMoved(int, int)} after
34 | * adjusting the underlying data to reflect this move.
35 | *
36 | * @param fromPosition The start position of the moved item.
37 | * @param toPosition Then resolved position of the moved item.
38 | * @return True if the item was moved to the new adapter position.
39 | *
40 | * @see RecyclerView#getAdapterPositionFor(RecyclerView.ViewHolder)
41 | * @see RecyclerView.ViewHolder#getAdapterPosition()
42 | */
43 | boolean onItemMove(int fromPosition, int toPosition);
44 |
45 |
46 | /**
47 | * Called when an item has been dismissed by a swipe.
48 | *
49 | * Implementations should call {@link RecyclerView.Adapter#notifyItemRemoved(int)} after
50 | * adjusting the underlying data to reflect this removal.
51 | *
52 | * @param position The position of the item dismissed.
53 | *
54 | * @see RecyclerView#getAdapterPositionFor(RecyclerView.ViewHolder)
55 | * @see RecyclerView.ViewHolder#getAdapterPosition()
56 | */
57 | void onItemDismiss(int position);
58 | }
59 |
--------------------------------------------------------------------------------
/app/src/main/java/com/laowch/githubtrends/helper/ItemTouchHelperViewHolder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Paul Burke
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.laowch.githubtrends.helper;
18 |
19 | import android.support.v7.widget.helper.ItemTouchHelper;
20 |
21 | /**
22 | * Interface to notify an item ViewHolder of relevant callbacks from {@link
23 | * android.support.v7.widget.helper.ItemTouchHelper.Callback}.
24 | *
25 | * @author Paul Burke (ipaulpro)
26 | */
27 | public interface ItemTouchHelperViewHolder {
28 |
29 | /**
30 | * Called when the {@link ItemTouchHelper} first registers an item as being moved or swiped.
31 | * Implementations should update the item view to indicate it's active state.
32 | */
33 | void onItemSelected();
34 |
35 |
36 | /**
37 | * Called when the {@link ItemTouchHelper} has completed the move or swipe, and the active item
38 | * state should be cleared.
39 | */
40 | void onItemClear();
41 | }
42 |
--------------------------------------------------------------------------------
/app/src/main/java/com/laowch/githubtrends/helper/OnStartDragListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Paul Burke
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.laowch.githubtrends.helper;
18 |
19 | import android.support.v7.widget.RecyclerView;
20 |
21 | /**
22 | * Listener for manual initiation of a drag.
23 | */
24 | public interface OnStartDragListener {
25 |
26 | /**
27 | * Called when a view is requesting a start of a drag.
28 | *
29 | * @param viewHolder The holder of the view to drag.
30 | */
31 | void onStartDrag(RecyclerView.ViewHolder viewHolder);
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/laowch/githubtrends/helper/SimpleItemTouchHelperCallback.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Paul Burke
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.laowch.githubtrends.helper;
18 |
19 | import android.graphics.Canvas;
20 | import android.support.v7.widget.GridLayoutManager;
21 | import android.support.v7.widget.RecyclerView;
22 | import android.support.v7.widget.helper.ItemTouchHelper;
23 |
24 | /**
25 | * An implementation of {@link ItemTouchHelper.Callback} that enables basic drag & drop and
26 | * swipe-to-dismiss. Drag events are automatically started by an item long-press.
27 | *
28 | * Expects the RecyclerView.Adapter
to listen for {@link
29 | * ItemTouchHelperAdapter} callbacks and the RecyclerView.ViewHolder
to implement
30 | * {@link ItemTouchHelperViewHolder}.
31 | *
32 | * @author Paul Burke (ipaulpro)
33 | */
34 | public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback {
35 |
36 | public static final float ALPHA_FULL = 1.0f;
37 |
38 | private final ItemTouchHelperAdapter mAdapter;
39 |
40 | public SimpleItemTouchHelperCallback(ItemTouchHelperAdapter adapter) {
41 | mAdapter = adapter;
42 | }
43 |
44 | @Override
45 | public boolean isLongPressDragEnabled() {
46 | return true;
47 | }
48 |
49 | @Override
50 | public boolean isItemViewSwipeEnabled() {
51 | return true;
52 | }
53 |
54 | @Override
55 | public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
56 | // Set movement flags based on the layout manager
57 | if (recyclerView.getLayoutManager() instanceof GridLayoutManager) {
58 | final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
59 | final int swipeFlags = 0;
60 | return makeMovementFlags(dragFlags, swipeFlags);
61 | } else {
62 | final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
63 | final int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
64 | return makeMovementFlags(dragFlags, swipeFlags);
65 | }
66 | }
67 |
68 | @Override
69 | public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) {
70 | if (source.getItemViewType() != target.getItemViewType()) {
71 | return false;
72 | }
73 |
74 | // Notify the adapter of the move
75 | mAdapter.onItemMove(source.getAdapterPosition(), target.getAdapterPosition());
76 | return true;
77 | }
78 |
79 | @Override
80 | public void onSwiped(RecyclerView.ViewHolder viewHolder, int i) {
81 | // Notify the adapter of the dismissal
82 | mAdapter.onItemDismiss(viewHolder.getAdapterPosition());
83 | }
84 |
85 | @Override
86 | public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
87 | if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
88 | // Fade out the view as it is swiped out of the parent's bounds
89 | final float alpha = ALPHA_FULL - Math.abs(dX) / (float) viewHolder.itemView.getWidth();
90 | viewHolder.itemView.setAlpha(alpha);
91 | viewHolder.itemView.setTranslationX(dX);
92 | } else {
93 | super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
94 | }
95 | }
96 |
97 | @Override
98 | public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
99 | // We only want the active item to change
100 | if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
101 | if (viewHolder instanceof ItemTouchHelperViewHolder) {
102 | // Let the view holder know that this item is being moved or dragged
103 | ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder;
104 | itemViewHolder.onItemSelected();
105 | }
106 | }
107 |
108 | super.onSelectedChanged(viewHolder, actionState);
109 | }
110 |
111 | @Override
112 | public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
113 | super.clearView(recyclerView, viewHolder);
114 |
115 | viewHolder.itemView.setAlpha(ALPHA_FULL);
116 |
117 | if (viewHolder instanceof ItemTouchHelperViewHolder) {
118 | // Tell the view holder it's time to restore the idle state
119 | ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder;
120 | itemViewHolder.onItemClear();
121 | }
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/app/src/main/java/com/laowch/githubtrends/model/Language.java:
--------------------------------------------------------------------------------
1 | package com.laowch.githubtrends.model;
2 |
3 | import com.google.gson.annotations.SerializedName;
4 |
5 | import java.io.Serializable;
6 |
7 | /**
8 | * Created by lao on 15/9/23.
9 | */
10 | public class Language implements Serializable {
11 | public String name;
12 |
13 | public String path;
14 |
15 | @SerializedName("short_name")
16 | private String shortName;
17 |
18 | public String getShortName() {
19 | return shortName == null ? name : shortName;
20 | }
21 |
22 | public Language() {
23 | }
24 |
25 | public Language(String name, String path) {
26 | this.name = name;
27 | this.path = path;
28 | }
29 |
30 | @Override
31 | public boolean equals(Object o) {
32 | if (o instanceof Language) {
33 | return name.equals(((Language) o).name);
34 | }
35 | return false;
36 | }
37 |
38 | @Override
39 | public int hashCode() {
40 | return name.hashCode();
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/app/src/main/java/com/laowch/githubtrends/model/Repo.java:
--------------------------------------------------------------------------------
1 | package com.laowch.githubtrends.model;
2 |
3 | import com.google.gson.annotations.SerializedName;
4 |
5 | import java.util.List;
6 |
7 | /**
8 | * Created by lao on 15/9/23.
9 | */
10 | public class Repo {
11 |
12 | public String name;
13 |
14 | public String owner;
15 |
16 | @SerializedName("link")
17 | public String url;
18 |
19 | @SerializedName("des")
20 | public String description;
21 | public String meta;
22 |
23 | public String language;
24 |
25 | public List contributors;
26 |
27 | @Override
28 | public boolean equals(Object o) {
29 | if (o instanceof Repo) {
30 | return name.equals(((Repo) o).name) && owner.equals(((Repo) o).owner);
31 | }
32 | return false;
33 | }
34 |
35 | @Override
36 | public int hashCode() {
37 | return name.hashCode() + owner.hashCode();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/app/src/main/java/com/laowch/githubtrends/model/User.java:
--------------------------------------------------------------------------------
1 | package com.laowch.githubtrends.model;
2 |
3 | /**
4 | * Created by lao on 15/9/23.
5 | */
6 | public class User {
7 |
8 | public String name;
9 |
10 | public String avatar;
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/com/laowch/githubtrends/request/GsonRequest.java:
--------------------------------------------------------------------------------
1 | package com.laowch.githubtrends.request;
2 |
3 | import com.android.volley.NetworkResponse;
4 | import com.android.volley.ParseError;
5 | import com.android.volley.Request;
6 | import com.android.volley.Response;
7 | import com.android.volley.toolbox.HttpHeaderParser;
8 | import com.google.gson.Gson;
9 | import com.google.gson.JsonSyntaxException;
10 |
11 | import java.io.UnsupportedEncodingException;
12 |
13 | /**
14 | * Created by lao on 15/9/23.
15 | */
16 | public class GsonRequest extends Request {
17 | private final Gson gson = new Gson();
18 | private final Class clazz;
19 | private final Response.Listener listener;
20 |
21 | /**
22 | * Make a GET request and return a parsed object from JSON.
23 | *
24 | * @param url URL of the request to make
25 | * @param clazz Relevant class object, for Gson's reflection
26 | */
27 | public GsonRequest(String url, Class clazz, Response.Listener listener, Response.ErrorListener errorListener) {
28 | super(Method.GET, url, errorListener);
29 | this.clazz = clazz;
30 | this.listener = listener;
31 | }
32 |
33 |
34 | @Override
35 | protected void deliverResponse(T response) {
36 | listener.onResponse(response);
37 | }
38 |
39 | @Override
40 | protected Response parseNetworkResponse(NetworkResponse response) {
41 | try {
42 | String json = new String(
43 | response.data,
44 | HttpHeaderParser.parseCharset(response.headers));
45 | return Response.success(
46 | gson.fromJson(json, clazz),
47 | HttpHeaderParser.parseCacheHeaders(response));
48 | } catch (UnsupportedEncodingException e) {
49 | return Response.error(new ParseError(e));
50 | } catch (JsonSyntaxException e) {
51 | return Response.error(new ParseError(e));
52 | }
53 | }
54 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/laowch/githubtrends/ui/AboutActivity.java:
--------------------------------------------------------------------------------
1 | package com.laowch.githubtrends.ui;
2 |
3 | import android.os.Bundle;
4 | import android.text.Html;
5 | import android.widget.TextView;
6 |
7 | import com.google.android.gms.ads.AdRequest;
8 | import com.google.android.gms.ads.AdView;
9 | import com.laowch.githubtrends.R;
10 |
11 | /**
12 | * Created by lao on 10/5/15.
13 | */
14 | public class AboutActivity extends BaseActivity {
15 |
16 | String aboutText = "It's a GitHub Trending repositories Viewer with Material Design.
" +
17 | "https://github.com/trending";
18 |
19 | @Override
20 | protected void onCreate(Bundle savedInstanceState) {
21 | super.onCreate(savedInstanceState);
22 | setContentView(R.layout.activity_about);
23 | ((TextView) findViewById(R.id.about)).setText(Html.fromHtml(aboutText));
24 |
25 | final AdView mAdView = (AdView) findViewById(R.id.adView);
26 | AdRequest adRequest = new AdRequest.Builder().build();
27 | mAdView.loadAd(adRequest);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/java/com/laowch/githubtrends/ui/AddLanguageAdapter.java:
--------------------------------------------------------------------------------
1 | package com.laowch.githubtrends.ui;
2 |
3 | import android.content.Context;
4 | import android.support.v7.widget.RecyclerView;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.CheckBox;
9 | import android.widget.CompoundButton;
10 | import android.widget.TextView;
11 |
12 | import com.laowch.githubtrends.R;
13 | import com.laowch.githubtrends.model.Language;
14 |
15 | import java.util.ArrayList;
16 | import java.util.Arrays;
17 | import java.util.LinkedList;
18 | import java.util.List;
19 |
20 | /**
21 | * Created by lao on 15/9/28.
22 | */
23 | public class AddLanguageAdapter extends RecyclerView.Adapter {
24 |
25 | Context context;
26 |
27 | List mItems = new ArrayList<>();
28 |
29 | LinkedList selectedItems = new LinkedList<>();
30 |
31 | public AddLanguageAdapter(Context context) {
32 | this.context = context;
33 | }
34 |
35 |
36 | @Override
37 | public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
38 | View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.add_language_grid_item, parent, false);
39 |
40 | return new ViewHolder(v);
41 | }
42 |
43 | @Override
44 | public void onBindViewHolder(final ViewHolder viewHolder, int position) {
45 | final Language language = mItems.get(position);
46 | viewHolder.text.setText(language.name);
47 |
48 | viewHolder.checkBox.setOnCheckedChangeListener(null);
49 |
50 | viewHolder.checkBox.setChecked(selectedItems.contains(language));
51 |
52 | viewHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
53 | @Override
54 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
55 | if (isChecked) {
56 | selectedItems.add(language);
57 | } else {
58 | selectedItems.remove(language);
59 | }
60 | }
61 | });
62 | }
63 |
64 | @Override
65 | public int getItemCount() {
66 | return mItems.size();
67 | }
68 |
69 | public void setItems(Language[] items) {
70 | mItems.clear();
71 | mItems.addAll(Arrays.asList(items));
72 | notifyDataSetChanged();
73 | }
74 |
75 | public List getSelectedItems() {
76 | return selectedItems;
77 | }
78 |
79 |
80 | public class ViewHolder extends RecyclerView.ViewHolder {
81 |
82 | private TextView text;
83 |
84 | private CheckBox checkBox;
85 |
86 | public ViewHolder(final View itemView) {
87 | super(itemView);
88 | text = (TextView) itemView.findViewById(R.id.text);
89 | checkBox = (CheckBox) itemView.findViewById(R.id.checkbox);
90 |
91 |
92 | itemView.setOnClickListener(new View.OnClickListener() {
93 | @Override
94 | public void onClick(View v) {
95 | checkBox.toggle();
96 | }
97 | });
98 | }
99 |
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/app/src/main/java/com/laowch/githubtrends/ui/AddLanguagesActivity.java:
--------------------------------------------------------------------------------
1 | package com.laowch.githubtrends.ui;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.support.v4.content.LocalBroadcastManager;
6 | import android.support.v7.app.ActionBar;
7 | import android.support.v7.widget.GridLayoutManager;
8 | import android.support.v7.widget.RecyclerView;
9 | import android.support.v7.widget.Toolbar;
10 | import android.view.Menu;
11 | import android.view.MenuItem;
12 |
13 | import com.laowch.githubtrends.Constants;
14 | import com.laowch.githubtrends.R;
15 | import com.laowch.githubtrends.model.Language;
16 | import com.laowch.githubtrends.utils.AnalyticsHelper;
17 | import com.laowch.githubtrends.utils.LanguageHelper;
18 |
19 | import java.util.List;
20 |
21 | /**
22 | * Created by lao on 15/9/28.
23 | */
24 | public class AddLanguagesActivity extends BaseActivity {
25 |
26 | AddLanguageAdapter adapter;
27 |
28 | @Override
29 | protected void onCreate(Bundle savedInstanceState) {
30 | super.onCreate(savedInstanceState);
31 | setContentView(R.layout.activity_simple_recycler_view);
32 |
33 |
34 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
35 | setSupportActionBar(toolbar);
36 | ActionBar actionBar = getSupportActionBar();
37 | actionBar.setDisplayHomeAsUpEnabled(true);
38 |
39 |
40 | adapter = new AddLanguageAdapter(getContext());
41 |
42 | RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
43 | recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2));
44 | recyclerView.setAdapter(adapter);
45 |
46 | adapter.setItems(LanguageHelper.getInstance().getUnselectedLanguages());
47 |
48 | }
49 |
50 | @Override
51 | public boolean onCreateOptionsMenu(Menu menu) {
52 | getMenuInflater().inflate(R.menu.menu_add_language, menu);
53 | return super.onCreateOptionsMenu(menu);
54 | }
55 |
56 | @Override
57 | public boolean onOptionsItemSelected(MenuItem item) {
58 |
59 | switch (item.getItemId()) {
60 | case R.id.action_done:
61 | AnalyticsHelper.sendEvent("AddLangs", "Menu", "Done", 0l);
62 |
63 | List selectedItems = adapter.getSelectedItems();
64 | if (selectedItems.size() > 0) {
65 | LanguageHelper.getInstance().addSelectedLanguages(selectedItems);
66 | }
67 |
68 | LocalBroadcastManager.getInstance(getContext()).sendBroadcast(new Intent(Constants.ACTION_SELECTED_LANGUAGES_CHANGE));
69 |
70 | finish();
71 | return true;
72 | }
73 | return super.onOptionsItemSelected(item);
74 | }
75 |
76 | @Override
77 | public void onBackPressed() {
78 | final List selectedItems = adapter.getSelectedItems();
79 | if (selectedItems.size() > 0) {
80 | ConfirmDialog confirmDialog = ConfirmDialog.newInstance("Confirm Exit", "Do you want to save your changes before exiting?", R.string.save, R.string.not_save);
81 | confirmDialog.setConfirmDialogListener(new ConfirmDialog.IConfirmDialogListener() {
82 | @Override
83 | public void onConfirm() {
84 | AnalyticsHelper.sendEvent("AddLangs", "ExitDialog", "Save", 0l);
85 | LanguageHelper.getInstance().addSelectedLanguages(selectedItems);
86 | LocalBroadcastManager.getInstance(getContext()).sendBroadcast(new Intent(Constants.ACTION_SELECTED_LANGUAGES_CHANGE));
87 | finish();
88 | }
89 | });
90 | confirmDialog.setNegativeClickListener(new ConfirmDialog.INegativeClickListener() {
91 | @Override
92 | public void onNegativeButtonClick() {
93 | AnalyticsHelper.sendEvent("AddLangs", "ExitDialog", "GiveUp", 0l);
94 | finish();
95 | }
96 | });
97 | confirmDialog.show(getSupportFragmentManager(), "confirm");
98 | } else {
99 | super.onBackPressed();
100 | }
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/app/src/main/java/com/laowch/githubtrends/ui/BaseActivity.java:
--------------------------------------------------------------------------------
1 | package com.laowch.githubtrends.ui;
2 |
3 | import android.content.Context;
4 | import android.os.Bundle;
5 | import android.support.v7.app.AppCompatActivity;
6 | import android.view.MenuItem;
7 |
8 | import com.laowch.githubtrends.R;
9 | import com.laowch.githubtrends.utils.PreferenceManager;
10 | import com.laowch.githubtrends.utils.Theme;
11 |
12 | /**
13 | * Created by lao on 15/9/23.
14 | */
15 | public class BaseActivity extends AppCompatActivity {
16 |
17 | protected void onPreCreate() {
18 | final Theme currentTheme = PreferenceManager.getCurrentTheme(this);
19 |
20 | switch (currentTheme) {
21 | case Blue:
22 | this.setTheme(R.style.BlueTheme);
23 | break;
24 | case Green:
25 | this.setTheme(R.style.GreenTheme);
26 | break;
27 | case Red:
28 | this.setTheme(R.style.RedTheme);
29 | break;
30 | case Indigo:
31 | this.setTheme(R.style.IndigoTheme);
32 | break;
33 | case BlueGrey:
34 | this.setTheme(R.style.BlueGreyTheme);
35 | break;
36 | case Black:
37 | this.setTheme(R.style.BlackTheme);
38 | break;
39 | case Orange:
40 | this.setTheme(R.style.OrangeTheme);
41 | break;
42 | case Purple:
43 | this.setTheme(R.style.PurpleTheme);
44 | break;
45 | case Pink:
46 | this.setTheme(R.style.PinkTheme);
47 | break;
48 | default:
49 | this.setTheme(R.style.BlueTheme);
50 | break;
51 | }
52 | }
53 |
54 | @Override
55 | protected void onCreate(Bundle savedInstanceState) {
56 | onPreCreate();
57 | super.onCreate(savedInstanceState);
58 | }
59 |
60 | public Context getContext() {
61 | return this;
62 | }
63 |
64 | @Override
65 | public boolean onOptionsItemSelected(MenuItem item) {
66 | switch (item.getItemId()) {
67 | case android.R.id.home:
68 | onBackPressed();
69 | return true;
70 | }
71 |
72 | return super.onOptionsItemSelected(item);
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/app/src/main/java/com/laowch/githubtrends/ui/ConfirmDialog.java:
--------------------------------------------------------------------------------
1 | package com.laowch.githubtrends.ui;
2 |
3 | import android.app.AlertDialog;
4 | import android.app.Dialog;
5 | import android.content.DialogInterface;
6 | import android.os.Bundle;
7 | import android.support.v4.app.DialogFragment;
8 |
9 | /**
10 | * Created by laowch on 4/15/14.
11 | */
12 | public class ConfirmDialog extends DialogFragment implements DialogInterface.OnClickListener {
13 |
14 | private final static String EXTRA_TITLE = "extra_title";
15 |
16 | private final static String EXTRA_MESSAGE = "extra_message";
17 |
18 | private final static String EXTRA_POSITIVE_TEXT = "extra_positive_text";
19 |
20 | private final static String EXTRA_NEGATIVE_TEXT = "extra_negative_text";
21 |
22 | public final static int HIDE_BUTTON = -1;
23 |
24 | private IConfirmDialogListener confirmDialogListener;
25 |
26 | private INegativeClickListener negativeClickListener;
27 |
28 | public static ConfirmDialog newInstance(final String pTitle, final String pMessage) {
29 | return newInstance(pTitle, pMessage, 0, 0);
30 | }
31 |
32 | public static ConfirmDialog newInstance(final String pTitle, final String pMessage, final int positiveText, final int negativeText) {
33 | ConfirmDialog dialog = new ConfirmDialog();
34 | Bundle bundle = new Bundle();
35 | bundle.putString(EXTRA_TITLE, pTitle);
36 | bundle.putString(EXTRA_MESSAGE, pMessage);
37 | bundle.putInt(EXTRA_POSITIVE_TEXT, positiveText);
38 | bundle.putInt(EXTRA_NEGATIVE_TEXT, negativeText);
39 | dialog.setArguments(bundle);
40 |
41 | return dialog;
42 | }
43 |
44 |
45 | public ConfirmDialog() {
46 | }
47 |
48 | public void setConfirmDialogListener(IConfirmDialogListener pConfirmDialogListener) {
49 | this.confirmDialogListener = pConfirmDialogListener;
50 | }
51 |
52 | public void setNegativeClickListener(INegativeClickListener negativeClickListener) {
53 | this.negativeClickListener = negativeClickListener;
54 | }
55 |
56 | @Override
57 | public Dialog onCreateDialog(Bundle savedInstanceState) {
58 |
59 | AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
60 | builder.setTitle(getArguments().getString(EXTRA_TITLE));
61 | builder.setMessage(getArguments().getString(EXTRA_MESSAGE));
62 |
63 | final int negativeText = getArguments().getInt(EXTRA_NEGATIVE_TEXT, 0);
64 | final int positiveText = getArguments().getInt(EXTRA_POSITIVE_TEXT, 0);
65 |
66 | if (positiveText != HIDE_BUTTON) {
67 | builder.setPositiveButton(positiveText == 0 ? android.R.string.ok : positiveText, this);
68 | }
69 |
70 | if (negativeText != HIDE_BUTTON) {
71 | builder.setNegativeButton(negativeText == 0 ? android.R.string.cancel : negativeText, this);
72 | }
73 |
74 | return builder.create();
75 | }
76 |
77 | @Override
78 | public void onClick(final DialogInterface pDialog, final int pWhich) {
79 | switch (pWhich) {
80 | case DialogInterface.BUTTON_NEGATIVE:
81 | if (this.negativeClickListener != null) {
82 | this.negativeClickListener.onNegativeButtonClick();
83 | }
84 |
85 | break;
86 | case DialogInterface.BUTTON_POSITIVE:
87 | if (this.confirmDialogListener != null) {
88 | this.confirmDialogListener.onConfirm();
89 | }
90 | break;
91 | default:
92 | break;
93 | }
94 |
95 | }
96 |
97 | public static interface IConfirmDialogListener {
98 | public void onConfirm();
99 | }
100 |
101 | public static interface INegativeClickListener {
102 | public void onNegativeButtonClick();
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/app/src/main/java/com/laowch/githubtrends/ui/CustomLanguageAdapter.java:
--------------------------------------------------------------------------------
1 | package com.laowch.githubtrends.ui;
2 |
3 | import android.content.Context;
4 | import android.graphics.Color;
5 | import android.support.v4.view.MotionEventCompat;
6 | import android.support.v7.app.AppCompatActivity;
7 | import android.support.v7.widget.RecyclerView;
8 | import android.view.LayoutInflater;
9 | import android.view.MotionEvent;
10 | import android.view.View;
11 | import android.view.ViewGroup;
12 | import android.widget.TextView;
13 |
14 | import com.laowch.githubtrends.Constants;
15 | import com.laowch.githubtrends.R;
16 | import com.laowch.githubtrends.helper.ItemTouchHelperAdapter;
17 | import com.laowch.githubtrends.helper.ItemTouchHelperViewHolder;
18 | import com.laowch.githubtrends.helper.OnStartDragListener;
19 | import com.laowch.githubtrends.model.Language;
20 |
21 | import java.util.ArrayList;
22 | import java.util.Arrays;
23 | import java.util.List;
24 |
25 | /**
26 | * Created by lao on 15/9/28.
27 | */
28 | public class CustomLanguageAdapter extends RecyclerView.Adapter implements ItemTouchHelperAdapter {
29 |
30 | Context context;
31 |
32 | List mItems = new ArrayList<>();
33 |
34 | private final OnStartDragListener mDragStartListener;
35 |
36 | int mode;
37 |
38 | public CustomLanguageAdapter(Context context, OnStartDragListener dragStartListener) {
39 | this.mDragStartListener = dragStartListener;
40 | this.context = context;
41 | mode = Constants.MODE_DRAGGABLE;
42 | }
43 |
44 | public void switchMode(int mode) {
45 | this.mode = mode;
46 | notifyDataSetChanged();
47 | }
48 |
49 | @Override
50 | public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
51 | View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.custom_language_grid_item, parent, false);
52 |
53 | return new ViewHolder(v);
54 | }
55 |
56 | @Override
57 | public void onBindViewHolder(final ViewHolder viewHolder, int position) {
58 | final Language language = mItems.get(position);
59 | viewHolder.text.setText(language.name);
60 |
61 | // Start a drag whenever the handle view it touched
62 | viewHolder.handleView.setOnTouchListener(new View.OnTouchListener() {
63 | @Override
64 | public boolean onTouch(View v, MotionEvent event) {
65 | if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN) {
66 | mDragStartListener.onStartDrag(viewHolder);
67 | }
68 | return false;
69 | }
70 | });
71 |
72 | viewHolder.removeView.setOnClickListener(new View.OnClickListener() {
73 | @Override
74 | public void onClick(View v) {
75 | int index = mItems.indexOf(language);
76 | if (index >= 0) {
77 | if (mItems.size() > 1) {
78 | mItems.remove(index);
79 | notifyItemRemoved(index);
80 | } else {
81 | ConfirmDialog confirmDialog = ConfirmDialog.newInstance("Invalid Operation", "You should keep at least one language.", 0, -1);
82 | confirmDialog.show(((AppCompatActivity) context).getSupportFragmentManager(), "confirm");
83 | }
84 | }
85 | }
86 | });
87 |
88 | switch (mode) {
89 | case Constants.MODE_DRAGGABLE:
90 | viewHolder.handleView.setVisibility(View.VISIBLE);
91 | viewHolder.removeView.setVisibility(View.GONE);
92 | break;
93 | case Constants.MODE_REMOVE:
94 | viewHolder.handleView.setVisibility(View.GONE);
95 | viewHolder.removeView.setVisibility(View.VISIBLE);
96 | break;
97 | }
98 | }
99 |
100 | @Override
101 | public int getItemCount() {
102 | return mItems.size();
103 | }
104 |
105 | public void setItems(Language[] items) {
106 | mItems.clear();
107 | mItems.addAll(Arrays.asList(items));
108 | notifyDataSetChanged();
109 | }
110 |
111 | @Override
112 | public void onItemDismiss(int position) {
113 | mItems.remove(position);
114 | notifyItemRemoved(position);
115 | }
116 |
117 | @Override
118 | public boolean onItemMove(int fromPosition, int toPosition) {
119 | Language language = mItems.remove(fromPosition);
120 | mItems.add(toPosition, language);
121 |
122 | notifyItemMoved(fromPosition, toPosition);
123 | return true;
124 | }
125 |
126 | public class ViewHolder extends RecyclerView.ViewHolder implements ItemTouchHelperViewHolder {
127 |
128 | private TextView text;
129 |
130 | private View handleView;
131 |
132 | private View removeView;
133 |
134 | public ViewHolder(View itemView) {
135 | super(itemView);
136 | text = (TextView) itemView.findViewById(R.id.text);
137 | handleView = itemView.findViewById(R.id.handle);
138 | removeView = itemView.findViewById(R.id.remove);
139 | }
140 |
141 | @Override
142 | public void onItemSelected() {
143 | itemView.setBackgroundColor(Color.LTGRAY);
144 | }
145 |
146 | @Override
147 | public void onItemClear() {
148 | itemView.setBackgroundColor(0);
149 | }
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/app/src/main/java/com/laowch/githubtrends/ui/CustomLanguagesActivity.java:
--------------------------------------------------------------------------------
1 | package com.laowch.githubtrends.ui;
2 |
3 | import android.content.BroadcastReceiver;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.content.IntentFilter;
7 | import android.os.Bundle;
8 | import android.support.v4.content.LocalBroadcastManager;
9 | import android.support.v7.app.ActionBar;
10 | import android.support.v7.widget.GridLayoutManager;
11 | import android.support.v7.widget.RecyclerView;
12 | import android.support.v7.widget.Toolbar;
13 | import android.support.v7.widget.helper.ItemTouchHelper;
14 | import android.view.Menu;
15 | import android.view.MenuItem;
16 |
17 | import com.laowch.githubtrends.Constants;
18 | import com.laowch.githubtrends.R;
19 | import com.laowch.githubtrends.helper.OnStartDragListener;
20 | import com.laowch.githubtrends.helper.SimpleItemTouchHelperCallback;
21 | import com.laowch.githubtrends.utils.AnalyticsHelper;
22 | import com.laowch.githubtrends.utils.IntentUtils;
23 | import com.laowch.githubtrends.utils.LanguageHelper;
24 |
25 | import java.util.Arrays;
26 |
27 | /**
28 | * Created by lao on 15/9/28.
29 | */
30 | public class CustomLanguagesActivity extends BaseActivity implements OnStartDragListener {
31 |
32 |
33 | final BroadcastReceiver languagesChangedReceiver = new BroadcastReceiver() {
34 | @Override
35 | public void onReceive(Context context, Intent intent) {
36 | updateView();
37 | }
38 | };
39 |
40 |
41 | private ItemTouchHelper mItemTouchHelper;
42 |
43 | CustomLanguageAdapter adapter;
44 |
45 | int mode;
46 |
47 | @Override
48 | protected void onCreate(Bundle savedInstanceState) {
49 | super.onCreate(savedInstanceState);
50 | setContentView(R.layout.activity_simple_recycler_view);
51 |
52 |
53 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
54 | setSupportActionBar(toolbar);
55 | ActionBar actionBar = getSupportActionBar();
56 | actionBar.setDisplayHomeAsUpEnabled(true);
57 |
58 |
59 | adapter = new CustomLanguageAdapter(getContext(), this);
60 |
61 | RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
62 | recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2));
63 | recyclerView.setAdapter(adapter);
64 |
65 | ItemTouchHelper.Callback callback = new SimpleItemTouchHelperCallback(adapter);
66 | mItemTouchHelper = new ItemTouchHelper(callback);
67 | mItemTouchHelper.attachToRecyclerView(recyclerView);
68 |
69 | adapter.setItems(LanguageHelper.getInstance().getSelectedLanguages());
70 |
71 | switchMode(getIntent().getIntExtra("mode", Constants.MODE_DRAGGABLE));
72 |
73 | IntentFilter languageFilter = new IntentFilter(Constants.ACTION_SELECTED_LANGUAGES_CHANGE);
74 | LocalBroadcastManager.getInstance(this).registerReceiver(languagesChangedReceiver, languageFilter);
75 | }
76 |
77 | @Override
78 | protected void onDestroy() {
79 | super.onDestroy();
80 | LocalBroadcastManager.getInstance(this).unregisterReceiver(languagesChangedReceiver);
81 | }
82 |
83 | public void updateView() {
84 | adapter.setItems(LanguageHelper.getInstance().getSelectedLanguages());
85 | }
86 |
87 | @Override
88 | public void onStartDrag(RecyclerView.ViewHolder viewHolder) {
89 | mItemTouchHelper.startDrag(viewHolder);
90 | }
91 |
92 | @Override
93 | public boolean onCreateOptionsMenu(Menu menu) {
94 | getMenuInflater().inflate(R.menu.menu_custom_languages, menu);
95 | return super.onCreateOptionsMenu(menu);
96 | }
97 |
98 | @Override
99 | public boolean onPrepareOptionsMenu(Menu menu) {
100 | boolean isRemoveMode = mode == Constants.MODE_REMOVE;
101 |
102 | menu.findItem(R.id.action_add).setVisible(!isRemoveMode);
103 | menu.findItem(R.id.action_remove).setVisible(!isRemoveMode);
104 | menu.findItem(R.id.action_done).setVisible(isRemoveMode);
105 | menu.findItem(R.id.action_save).setVisible(!isRemoveMode);
106 |
107 | return super.onPrepareOptionsMenu(menu);
108 | }
109 |
110 | @Override
111 | public boolean onOptionsItemSelected(MenuItem item) {
112 | switch (item.getItemId()) {
113 | case R.id.action_add:
114 | AnalyticsHelper.sendEvent("CustomLangs", "Menu", "LangsAdd", 0l);
115 | IntentUtils.openAddLanguage(getContext());
116 | return true;
117 | case R.id.action_remove:
118 | AnalyticsHelper.sendEvent("CustomLangs", "Menu", "LangRemove", 0l);
119 | switchMode(Constants.MODE_REMOVE);
120 | return true;
121 | case R.id.action_done:
122 | AnalyticsHelper.sendEvent("CustomLangs", "Menu", "Done", 0l);
123 | switchMode(Constants.MODE_DRAGGABLE);
124 | return true;
125 | case R.id.action_save:
126 | AnalyticsHelper.sendEvent("CustomLangs", "Menu", "Save", 0l);
127 | LanguageHelper.getInstance().setSelectedLanguages(adapter.mItems);
128 | LocalBroadcastManager.getInstance(getContext()).sendBroadcast(new Intent(Constants.ACTION_SELECTED_LANGUAGES_CHANGE));
129 | finish();
130 | return true;
131 | }
132 |
133 | return super.onOptionsItemSelected(item);
134 | }
135 |
136 | private void switchMode(int mode) {
137 | this.mode = mode;
138 | adapter.switchMode(mode);
139 | invalidateOptionsMenu();
140 | }
141 |
142 | @Override
143 | public void onBackPressed() {
144 | if (Arrays.equals(adapter.mItems.toArray(), LanguageHelper.getInstance().getSelectedLanguages())) {
145 | super.onBackPressed();
146 | } else {
147 | ConfirmDialog confirmDialog = ConfirmDialog.newInstance("Confirm Exit", "Do you want to save your changes before exiting?", R.string.save, R.string.not_save);
148 | confirmDialog.setConfirmDialogListener(new ConfirmDialog.IConfirmDialogListener() {
149 | @Override
150 | public void onConfirm() {
151 | AnalyticsHelper.sendEvent("CustomLangs", "ExitDialog", "Save", 0l);
152 | LanguageHelper.getInstance().setSelectedLanguages(adapter.mItems);
153 | LocalBroadcastManager.getInstance(getContext()).sendBroadcast(new Intent(Constants.ACTION_SELECTED_LANGUAGES_CHANGE));
154 | finish();
155 | }
156 | });
157 | confirmDialog.setNegativeClickListener(new ConfirmDialog.INegativeClickListener() {
158 | @Override
159 | public void onNegativeButtonClick() {
160 | AnalyticsHelper.sendEvent("CustomLangs", "ExitDialog", "GiveUp", 0l);
161 | finish();
162 | }
163 | });
164 | confirmDialog.show(getSupportFragmentManager(), "confirm");
165 | }
166 |
167 |
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/app/src/main/java/com/laowch/githubtrends/ui/FavoritesActivity.java:
--------------------------------------------------------------------------------
1 | package com.laowch.githubtrends.ui;
2 |
3 | import android.os.Bundle;
4 | import android.support.v7.app.ActionBar;
5 | import android.support.v7.widget.LinearLayoutManager;
6 | import android.support.v7.widget.RecyclerView;
7 | import android.support.v7.widget.Toolbar;
8 |
9 | import com.laowch.githubtrends.R;
10 | import com.laowch.githubtrends.model.Language;
11 | import com.laowch.githubtrends.utils.FavoReposHelper;
12 |
13 | /**
14 | * Created by lao on 15/9/25.
15 | */
16 | public class FavoritesActivity extends BaseActivity {
17 |
18 | RepoListAdapter adapter;
19 |
20 | @Override
21 | protected void onCreate(Bundle savedInstanceState) {
22 | super.onCreate(savedInstanceState);
23 | setContentView(R.layout.activity_simple_recycler_view);
24 |
25 |
26 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
27 | setSupportActionBar(toolbar);
28 | ActionBar actionBar = getSupportActionBar();
29 | actionBar.setDisplayHomeAsUpEnabled(true);
30 |
31 |
32 | adapter = new RepoListAdapter(getContext(), new Language("favos", "favos_path"));
33 |
34 | RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
35 | recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
36 | recyclerView.setAdapter(adapter);
37 |
38 | adapter.setItems(FavoReposHelper.getInstance().getFavos());
39 |
40 | }
41 |
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/app/src/main/java/com/laowch/githubtrends/ui/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.laowch.githubtrends.ui;
2 |
3 | import android.content.BroadcastReceiver;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.content.IntentFilter;
7 | import android.os.Bundle;
8 | import android.support.design.widget.NavigationView;
9 | import android.support.design.widget.TabLayout;
10 | import android.support.v4.app.Fragment;
11 | import android.support.v4.app.FragmentManager;
12 | import android.support.v4.app.FragmentPagerAdapter;
13 | import android.support.v4.app.FragmentTransaction;
14 | import android.support.v4.content.LocalBroadcastManager;
15 | import android.support.v4.view.ViewPager;
16 | import android.support.v4.widget.DrawerLayout;
17 | import android.support.v7.app.ActionBar;
18 | import android.support.v7.widget.Toolbar;
19 | import android.view.Gravity;
20 | import android.view.LayoutInflater;
21 | import android.view.Menu;
22 | import android.view.MenuItem;
23 | import android.view.View;
24 | import android.view.ViewGroup;
25 | import android.widget.AdapterView;
26 | import android.widget.BaseAdapter;
27 | import android.widget.Spinner;
28 | import android.widget.TextView;
29 |
30 | import com.laowch.githubtrends.Constants;
31 | import com.laowch.githubtrends.R;
32 | import com.laowch.githubtrends.model.Language;
33 | import com.laowch.githubtrends.utils.AnalyticsHelper;
34 | import com.laowch.githubtrends.utils.IntentUtils;
35 | import com.laowch.githubtrends.utils.LanguageHelper;
36 |
37 | public class MainActivity extends BaseActivity implements ActionBar.TabListener {
38 |
39 | final BroadcastReceiver languagesChangedReceiver = new BroadcastReceiver() {
40 | @Override
41 | public void onReceive(Context context, Intent intent) {
42 | updateView();
43 | }
44 | };
45 |
46 |
47 | ViewPager viewPager;
48 |
49 | DrawerLayout drawerLayout;
50 |
51 | NavigationView navigationView;
52 |
53 | LanguagesPagerAdapter mPagerAdapter;
54 |
55 | TabLayout tabLayout;
56 |
57 | String mTimeSpan = "daily";
58 |
59 | @Override
60 | protected void onCreate(Bundle savedInstanceState) {
61 | super.onCreate(savedInstanceState);
62 | setContentView(R.layout.activity_main);
63 |
64 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
65 | setSupportActionBar(toolbar);
66 | ActionBar actionBar = getSupportActionBar();
67 | actionBar.setHomeAsUpIndicator(R.drawable.ic_menu_white_24dp);
68 | actionBar.setDisplayHomeAsUpEnabled(true);
69 |
70 | View spinnerContainer = LayoutInflater.from(this).inflate(R.layout.toolbar_spinner,
71 | toolbar, false);
72 | ActionBar.LayoutParams lp = new ActionBar.LayoutParams(
73 | ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
74 | toolbar.addView(spinnerContainer, lp);
75 |
76 | SinceSpinnerAdapter spinnerAdapter = new SinceSpinnerAdapter();
77 |
78 | Spinner spinner = (Spinner) spinnerContainer.findViewById(R.id.toolbar_spinner);
79 | spinner.setAdapter(spinnerAdapter);
80 | spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
81 | @Override
82 | public void onItemSelected(AdapterView> parent, View view, int position, long id) {
83 | switch (position) {
84 | case 0: // daily
85 | mTimeSpan = "daily";
86 | break;
87 | case 1: // weekly
88 | mTimeSpan = "weekly";
89 | break;
90 | case 2: // monthly
91 | mTimeSpan = "monthly";
92 | break;
93 |
94 | }
95 |
96 | for (int i = 0; i < mPagerAdapter.getCount(); i++) {
97 | Fragment fragment = getSupportFragmentManager().findFragmentByTag(mPagerAdapter.getFragmentTag(R.id.pager, i));
98 | if (fragment instanceof RepoListFragment) {
99 | if (fragment.isAdded()) {
100 | ((RepoListFragment) fragment).updateTimeSpan(mTimeSpan);
101 | }
102 | }
103 | }
104 | }
105 |
106 | @Override
107 | public void onNothingSelected(AdapterView> parent) {
108 |
109 | }
110 | });
111 |
112 | // Get the ViewPager and set it's PagerAdapter so that it can display items
113 | viewPager = (ViewPager) findViewById(R.id.pager);
114 | mPagerAdapter = new LanguagesPagerAdapter(getSupportFragmentManager());
115 | viewPager.setAdapter(mPagerAdapter);
116 |
117 | // Give the TabLayout the ViewPager
118 | tabLayout = (TabLayout) findViewById(R.id.sliding_tabs);
119 | tabLayout.setupWithViewPager(viewPager);
120 |
121 | drawerLayout = (DrawerLayout) findViewById(R.id.draw_layout);
122 | navigationView = (NavigationView) findViewById(R.id.navigation_view);
123 | navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
124 | @Override
125 | public boolean onNavigationItemSelected(MenuItem menuItem) {
126 | switch (menuItem.getItemId()) {
127 | case R.id.action_favos:
128 | AnalyticsHelper.sendEvent("Main", "Navigation", "Favos", 0l);
129 | IntentUtils.openFavos(getContext());
130 | break;
131 | case R.id.action_custom:
132 | AnalyticsHelper.sendEvent("Main", "Navigation", "LangsCustom", 0l);
133 | IntentUtils.openCustomLanguage(getContext());
134 | break;
135 | case R.id.action_add:
136 | AnalyticsHelper.sendEvent("Main", "Navigation", "LangsAdd", 0l);
137 | IntentUtils.openAddLanguage(getContext());
138 | break;
139 | case R.id.action_remove:
140 | AnalyticsHelper.sendEvent("Main", "Navigation", "LangsRemove", 0l);
141 | IntentUtils.openRemoveLanguage(getContext());
142 | break;
143 | case R.id.action_theme:
144 | AnalyticsHelper.sendEvent("Main", "Navigation", "Theme", 0l);
145 | ThemeDialog dialog = new ThemeDialog();
146 | dialog.show(getSupportFragmentManager(), "theme");
147 | break;
148 | case R.id.action_about:
149 | AnalyticsHelper.sendEvent("Main", "Navigation", "About", 0l);
150 | IntentUtils.openAbout(getContext());
151 | break;
152 | }
153 |
154 | drawerLayout.closeDrawer(Gravity.LEFT);
155 | return true;
156 | }
157 | });
158 |
159 | IntentFilter languageFilter = new IntentFilter(Constants.ACTION_SELECTED_LANGUAGES_CHANGE);
160 | LocalBroadcastManager.getInstance(this).registerReceiver(languagesChangedReceiver, languageFilter);
161 | }
162 |
163 | @Override
164 | protected void onDestroy() {
165 | super.onDestroy();
166 | LocalBroadcastManager.getInstance(this).unregisterReceiver(languagesChangedReceiver);
167 | }
168 |
169 | @Override
170 | public boolean onCreateOptionsMenu(Menu menu) {
171 | // Inflate the menu; this adds items to the action bar if it is present.
172 | getMenuInflater().inflate(R.menu.menu_main, menu);
173 | return true;
174 | }
175 |
176 | public void updateView() {
177 | mPagerAdapter.onLanguagesChange();
178 | tabLayout.setupWithViewPager(viewPager);
179 | }
180 |
181 | @Override
182 | public boolean onOptionsItemSelected(MenuItem item) {
183 |
184 | switch (item.getItemId()) {
185 | case R.id.action_custom:
186 | IntentUtils.openCustomLanguage(getContext());
187 | AnalyticsHelper.sendEvent("Main", "Menu", "LangsCustom", 0l);
188 | return true;
189 | case R.id.action_favos:
190 | AnalyticsHelper.sendEvent("Main", "Menu", "Favos", 0l);
191 | IntentUtils.openFavos(getContext());
192 | return true;
193 | case R.id.action_settings:
194 | return true;
195 | case android.R.id.home:
196 | AnalyticsHelper.sendEvent("Main", "Menu", "Drawer", 0l);
197 | drawerLayout.openDrawer(Gravity.LEFT);
198 | return true;
199 | }
200 |
201 | return super.onOptionsItemSelected(item);
202 | }
203 |
204 | @Override
205 | public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
206 | // When the given tab is selected, switch to the corresponding page in
207 | // the ViewPager.
208 | viewPager.setCurrentItem(tab.getPosition());
209 | }
210 |
211 | @Override
212 | public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
213 | }
214 |
215 | @Override
216 | public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
217 | }
218 |
219 |
220 | public class SinceSpinnerAdapter extends BaseAdapter {
221 |
222 | final String[] timeSpanTextArray = new String[]{"Today", "This Week", "This Month"};
223 |
224 | @Override
225 | public int getCount() {
226 | return timeSpanTextArray.length;
227 | }
228 |
229 | @Override
230 | public String getItem(int position) {
231 | return timeSpanTextArray[position];
232 | }
233 |
234 | @Override
235 | public long getItemId(int position) {
236 | return position;
237 | }
238 |
239 | @Override
240 | public View getView(int position, View convertView, ViewGroup parent) {
241 | View view = convertView != null ? convertView :
242 | getLayoutInflater().inflate(R.layout.toolbar_spinner_item_actionbar, parent, false);
243 |
244 | TextView textView = (TextView) view.findViewById(android.R.id.text1);
245 | textView.setText("Trends " + getItem(position));
246 | return view;
247 | }
248 |
249 | @Override
250 | public View getDropDownView(int position, View convertView, ViewGroup parent) {
251 |
252 | View view = convertView != null ? convertView :
253 | getLayoutInflater().inflate(R.layout.toolbar_spinner_item_dropdown, parent, false);
254 |
255 | TextView textView = (TextView) view.findViewById(android.R.id.text1);
256 | textView.setText(getItem(position));
257 |
258 | return view;
259 | }
260 | }
261 |
262 | public class LanguagesPagerAdapter extends FragmentPagerAdapter {
263 |
264 | Language[] languagesArray;
265 |
266 | public LanguagesPagerAdapter(FragmentManager fm) {
267 | super(fm);
268 | languagesArray = LanguageHelper.getInstance().getSelectedLanguages();
269 | }
270 |
271 | public void onLanguagesChange() {
272 | languagesArray = LanguageHelper.getInstance().getSelectedLanguages();
273 | notifyDataSetChanged();
274 | }
275 |
276 | @Override
277 | public Fragment getItem(int position) {
278 | return RepoListFragment.newInstance(getContext(), languagesArray[position], mTimeSpan);
279 | }
280 |
281 | @Override
282 | public int getCount() {
283 | return languagesArray.length;
284 | }
285 |
286 | @Override
287 | public CharSequence getPageTitle(int position) {
288 | return languagesArray[position].name;
289 | }
290 |
291 |
292 | public String getFragmentTag(int viewPagerId, int fragmentPosition) {
293 | return "android:switcher:" + viewPagerId + ":" + fragmentPosition;
294 | }
295 | }
296 |
297 |
298 | @Override
299 | public void onBackPressed() {
300 |
301 | if (drawerLayout.isDrawerOpen(Gravity.LEFT)) {
302 | drawerLayout.closeDrawer(Gravity.LEFT);
303 | } else {
304 | super.onBackPressed();
305 | }
306 | }
307 | }
308 |
--------------------------------------------------------------------------------
/app/src/main/java/com/laowch/githubtrends/ui/RepoListAdapter.java:
--------------------------------------------------------------------------------
1 | package com.laowch.githubtrends.ui;
2 |
3 | import android.content.Context;
4 | import android.support.v7.widget.RecyclerView;
5 | import android.text.TextUtils;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.widget.ImageView;
10 | import android.widget.TextView;
11 |
12 | import com.laowch.githubtrends.R;
13 | import com.laowch.githubtrends.model.Language;
14 | import com.laowch.githubtrends.model.Repo;
15 | import com.laowch.githubtrends.utils.AsyncImageView;
16 | import com.laowch.githubtrends.utils.FavoReposHelper;
17 | import com.laowch.githubtrends.utils.IntentUtils;
18 | import com.laowch.githubtrends.utils.LanguageHelper;
19 |
20 | import java.util.ArrayList;
21 | import java.util.Arrays;
22 | import java.util.List;
23 |
24 | /**
25 | * Created by lao on 15/9/23.
26 | */
27 | public class RepoListAdapter extends RecyclerView.Adapter {
28 |
29 |
30 | private List mItems = new ArrayList<>();
31 |
32 | Context mContext;
33 |
34 | Language language;
35 |
36 | public RepoListAdapter(Context context, Language language) {
37 | this.mContext = context;
38 | this.language = language;
39 | }
40 |
41 | public void setItems(Repo[] repos) {
42 | mItems = Arrays.asList(repos);
43 | notifyDataSetChanged();
44 | }
45 |
46 | @Override
47 | public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
48 | View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.repo_list_item, parent, false);
49 |
50 | return new ViewHolder(v);
51 | }
52 |
53 | @Override
54 | public void onBindViewHolder(ViewHolder viewHolder, int position) {
55 |
56 | Repo item = mItems.get(position);
57 |
58 | viewHolder.repo = item;
59 |
60 | viewHolder.title.setText(item.owner + " / " + item.name);
61 | if (TextUtils.isEmpty(item.description)) {
62 | viewHolder.description.setVisibility(View.GONE);
63 | } else {
64 | viewHolder.description.setText(item.description);
65 | viewHolder.description.setVisibility(View.VISIBLE);
66 | }
67 |
68 | if (TextUtils.isEmpty(item.meta)) {
69 | viewHolder.meta.setVisibility(View.GONE);
70 | } else {
71 | viewHolder.meta.setText(item.meta);
72 | viewHolder.meta.setVisibility(View.VISIBLE);
73 | }
74 |
75 | if (FavoReposHelper.getInstance().contains(item)) {
76 | viewHolder.starImage.setImageResource(R.drawable.ic_star_checked);
77 | } else {
78 | viewHolder.starImage.setImageResource(R.drawable.ic_star_unchecked);
79 | }
80 |
81 | if (TextUtils.isEmpty(language.path)) {
82 | // only show label in Tab 『All Language』
83 | if (TextUtils.isEmpty(item.language)) {
84 | viewHolder.label.setText("N/A");
85 | } else {
86 | Language language = LanguageHelper.getInstance().getLanguageByName(item.language);
87 | if (language == null) {
88 | viewHolder.label.setText(item.language);
89 | } else {
90 | viewHolder.label.setText(language.getShortName());
91 | }
92 | }
93 | viewHolder.label.setVisibility(View.VISIBLE);
94 | } else {
95 | viewHolder.label.setVisibility(View.GONE);
96 | }
97 |
98 |
99 | for (int i = 0; i < viewHolder.avatars.size(); i++) {
100 | if (i < item.contributors.size()) {
101 | viewHolder.avatars.get(i).loadImage(item.contributors.get(i).avatar);
102 | viewHolder.avatars.get(i).setVisibility(View.VISIBLE);
103 | } else {
104 | viewHolder.avatars.get(i).setVisibility(View.GONE);
105 | }
106 | }
107 |
108 | }
109 |
110 | @Override
111 | public int getItemCount() {
112 | return mItems.size();
113 | }
114 |
115 | public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
116 |
117 | Repo repo;
118 |
119 | private final TextView title;
120 | private final TextView description;
121 | private final TextView meta;
122 | private final ImageView starImage;
123 | private final TextView label;
124 | private List avatars;
125 |
126 | public ViewHolder(View itemView) {
127 | super(itemView);
128 | title = (TextView) itemView.findViewById(R.id.title);
129 | description = (TextView) itemView.findViewById(R.id.description);
130 | meta = (TextView) itemView.findViewById(R.id.meta);
131 | starImage = (ImageView) itemView.findViewById(R.id.star);
132 | label = (TextView) itemView.findViewById(R.id.label);
133 | avatars = new ArrayList<>();
134 | avatars.add((AsyncImageView) itemView.findViewById(R.id.avatar1));
135 | avatars.add((AsyncImageView) itemView.findViewById(R.id.avatar2));
136 | avatars.add((AsyncImageView) itemView.findViewById(R.id.avatar3));
137 | avatars.add((AsyncImageView) itemView.findViewById(R.id.avatar4));
138 | avatars.add((AsyncImageView) itemView.findViewById(R.id.avatar5));
139 |
140 | itemView.findViewById(R.id.repo_card).setOnClickListener(this);
141 | itemView.findViewById(R.id.contributors_line).setOnClickListener(this);
142 | starImage.setOnClickListener(this);
143 | }
144 |
145 | @Override
146 | public void onClick(View v) {
147 | switch (v.getId()) {
148 | case R.id.repo_card:
149 | IntentUtils.openExternalUrl(mContext, repo.url);
150 | break;
151 | case R.id.contributors_line:
152 | String contributorUrl;
153 | if (repo.url.endsWith("/")) {
154 | contributorUrl = repo.url + "graphs/contributors";
155 | } else {
156 | contributorUrl = repo.url + "/graphs/contributors";
157 | }
158 |
159 | IntentUtils.openExternalUrl(mContext, contributorUrl);
160 | break;
161 | case R.id.star:
162 | if (FavoReposHelper.getInstance().contains(repo)) {
163 | FavoReposHelper.getInstance().removeFavo(repo);
164 | starImage.setImageResource(R.drawable.ic_star_unchecked);
165 | } else {
166 | FavoReposHelper.getInstance().addFavo(repo);
167 | starImage.setImageResource(R.drawable.ic_star_checked);
168 | }
169 | break;
170 | }
171 | }
172 | }
173 | }
174 |
--------------------------------------------------------------------------------
/app/src/main/java/com/laowch/githubtrends/ui/RepoListFragment.java:
--------------------------------------------------------------------------------
1 | package com.laowch.githubtrends.ui;
2 |
3 | import android.content.Context;
4 | import android.os.Bundle;
5 | import android.support.annotation.Nullable;
6 | import android.support.v4.app.Fragment;
7 | import android.support.v4.widget.SwipeRefreshLayout;
8 | import android.support.v7.widget.LinearLayoutManager;
9 | import android.support.v7.widget.RecyclerView;
10 | import android.view.LayoutInflater;
11 | import android.view.View;
12 | import android.view.ViewGroup;
13 |
14 | import com.android.volley.RequestQueue;
15 | import com.android.volley.Response;
16 | import com.android.volley.VolleyError;
17 | import com.android.volley.toolbox.Volley;
18 | import com.laowch.githubtrends.Constants;
19 | import com.laowch.githubtrends.R;
20 | import com.laowch.githubtrends.model.Language;
21 | import com.laowch.githubtrends.model.Repo;
22 | import com.laowch.githubtrends.request.GsonRequest;
23 | import com.laowch.githubtrends.utils.AttrsHelper;
24 |
25 | /**
26 | * Created by lao on 15/9/23.
27 | */
28 | public class RepoListFragment extends Fragment {
29 |
30 | final static String TAG = "RepoListFragment";
31 |
32 | public static Fragment newInstance(Context context, Language language, String timeSpan) {
33 | Bundle bundle = new Bundle();
34 | bundle.putSerializable("extra_language", language);
35 | bundle.putSerializable("extra_time_span", timeSpan);
36 | return Fragment.instantiate(context, RepoListFragment.class.getName(), bundle);
37 | }
38 |
39 |
40 | Language language;
41 |
42 | String timeSpan;
43 |
44 | SwipeRefreshLayout swipeRefreshLayout;
45 |
46 | RepoListAdapter adapter;
47 |
48 | RequestQueue mRequestQueue;
49 |
50 | @Override
51 | public void onCreate(@Nullable Bundle savedInstanceState) {
52 | super.onCreate(savedInstanceState);
53 | language = (Language) getArguments().getSerializable("extra_language");
54 | timeSpan = (String) getArguments().getSerializable("extra_time_span");
55 | mRequestQueue = Volley.newRequestQueue(getContext());
56 | }
57 |
58 | @Override
59 | public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
60 | super.onViewCreated(view, savedInstanceState);
61 | swipeRefreshLayout.post(new Runnable() {
62 | @Override
63 | public void run() {
64 | swipeRefreshLayout.setRefreshing(true);
65 | }
66 | });
67 | executeGetRepos();
68 | }
69 |
70 |
71 | @Nullable
72 | @Override
73 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
74 | View view = inflater.inflate(R.layout.fragment_repo_list, container, false);
75 |
76 | swipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_refresh_layout);
77 | swipeRefreshLayout.setColorSchemeColors(AttrsHelper.getColor(getContext(), R.attr.colorPrimary), AttrsHelper.getColor(getContext(), R.attr.colorPrimaryLight));
78 | swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
79 |
80 | @Override
81 | public void onRefresh() {
82 | executeGetRepos();
83 | }
84 | });
85 |
86 | adapter = new RepoListAdapter(getContext(), language);
87 |
88 | RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
89 | recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
90 | recyclerView.setAdapter(adapter);
91 |
92 | return view;
93 | }
94 |
95 |
96 | public void updateTimeSpan(String timeSpan) {
97 | this.timeSpan = timeSpan;
98 | executeGetRepos();
99 | }
100 |
101 | @Override
102 | public void onStop() {
103 | super.onStop();
104 | if (mRequestQueue != null) {
105 | mRequestQueue.cancelAll(TAG);
106 | }
107 | }
108 |
109 | private void executeGetRepos() {
110 | // network request
111 | String url = Constants.URL + language.path + "_" + timeSpan;
112 |
113 | GsonRequest request = new GsonRequest(url, Repo[].class, new Response.Listener() {
114 | @Override
115 | public void onResponse(Repo[] response) {
116 | adapter.setItems(response);
117 | swipeRefreshLayout.setRefreshing(false);
118 | }
119 | }, new Response.ErrorListener() {
120 | @Override
121 | public void onErrorResponse(VolleyError error) {
122 | // TODO process error
123 | swipeRefreshLayout.setRefreshing(false);
124 | }
125 | });
126 | request.setTag(TAG);
127 | mRequestQueue.add(request);
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/app/src/main/java/com/laowch/githubtrends/ui/ThemeDialog.java:
--------------------------------------------------------------------------------
1 | package com.laowch.githubtrends.ui;
2 |
3 | import android.app.Dialog;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.support.annotation.Nullable;
7 | import android.support.v4.app.DialogFragment;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.view.Window;
12 |
13 | import com.laowch.githubtrends.R;
14 | import com.laowch.githubtrends.utils.PreferenceManager;
15 | import com.laowch.githubtrends.utils.Theme;
16 |
17 |
18 | /**
19 | * Created by lao on 10/4/15.
20 | */
21 | public class ThemeDialog extends DialogFragment implements View.OnClickListener {
22 |
23 | @Nullable
24 | @Override
25 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
26 | this.getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
27 |
28 | final View layout = inflater.inflate(R.layout.dialog_theme, container, false);
29 | layout.findViewById(R.id.blue_theme).setOnClickListener(this);
30 | layout.findViewById(R.id.indigo_theme).setOnClickListener(this);
31 | layout.findViewById(R.id.green_theme).setOnClickListener(this);
32 | layout.findViewById(R.id.red_theme).setOnClickListener(this);
33 | layout.findViewById(R.id.blue_grey_theme).setOnClickListener(this);
34 | layout.findViewById(R.id.black_theme).setOnClickListener(this);
35 | layout.findViewById(R.id.purple_theme).setOnClickListener(this);
36 | layout.findViewById(R.id.orange_theme).setOnClickListener(this);
37 | layout.findViewById(R.id.pink_theme).setOnClickListener(this);
38 | return layout;
39 | }
40 |
41 | @Override
42 | public void onStart() {
43 | super.onStart();
44 | Dialog dialog = getDialog();
45 | if (dialog != null) {
46 | int width = ViewGroup.LayoutParams.MATCH_PARENT;
47 | int height = ViewGroup.LayoutParams.MATCH_PARENT;
48 | dialog.getWindow().setLayout(width, height);
49 | }
50 | }
51 |
52 | @Override
53 | public void onClick(View v) {
54 |
55 | Theme theme;
56 | switch (v.getId()) {
57 | case R.id.blue_theme:
58 | theme = Theme.Blue;
59 | break;
60 | case R.id.indigo_theme:
61 | theme = Theme.Indigo;
62 | break;
63 | case R.id.green_theme:
64 | theme = Theme.Green;
65 | break;
66 | case R.id.red_theme:
67 | theme = Theme.Red;
68 | break;
69 | case R.id.blue_grey_theme:
70 | theme = Theme.BlueGrey;
71 | break;
72 | case R.id.black_theme:
73 | theme = Theme.Black;
74 | break;
75 |
76 | case R.id.orange_theme:
77 | theme = Theme.Orange;
78 | break;
79 |
80 | case R.id.purple_theme:
81 | theme = Theme.Purple;
82 | break;
83 | case R.id.pink_theme:
84 | theme = Theme.Pink;
85 | break;
86 | default:
87 | theme = Theme.Blue;
88 | break;
89 | }
90 | PreferenceManager.setCurrentTheme(getContext(), theme);
91 | startActivity(new Intent(getContext(), MainActivity.class));
92 | getActivity().finish();
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/app/src/main/java/com/laowch/githubtrends/utils/AnalyticsHelper.java:
--------------------------------------------------------------------------------
1 | package com.laowch.githubtrends.utils;
2 |
3 | import android.content.Context;
4 |
5 | import com.google.android.gms.analytics.GoogleAnalytics;
6 | import com.google.android.gms.analytics.HitBuilders;
7 | import com.google.android.gms.analytics.HitBuilders.ScreenViewBuilder;
8 | import com.google.android.gms.analytics.Tracker;
9 | import com.laowch.githubtrends.R;
10 |
11 | import java.io.PrintWriter;
12 | import java.io.StringWriter;
13 |
14 |
15 | public class AnalyticsHelper {
16 |
17 |
18 | private static Tracker sTracker;
19 |
20 |
21 | public static void initialize(final Context pContext) {
22 | AnalyticsHelper.sTracker = GoogleAnalytics.getInstance(pContext).newTracker(R.xml.analytics);
23 | }
24 |
25 | public static void sendView(final String pScreenName) {
26 | AnalyticsHelper.sTracker.setScreenName(pScreenName);
27 | AnalyticsHelper.sTracker.send(new ScreenViewBuilder().build());
28 | AnalyticsHelper.sTracker.setScreenName(null);
29 | }
30 |
31 | public static void sendEvent(final String pCategory, final String pAction, final String pLabel, final Long pValue) {
32 |
33 | AnalyticsHelper.sTracker.send(new HitBuilders.EventBuilder().setCategory(pCategory).setAction(pAction).setLabel(pLabel).setValue(pValue).build());
34 | }
35 |
36 |
37 | public static void sendException(Exception ex, boolean isFatal) {
38 | StringWriter sw = new StringWriter();
39 | PrintWriter pw = new PrintWriter(sw);
40 | ex.printStackTrace(pw);
41 |
42 |
43 | AnalyticsHelper.sTracker.send(new HitBuilders.ExceptionBuilder()
44 | .setDescription(ex.getMessage() + "\n" + sw.toString())
45 | .setFatal(isFatal)
46 | .build());
47 | }
48 |
49 | public static void sendTiming(String category, long timeMills, String action, String label) {
50 | AnalyticsHelper.sTracker.send(new HitBuilders.TimingBuilder().setCategory(category).setVariable(action).setLabel(label).setValue(timeMills).build());
51 | }
52 |
53 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/laowch/githubtrends/utils/AsyncImageView.java:
--------------------------------------------------------------------------------
1 | package com.laowch.githubtrends.utils;
2 |
3 | import android.content.Context;
4 | import android.net.Uri;
5 | import android.text.TextUtils;
6 | import android.util.AttributeSet;
7 | import android.widget.ImageView;
8 |
9 | import com.laowch.githubtrends.R;
10 | import com.nostra13.universalimageloader.core.DisplayImageOptions;
11 | import com.nostra13.universalimageloader.core.ImageLoader;
12 | import com.nostra13.universalimageloader.core.display.SimpleBitmapDisplayer;
13 | import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
14 |
15 | /**
16 | * Created by lao on 3/4/14.
17 | */
18 | public class AsyncImageView extends ImageView {
19 |
20 |
21 | String url;
22 |
23 | ImageLoadingListener imageLoadingListener;
24 |
25 | public AsyncImageView(final Context context) {
26 | super(context);
27 | init();
28 | }
29 |
30 | public AsyncImageView(final Context context, final AttributeSet attrs) {
31 | super(context, attrs);
32 | init();
33 | }
34 |
35 | public AsyncImageView(final Context context, final AttributeSet attrs, final int defStyle) {
36 | super(context, attrs, defStyle);
37 | init();
38 | }
39 |
40 | public void setImageLoadingListener(ImageLoadingListener listener) {
41 | this.imageLoadingListener = listener;
42 | }
43 |
44 | protected void init() {
45 |
46 | }
47 |
48 | public void loadImage(final String imageUrl) {
49 | if (imageUrl != null && url != null) {
50 | if (Uri.parse(imageUrl).getPath().equals(Uri.parse(url).getPath())) {
51 | return;
52 | }
53 | }
54 | url = imageUrl;
55 | executeLoadImage();
56 | }
57 |
58 |
59 | protected void executeLoadImage() {
60 |
61 | if (TextUtils.isEmpty(url)) {
62 | setImageResource(R.drawable.image_loading_resource);
63 | } else {
64 |
65 | DisplayImageOptions.Builder builder = new DisplayImageOptions.Builder()
66 | .showImageOnLoading(R.drawable.image_loading_resource)
67 | .cacheInMemory(true)
68 | .cacheOnDisk(true)
69 | .displayer(new SimpleBitmapDisplayer());
70 |
71 | DisplayImageOptions options = builder.build();
72 | ImageLoader.getInstance().displayImage(url, this, options, imageLoadingListener);
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/app/src/main/java/com/laowch/githubtrends/utils/AttrsHelper.java:
--------------------------------------------------------------------------------
1 | package com.laowch.githubtrends.utils;
2 |
3 | import android.content.Context;
4 | import android.content.res.Resources;
5 | import android.util.TypedValue;
6 |
7 | /**
8 | * Created by lao on 9/30/15.
9 | */
10 | public class AttrsHelper {
11 |
12 | public static int getColor(Context context, int attr) {
13 | TypedValue typedValue = new TypedValue();
14 | Resources.Theme theme = context.getTheme();
15 | theme.resolveAttribute(attr, typedValue, true);
16 | int color = typedValue.data;
17 |
18 | return color;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/laowch/githubtrends/utils/FavoReposHelper.java:
--------------------------------------------------------------------------------
1 | package com.laowch.githubtrends.utils;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 |
6 | import com.laowch.githubtrends.MyApplication;
7 | import com.laowch.githubtrends.model.Repo;
8 |
9 | import java.util.Arrays;
10 | import java.util.LinkedHashSet;
11 |
12 | /**
13 | * Created by lao on 15/9/25.
14 | */
15 | public class FavoReposHelper {
16 |
17 |
18 | static FavoReposHelper instance;
19 |
20 | public static synchronized FavoReposHelper getInstance() {
21 | return instance;
22 | }
23 |
24 |
25 | public static void init(Application application) {
26 | instance = new FavoReposHelper(application);
27 | }
28 |
29 | LinkedHashSet reposSet = new LinkedHashSet<>();
30 |
31 | Context context;
32 |
33 | private FavoReposHelper(Context context) {
34 | this.context = context;
35 | String favoReposJson = PreferenceManager.getString(context, "favo_repos", null);
36 | Repo[] favoReops = MyApplication.getGson().fromJson(favoReposJson, Repo[].class);
37 | if (favoReops != null) {
38 | reposSet.addAll(Arrays.asList(favoReops));
39 | }
40 | }
41 |
42 | public boolean contains(Repo repo) {
43 | return reposSet.contains(repo);
44 | }
45 |
46 | public Repo[] getFavos() {
47 | return reposSet.toArray(new Repo[0]);
48 | }
49 |
50 | public void addFavo(Repo repo) {
51 | reposSet.add(repo);
52 |
53 | saveToPref();
54 | }
55 |
56 | public void removeFavo(Repo repo) {
57 | reposSet.remove(repo);
58 |
59 | saveToPref();
60 | }
61 |
62 | private void saveToPref() {
63 | Repo[] repos = reposSet.toArray(new Repo[0]);
64 | String reposJson = MyApplication.getGson().toJson(repos);
65 | PreferenceManager.putString(context, "favo_repos", reposJson);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/app/src/main/java/com/laowch/githubtrends/utils/IntentUtils.java:
--------------------------------------------------------------------------------
1 | package com.laowch.githubtrends.utils;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.net.Uri;
6 |
7 | import com.laowch.githubtrends.Constants;
8 | import com.laowch.githubtrends.ui.AboutActivity;
9 | import com.laowch.githubtrends.ui.AddLanguagesActivity;
10 | import com.laowch.githubtrends.ui.CustomLanguagesActivity;
11 | import com.laowch.githubtrends.ui.FavoritesActivity;
12 |
13 | /**
14 | * Created by lao on 15/9/24.
15 | */
16 | public class IntentUtils {
17 |
18 | public static void openAbout(Context context) {
19 | Intent intent = new Intent(context, AboutActivity.class);
20 | context.startActivity(intent);
21 | }
22 |
23 | public static void openFavos(final Context context) {
24 | Intent intent = new Intent(context, FavoritesActivity.class);
25 | context.startActivity(intent);
26 | }
27 |
28 | public static void openCustomLanguage(Context context) {
29 | Intent intent = new Intent(context, CustomLanguagesActivity.class);
30 | context.startActivity(intent);
31 | }
32 |
33 | public static void openRemoveLanguage(Context context) {
34 | Intent intent = new Intent(context, CustomLanguagesActivity.class);
35 | intent.putExtra("mode", Constants.MODE_REMOVE);
36 | context.startActivity(intent);
37 | }
38 |
39 | public static void openAddLanguage(Context context) {
40 | Intent intent = new Intent(context, AddLanguagesActivity.class);
41 | context.startActivity(intent);
42 | }
43 |
44 | public static void openExternalUrl(final Context context, String url) {
45 |
46 | // process url like intent://scan/#Intent;scheme=zxing;package=com.google.zxing.client.android;end"
47 | // ref: https://developer.chrome.com/multidevice/android/intents
48 | try {
49 | if (url.startsWith("intent")) {
50 |
51 | int schemeStart = url.indexOf("scheme=") + "scheme=".length();
52 | int schemeEnd = url.indexOf(';', schemeStart);
53 | String scheme = url.substring(schemeStart, schemeEnd);
54 | url = scheme + url.substring("intent".length());
55 | }
56 | } catch (Exception ex) {
57 | }
58 |
59 |
60 | try {
61 | Intent intent = new Intent(Intent.ACTION_VIEW);
62 | intent.setData(Uri.parse(url));
63 | context.startActivity(intent);
64 | } catch (Exception ex) {
65 | }
66 | }
67 |
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/app/src/main/java/com/laowch/githubtrends/utils/LanguageHelper.java:
--------------------------------------------------------------------------------
1 | package com.laowch.githubtrends.utils;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 |
6 | import com.laowch.githubtrends.MyApplication;
7 | import com.laowch.githubtrends.model.Language;
8 |
9 | import java.io.BufferedReader;
10 | import java.io.InputStream;
11 | import java.io.InputStreamReader;
12 | import java.util.ArrayList;
13 | import java.util.Arrays;
14 | import java.util.HashMap;
15 | import java.util.List;
16 |
17 | /**
18 | * Created by lao on 15/9/25.
19 | */
20 | public class LanguageHelper {
21 |
22 |
23 | static LanguageHelper instance;
24 |
25 | public static synchronized LanguageHelper getInstance() {
26 | return instance;
27 | }
28 |
29 |
30 | public static void init(Application application) {
31 | instance = new LanguageHelper(application);
32 | }
33 |
34 |
35 | Language[] allLanguages;
36 | HashMap languageMap = new HashMap<>();
37 | List selectedLanguages = new ArrayList<>();
38 |
39 | Context context;
40 |
41 | private LanguageHelper(Context context) {
42 | this.context = context;
43 |
44 | String selectedLanguageJson = PreferenceManager.getString(context, "selected_languages", null);
45 | Language[] selected = MyApplication.getGson().fromJson(selectedLanguageJson, Language[].class);
46 | if (selected != null && selected.length > 0) {
47 | selectedLanguages.addAll(Arrays.asList(selected));
48 | } else {
49 | selectedLanguages.addAll(getDefaultSelectedLanguage());
50 | }
51 | }
52 |
53 |
54 | public Language[] getAllLanguages() {
55 | if (allLanguages != null) {
56 | return allLanguages;
57 | }
58 |
59 | try {
60 | StringBuilder buf = new StringBuilder();
61 |
62 | InputStream inputStream = context.getAssets().open("langs.json");
63 | BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
64 | String str;
65 | while ((str = in.readLine()) != null) {
66 | buf.append(str);
67 | }
68 | in.close();
69 |
70 | allLanguages = MyApplication.getGson().fromJson(buf.toString(), Language[].class);
71 | } catch (Exception e) {
72 | }
73 | return allLanguages;
74 | }
75 |
76 | public void setSelectedLanguages(List languageList) {
77 | selectedLanguages = languageList;
78 | saveToPref();
79 | }
80 |
81 | public void addSelectedLanguages(List languageList) {
82 | for (Language language : languageList) {
83 | if (!selectedLanguages.contains(language)) {
84 | selectedLanguages.add(language);
85 | }
86 | }
87 | saveToPref();
88 | }
89 |
90 | public Language[] getSelectedLanguages() {
91 | return selectedLanguages.toArray(new Language[0]);
92 | }
93 |
94 |
95 | public Language[] getUnselectedLanguages() {
96 | List unselectedLanguages = new ArrayList<>();
97 | for (Language language : getAllLanguages()) {
98 | if (!selectedLanguages.contains(language)) {
99 | unselectedLanguages.add(language);
100 | }
101 | }
102 |
103 | return unselectedLanguages.toArray(new Language[0]);
104 | }
105 |
106 |
107 | public Language getLanguageByName(String languageName) {
108 | if (languageMap.size() == 0) {
109 |
110 | for (Language language : getAllLanguages()) {
111 | languageMap.put(language.name, language);
112 | }
113 | }
114 |
115 | return languageMap.get(languageName);
116 |
117 | }
118 |
119 |
120 | private void saveToPref() {
121 | Language[] languages = selectedLanguages.toArray(new Language[0]);
122 | String languagesJson = MyApplication.getGson().toJson(languages);
123 | PreferenceManager.putString(context, "selected_languages", languagesJson);
124 | }
125 |
126 | private List getDefaultSelectedLanguage() {
127 | String[] defaultLanguagesName = new String[]{"All Language", "JavaScript", "Java", "Go", "CSS", "Objective-C", "Python", "Swift", "HTML"};
128 |
129 | List defaultLanguages = new ArrayList<>();
130 | for (String langNAme : defaultLanguagesName) {
131 | defaultLanguages.add(getLanguageByName(langNAme));
132 | }
133 | return defaultLanguages;
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/app/src/main/java/com/laowch/githubtrends/utils/PreferenceManager.java:
--------------------------------------------------------------------------------
1 | package com.laowch.githubtrends.utils;
2 |
3 |
4 | import android.content.Context;
5 | import android.content.SharedPreferences;
6 |
7 |
8 | public class PreferenceManager {
9 |
10 |
11 | private static SharedPreferences getSharedPreferences(final Context context) {
12 | return android.preference.PreferenceManager.getDefaultSharedPreferences(context);
13 | }
14 |
15 |
16 | public static boolean isFirstTime(Context context, String key) {
17 | if (getBoolean(context, key, false)) {
18 | return false;
19 | } else {
20 | putBoolean(context, key, true);
21 | return true;
22 | }
23 | }
24 |
25 |
26 | public static boolean contains(Context context, String key) {
27 | return PreferenceManager.getSharedPreferences(context).contains(key);
28 | }
29 |
30 | public static int getInt(final Context context, final String key, final int defaultValue) {
31 | return PreferenceManager.getSharedPreferences(context).getInt(key, defaultValue);
32 | }
33 |
34 | public static boolean putInt(final Context context, final String key, final int pValue) {
35 | final SharedPreferences.Editor editor = PreferenceManager.getSharedPreferences(context).edit();
36 |
37 | editor.putInt(key, pValue);
38 |
39 | return editor.commit();
40 | }
41 |
42 | public static long getLong(final Context context, final String key, final long defaultValue) {
43 | return PreferenceManager.getSharedPreferences(context).getLong(key, defaultValue);
44 | }
45 |
46 | public static Long getLong(final Context context, final String key, final Long defaultValue) {
47 | if (PreferenceManager.getSharedPreferences(context).contains(key)) {
48 | return PreferenceManager.getSharedPreferences(context).getLong(key, 0);
49 | } else {
50 | return null;
51 | }
52 | }
53 |
54 |
55 | public static boolean putLong(final Context context, final String key, final long pValue) {
56 | final SharedPreferences.Editor editor = PreferenceManager.getSharedPreferences(context).edit();
57 |
58 | editor.putLong(key, pValue);
59 |
60 | return editor.commit();
61 | }
62 |
63 | public static boolean getBoolean(final Context context, final String key, final boolean defaultValue) {
64 | return PreferenceManager.getSharedPreferences(context).getBoolean(key, defaultValue);
65 | }
66 |
67 | public static boolean putBoolean(final Context context, final String key, final boolean pValue) {
68 | final SharedPreferences.Editor editor = PreferenceManager.getSharedPreferences(context).edit();
69 |
70 | editor.putBoolean(key, pValue);
71 |
72 | return editor.commit();
73 | }
74 |
75 | public static String getString(final Context context, final String key, final String defaultValue) {
76 | return PreferenceManager.getSharedPreferences(context).getString(key, defaultValue);
77 | }
78 |
79 | public static boolean putString(final Context context, final String key, final String pValue) {
80 | final SharedPreferences.Editor editor = PreferenceManager.getSharedPreferences(context).edit();
81 |
82 | editor.putString(key, pValue);
83 |
84 | return editor.commit();
85 | }
86 |
87 |
88 | public static boolean remove(final Context context, final String key) {
89 | final SharedPreferences.Editor editor = PreferenceManager.getSharedPreferences(context).edit();
90 |
91 | editor.remove(key);
92 |
93 | return editor.commit();
94 | }
95 |
96 | public static Theme getCurrentTheme(Context context) {
97 | return Theme.valueOf(PreferenceManager.getString(context, "app_theme", Theme.Blue.name()));
98 | }
99 |
100 | public static void setCurrentTheme(Context context, Theme currentTheme) {
101 | PreferenceManager.putString(context, "app_theme", currentTheme.name());
102 | }
103 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/laowch/githubtrends/utils/Theme.java:
--------------------------------------------------------------------------------
1 | package com.laowch.githubtrends.utils;
2 |
3 | /**
4 | * Created by lao on 9/30/15.
5 | */
6 | public enum Theme {
7 | Blue,
8 |
9 | Indigo,
10 |
11 | Green,
12 |
13 | Red,
14 |
15 | BlueGrey,
16 |
17 | Black,
18 |
19 | Purple,
20 |
21 | Orange,
22 |
23 | Pink
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_about.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-hdpi/ic_about.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_action_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-hdpi/ic_action_add.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_action_custom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-hdpi/ic_action_custom.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_action_favo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-hdpi/ic_action_favo.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_action_remove.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-hdpi/ic_action_remove.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_action_theme.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-hdpi/ic_action_theme.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_draggable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-hdpi/ic_draggable.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_menu_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-hdpi/ic_menu_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_remove.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-hdpi/ic_remove.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_star_checked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-hdpi/ic_star_checked.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_star_unchecked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-hdpi/ic_star_unchecked.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_about.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-mdpi/ic_about.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_action_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-mdpi/ic_action_add.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_action_custom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-mdpi/ic_action_custom.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_action_favo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-mdpi/ic_action_favo.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_action_remove.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-mdpi/ic_action_remove.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_action_theme.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-mdpi/ic_action_theme.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_draggable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-mdpi/ic_draggable.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_menu_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-mdpi/ic_menu_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_remove.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-mdpi/ic_remove.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_star_checked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-mdpi/ic_star_checked.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_star_unchecked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-mdpi/ic_star_unchecked.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_about.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xhdpi/ic_about.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_action_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xhdpi/ic_action_add.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_action_custom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xhdpi/ic_action_custom.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_action_favo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xhdpi/ic_action_favo.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_action_remove.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xhdpi/ic_action_remove.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_action_theme.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xhdpi/ic_action_theme.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_draggable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xhdpi/ic_draggable.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_menu_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xhdpi/ic_menu_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_remove.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xhdpi/ic_remove.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_star_checked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xhdpi/ic_star_checked.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_star_unchecked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xhdpi/ic_star_unchecked.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_about.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xxhdpi/ic_about.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_action_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xxhdpi/ic_action_add.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_action_custom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xxhdpi/ic_action_custom.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_action_favo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xxhdpi/ic_action_favo.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_action_remove.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xxhdpi/ic_action_remove.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_action_theme.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xxhdpi/ic_action_theme.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_draggable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xxhdpi/ic_draggable.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_menu_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xxhdpi/ic_menu_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_remove.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xxhdpi/ic_remove.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_star_checked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xxhdpi/ic_star_checked.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_star_unchecked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xxhdpi/ic_star_unchecked.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/spinner_triangle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xxhdpi/spinner_triangle.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/spinner_triangle_sub.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xxhdpi/spinner_triangle_sub.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_about.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xxxhdpi/ic_about.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_action_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xxxhdpi/ic_action_add.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_action_custom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xxxhdpi/ic_action_custom.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_action_favo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xxxhdpi/ic_action_favo.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_action_remove.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xxxhdpi/ic_action_remove.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_action_theme.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xxxhdpi/ic_action_theme.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_draggable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xxxhdpi/ic_draggable.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_menu_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xxxhdpi/ic_menu_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_remove.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xxxhdpi/ic_remove.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_star_checked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xxxhdpi/ic_star_checked.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_star_unchecked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/drawable-xxxhdpi/ic_star_unchecked.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/image_loading_resource.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_about.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
19 |
20 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
13 |
14 |
15 |
18 |
19 |
27 |
28 |
34 |
35 |
36 |
37 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
55 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_simple_recycler_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
12 |
20 |
21 |
22 |
23 |
24 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/add_language_grid_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
18 |
19 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/custom_language_grid_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
18 |
19 |
26 |
27 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/dialog_theme.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
15 |
16 |
24 |
25 |
32 |
33 |
34 |
35 |
43 |
44 |
51 |
52 |
53 |
54 |
55 |
63 |
64 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
82 |
83 |
91 |
92 |
99 |
100 |
101 |
102 |
110 |
111 |
118 |
119 |
120 |
121 |
129 |
130 |
137 |
138 |
139 |
140 |
141 |
142 |
147 |
148 |
156 |
157 |
164 |
165 |
166 |
167 |
175 |
176 |
183 |
184 |
185 |
186 |
194 |
195 |
202 |
203 |
204 |
205 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/drawer_header.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_main.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_repo_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/repo_list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
15 |
16 |
21 |
22 |
28 |
29 |
35 |
36 |
42 |
43 |
44 |
51 |
52 |
58 |
59 |
64 |
65 |
70 |
71 |
76 |
77 |
82 |
83 |
88 |
89 |
90 |
91 |
92 |
99 |
100 |
116 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/toolbar_spinner.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/toolbar_spinner_item_actionbar.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/toolbar_spinner_item_dropdown.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_add_language.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_custom_languages.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_drawer.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_main.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
13 |
14 |
15 |
21 |
22 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #2196F3
4 | #1976D2
5 | #90CAF9
6 | #2196F3
7 |
8 |
9 | #3F51B5
10 | #303F9F
11 | #C5CAE9
12 | #3F51B5
13 |
14 |
15 | #4CAF50
16 | #388E3C
17 | #C8E6C9
18 | #4CAF50
19 |
20 |
21 | #f44336
22 | #d32f2f
23 | #ef9a9a
24 | #f44336
25 |
26 |
27 | #607D8B
28 | #455A64
29 | #B0BEC5
30 | #607D8B
31 |
32 | #000
33 | #000
34 | #666
35 | #000
36 |
37 | #9C27B0
38 | #7B1FA2
39 | #CE93D8
40 | #9C27B0
41 |
42 |
43 | #FF9800
44 | #F57C00
45 | #FFCC80
46 | #FF9800
47 |
48 |
49 | #E91E63
50 | #C2185B
51 | #F48FB1
52 | #E91E63
53 |
54 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 | 24dp
7 | 8dp
8 | 2dp
9 | 4dp
10 | 16dp
11 | 4dp
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Github Trends
3 |
4 | Settings
5 | Favorites
6 | Custom Languages
7 |
8 | Remove Language
9 | Done
10 | Add Language
11 | Save
12 | Don\'t Save
13 | About
14 | Color Theme
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
16 |
17 |
23 |
24 |
25 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
17 |
18 |
19 |
25 |
26 |
27 |
33 |
34 |
35 |
41 |
42 |
43 |
49 |
50 |
56 |
57 |
58 |
64 |
65 |
71 |
72 |
78 |
79 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/analytics.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UA-36768262-7
6 |
7 |
8 | true
9 |
10 |
11 | true
12 |
13 |
14 | false
15 |
16 | 30
17 |
18 | 300
19 |
--------------------------------------------------------------------------------
/app/src/main/web_hi_res_512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/app/src/main/web_hi_res_512.png
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:1.3.0'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/screenshot/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/screenshot/1.png
--------------------------------------------------------------------------------
/screenshot/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/screenshot/2.png
--------------------------------------------------------------------------------
/screenshot/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/screenshot/3.png
--------------------------------------------------------------------------------
/screenshot/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/screenshot/4.png
--------------------------------------------------------------------------------
/screenshot/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/laowch/GithubTrends/6d9b18c62451da45575067bb4383d2b2bf68ffea/screenshot/5.png
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------