├── .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 | screenshot screenshot 25 | 26 | screenshot screenshot 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 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_custom_languages.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 10 | 11 | 17 | 18 | 23 | 24 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_drawer.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 12 | 13 | 17 | 21 | 22 | 26 | 27 | 28 | 29 | 32 | 33 | 37 | 38 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /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 | --------------------------------------------------------------------------------