├── .gitignore ├── GankDaily.iml ├── LICENSE ├── app ├── .gitignore ├── build.gradle ├── libs │ ├── armeabi │ │ └── libbspatch.so │ └── umeng-update-v2.6.0.1.jar ├── proguard-rules.pro └── src │ ├── beta │ └── res │ │ ├── menu │ │ └── 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 │ │ └── strings.xml │ └── main │ ├── AndroidManifest.xml │ ├── assets │ ├── about_gank_app.html │ ├── about_gank_site.html │ └── changelog.html │ ├── java │ └── com │ │ └── gudong │ │ └── gankio │ │ ├── GankApp.java │ │ ├── core │ │ ├── GankCategory.java │ │ ├── GuDong.java │ │ ├── MainFactory.java │ │ └── MainRetrofit.java │ │ ├── data │ │ ├── BaseData.java │ │ ├── GankData.java │ │ ├── PrettyGirlData.java │ │ ├── RestData.java │ │ └── entity │ │ │ ├── Gank.java │ │ │ ├── Girl.java │ │ │ └── Soul.java │ │ ├── presenter │ │ ├── BasePresenter.java │ │ ├── CustomDialogPresenter.java │ │ ├── GirlFacePresenter.java │ │ ├── MainPresenter.java │ │ ├── ViewListPresenter.java │ │ └── WebPresenter.java │ │ ├── ui │ │ ├── activity │ │ │ ├── AboutActivity.java │ │ │ ├── BaseActivity.java │ │ │ ├── BaseSwipeRefreshActivity.java │ │ │ ├── GirlFaceActivity.java │ │ │ ├── MainActivity.java │ │ │ ├── ViewListActivity.java │ │ │ └── WebActivity.java │ │ ├── adapter │ │ │ ├── MainListAdapter.java │ │ │ └── ViewListAdapter.java │ │ ├── fragment │ │ │ └── CustomWebViewDialog.java │ │ ├── view │ │ │ ├── IBaseView.java │ │ │ ├── ICustomDialog.java │ │ │ ├── IGirlFaceView.java │ │ │ ├── IMainView.java │ │ │ ├── ISwipeRefreshView.java │ │ │ ├── IViewListView.java │ │ │ └── IWebView.java │ │ └── widget │ │ │ └── RatioImageView.java │ │ └── util │ │ ├── AndroidUtils.java │ │ ├── DateUtil.java │ │ ├── DialogUtil.java │ │ ├── StringStyleUtils.java │ │ ├── TaskUtils.java │ │ └── ToastUtils.java │ └── res │ ├── drawable-hdpi │ ├── umeng_update_btn_check_off_focused_holo_light.png │ ├── umeng_update_btn_check_off_holo_light.png │ ├── umeng_update_btn_check_off_pressed_holo_light.png │ ├── umeng_update_btn_check_on_focused_holo_light.png │ ├── umeng_update_btn_check_on_holo_light.png │ ├── umeng_update_btn_check_on_pressed_holo_light.png │ ├── umeng_update_close_bg_normal.png │ └── umeng_update_close_bg_tap.png │ ├── drawable-xhdpi │ ├── bg_card.9.png │ └── splash_5.jpg │ ├── drawable │ ├── ic_brower.xml │ ├── ic_bug.xml │ ├── ic_describe.xml │ ├── ic_email.xml │ ├── ic_github.xml │ ├── ic_issues.xml │ ├── ic_issues_white.xml │ ├── ic_profile.xml │ ├── ic_star_filled.xml │ ├── shape_material_button_press.xml │ ├── tb_munion_icon.xml │ ├── tb_munion_item_selector.xml │ ├── umeng_common_gradient_green.xml │ ├── umeng_common_gradient_orange.xml │ ├── umeng_common_gradient_red.xml │ ├── umeng_update_button_cancel_bg_focused.xml │ ├── umeng_update_button_cancel_bg_normal.xml │ ├── umeng_update_button_cancel_bg_selector.xml │ ├── umeng_update_button_cancel_bg_tap.xml │ ├── umeng_update_button_check_selector.xml │ ├── umeng_update_button_close_bg_selector.xml │ ├── umeng_update_button_ok_bg_focused.xml │ ├── umeng_update_button_ok_bg_normal.xml │ ├── umeng_update_button_ok_bg_selector.xml │ ├── umeng_update_button_ok_bg_tap.xml │ ├── umeng_update_dialog_bg.xml │ ├── umeng_update_title_bg.xml │ └── umeng_update_wifi_disable.png │ ├── layout-v9 │ └── umeng_common_download_notification.xml │ ├── layout │ ├── activity_girl_detail.xml │ ├── activity_main.xml │ ├── activity_view_list.xml │ ├── activity_web.xml │ ├── dialog_webview.xml │ ├── gank_item_category.xml │ ├── gank_item_girl.xml │ ├── gank_item_normal.xml │ ├── index_item.xml │ ├── model_toolbar.xml │ ├── tb_munion_aditem.xml │ ├── tb_munion_adview.xml │ ├── umeng_common_download_notification.xml │ └── umeng_update_dialog.xml │ ├── menu │ ├── menu_gank.xml │ ├── menu_girl_detail.xml │ ├── menu_main.xml │ └── menu_web.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-zh │ ├── umeng_common_strings.xml │ └── umeng_update_string.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── ids.xml │ ├── material_designer_color.xml │ ├── strings.xml │ ├── styles.xml │ ├── tb_munion_strings.xml │ ├── umeng_common_strings.xml │ └── umeng_update_string.xml ├── art ├── download.png └── gank_introduce.png ├── build.gradle ├── gradle.properties ├── gradlew ├── gradlew.bat ├── readme.md └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /local.properties 3 | /gradle.properties 4 | /.idea 5 | /.idea/workspace.xml 6 | /.idea/gradle.xml 7 | /.idea/libraries 8 | /app/app.iml 9 | .DS_Store 10 | /build 11 | /captures 12 | /picture 13 | /GankIO.iml -------------------------------------------------------------------------------- /GankDaily.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | def releaseTime() { 4 | return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC")) 5 | } 6 | 7 | android { 8 | compileSdkVersion 25 9 | buildToolsVersion '25.0.2' 10 | defaultConfig { 11 | applicationId "com.gudong.gankio" 12 | //For use TYPE_TOAST 13 | minSdkVersion 19 14 | targetSdkVersion 25 15 | versionCode 9 16 | versionName "1.3" 17 | vectorDrawables.useSupportLibrary = true 18 | } 19 | 20 | signingConfigs { 21 | //指定名叫release的一个签名对象 会在下面的脚本(85行开始)中,动态根据配置文件设置属性 22 | release 23 | } 24 | 25 | buildTypes { 26 | release { 27 | println 'build - release' 28 | //设置是否混淆 29 | minifyEnabled true 30 | //设置压缩对齐 31 | zipAlignEnabled true 32 | //移除无用的资源文件 33 | shrinkResources true 34 | //设置混淆配置文件 35 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 36 | //如果签名配置不为空 则设置签名信息 37 | if (signingConfigs.release != null) { 38 | signingConfig signingConfigs.release 39 | } 40 | //指定签名包得输入文件名称 41 | applicationVariants.all { variant -> 42 | variant.outputs.each { output -> 43 | def outputFile = output.outputFile 44 | if (outputFile != null && outputFile.name.endsWith('.apk')) { 45 | // 输出apk名称为GankDaily_v1.0_2015-01-15_wandoujia.apk 46 | def fileName = "GankDaily_v${defaultConfig.versionName}_${releaseTime()}_${variant.productFlavors[0].name}_release.apk" 47 | output.outputFile = new File(outputFile.parent, fileName) 48 | } 49 | } 50 | } 51 | } 52 | 53 | debug{ 54 | println 'build - debug' 55 | } 56 | } 57 | 58 | productFlavors { 59 | beta{ 60 | manifestPlaceholders = [UMENG_CHANNEL_VALUE:"beta"] 61 | } 62 | xiaomi { 63 | manifestPlaceholders = [UMENG_CHANNEL_VALUE:"xiaomi"] 64 | } 65 | coolapk { 66 | manifestPlaceholders = [UMENG_CHANNEL_VALUE:"coolapk"] 67 | } 68 | wandoujia { 69 | manifestPlaceholders = [UMENG_CHANNEL_VALUE: "wandoujia"] 70 | } 71 | fir { 72 | manifestPlaceholders = [UMENG_CHANNEL_VALUE: "fir"] 73 | } 74 | umeng { 75 | manifestPlaceholders = [UMENG_CHANNEL_VALUE: "umeng"] 76 | } 77 | play { 78 | manifestPlaceholders = [UMENG_CHANNEL_VALUE: "play"] 79 | } 80 | } 81 | 82 | lintOptions { 83 | checkReleaseBuilds false 84 | // Or, if you prefer, you can continue to check for errors in release builds, 85 | // but continue the build even when errors are found: 86 | abortOnError false 87 | } 88 | } 89 | 90 | //set release sign info synchronously 91 | def Properties props = new Properties() 92 | def propFile = file('../gradle.properties') 93 | if (propFile.canRead()) { 94 | props.load(new FileInputStream(propFile)) 95 | if (props != null && 96 | props.containsKey('SIGN_FILE') && props.containsKey('SIGN_KEYSTORE_PASS') && 97 | props.containsKey('SIGN_KEYSTORE_ALIAS') && props.containsKey('SIGN_KEYSTORE_ALIAS_PASS')) { 98 | println 'release build signing' 99 | android.signingConfigs.release.storeFile = file(props['SIGN_FILE']) 100 | android.signingConfigs.release.storePassword = props['SIGN_KEYSTORE_PASS'] 101 | android.signingConfigs.release.keyAlias = props['SIGN_KEYSTORE_ALIAS'] 102 | android.signingConfigs.release.keyPassword = props['SIGN_KEYSTORE_ALIAS_PASS'] 103 | } else { 104 | println 'release build not found signing properties' 105 | android.buildTypes.release.signingConfig = null 106 | } 107 | } else { 108 | println 'release build not found signing file' 109 | android.buildTypes.release.signingConfig = null 110 | } 111 | 112 | 113 | dependencies { 114 | compile fileTree(dir: 'libs', include: ['*.jar']) 115 | compile 'com.android.support:appcompat-v7:25.3.1' 116 | compile 'com.android.support:recyclerview-v7:25.3.1' 117 | compile 'com.android.support:design:25.3.1' 118 | 119 | compile 'com.jakewharton:butterknife:7.0.1' 120 | 121 | compile 'io.reactivex:rxandroid:1.0.0' 122 | 123 | compile 'com.orhanobut:logger:1.4' 124 | 125 | compile 'com.squareup.okhttp:okhttp:2.5.0' 126 | compile 'com.squareup.retrofit:retrofit:1.9.0' 127 | 128 | compile 'com.github.chrisbanes:PhotoView:2.0.0' 129 | 130 | compile 'com.github.bumptech.glide:glide:3.7.0' 131 | 132 | compile 'com.umeng.analytics:analytics:latest.integration' 133 | 134 | compile 'com.github.daniel-stoneuk:material-about-library:1.8.2' 135 | } 136 | -------------------------------------------------------------------------------- /app/libs/armeabi/libbspatch.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maoruibin/GankDaily/bbdf5a79c336968ed7308d562aeff4ede8dd2736/app/libs/armeabi/libbspatch.so -------------------------------------------------------------------------------- /app/libs/umeng-update-v2.6.0.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maoruibin/GankDaily/bbdf5a79c336968ed7308d562aeff4ede8dd2736/app/libs/umeng-update-v2.6.0.1.jar -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/drakeet/Applications/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | -dontwarn com.squareup.okhttp.** 20 | 21 | -keep class butterknife.** { *; } 22 | -dontwarn butterknife.internal.** 23 | -keep class **$$ViewBinder { *; } 24 | 25 | -keepclasseswithmembernames class * { 26 | @butterknife.* ; 27 | } 28 | 29 | -keepclasseswithmembernames class * { 30 | @butterknife.* ; 31 | } 32 | 33 | -keepattributes *Annotation* 34 | -keepclassmembers class ** { 35 | @com.squareup.otto.Subscribe public *; 36 | @com.squareup.otto.Produce public *; 37 | } 38 | 39 | 40 | -keep public class com.gudong.gankio.R$*{ 41 | public static final int *; 42 | } 43 | 44 | -keep public class com.umeng.fb.ui.ThreadView {} 45 | 46 | -keep class com.gudong.gankio.BuildConfig { *; } 47 | -keep public class * extends android.os.Binder 48 | 49 | # Keep the support library 50 | -keep class android.support.** { *; } 51 | -keep interface android.support.** { *; } 52 | 53 | # For using GSON @Expose annotation 54 | -keepattributes *Annotation* 55 | 56 | -keepattributes EnclosingMethod 57 | 58 | # Gson specific classes 59 | -keep class sun.misc.Unsafe { *; } 60 | -keep class com.google.gson.stream.** { *; } 61 | 62 | -keepclassmembers enum * { 63 | public static **[] values(); 64 | public static ** valueOf(java.lang.String); 65 | } 66 | 67 | -keep class * implements android.os.Parcelable { 68 | public static final android.os.Parcelable$Creator *; 69 | } 70 | 71 | -keepattributes Signature 72 | -keep class **.R$* {*;} 73 | -ignorewarnings 74 | 75 | -verbose 76 | -keepclasseswithmembernames class * { 77 | native ; 78 | } 79 | 80 | -keep class com.gudong.gankio.** { *;} 81 | 82 | -keepclasseswithmembernames class * { 83 | native ; 84 | } 85 | 86 | -keep class android.support.v8.renderscript.** { *; } 87 | 88 | # ActiveAndroid 89 | -keep class com.activeandroid.** { *; } 90 | -keep class com.activeandroid.**.** { *; } 91 | -keep class * extends com.activeandroid.Model 92 | -keep class * extends com.activeandroid.serializer.TypeSerializer 93 | 94 | 95 | # Remove logging calls 96 | -assumenosideeffects class android.util.Log { 97 | public static boolean isLoggable(java.lang.String, int); 98 | public static int v(...); 99 | public static int i(...); 100 | public static int w(...); 101 | public static int d(...); 102 | public static int e(...); 103 | } 104 | 105 | # For Guava: 106 | -dontwarn javax.annotation.** 107 | -dontwarn javax.inject.** 108 | -dontwarn sun.misc.Unsafe 109 | 110 | # For RxJava: 111 | -dontwarn org.mockito.** 112 | -dontwarn org.junit.** 113 | -dontwarn org.robolectric.** 114 | 115 | 116 | -keepattributes Signature 117 | -keepattributes *Annotation* 118 | -keep class com.squareup.okhttp.** { *; } 119 | -keep interface com.squareup.okhttp.** { *; } 120 | -dontwarn com.squareup.okhttp.** 121 | 122 | -dontwarn rx.** 123 | -dontwarn retrofit.** 124 | -keep class retrofit.** { *; } 125 | -keepclasseswithmembers class * { 126 | @retrofit.http.* ; 127 | } 128 | 129 | -keep class sun.misc.Unsafe { *; } 130 | 131 | -dontwarn java.lang.invoke.* 132 | 133 | # 使用注解 134 | -keepattributes *Annotation*,Signature 135 | 136 | # 保持混淆时类的实名及行号(——————— 调试时打开 ———————) 137 | -keepattributes SourceFile,LineNumberTable 138 | 139 | # 枚举需要keep see http://proguard.sourceforge.net/manual/examples.html#enumerations 140 | -keepclassmembers enum * { 141 | **[] $VALUES; 142 | public *; 143 | } 144 | 145 | #glide 146 | -keep public class * implements com.bumptech.glide.module.GlideModule 147 | -keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** { 148 | **[] $VALUES; 149 | public *; 150 | } -------------------------------------------------------------------------------- /app/src/beta/res/menu/menu_main.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 10 | 11 | 16 | 17 | 21 | 22 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/beta/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maoruibin/GankDaily/bbdf5a79c336968ed7308d562aeff4ede8dd2736/app/src/beta/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/beta/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maoruibin/GankDaily/bbdf5a79c336968ed7308d562aeff4ede8dd2736/app/src/beta/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/beta/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maoruibin/GankDaily/bbdf5a79c336968ed7308d562aeff4ede8dd2736/app/src/beta/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/beta/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maoruibin/GankDaily/bbdf5a79c336968ed7308d562aeff4ede8dd2736/app/src/beta/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/beta/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maoruibin/GankDaily/bbdf5a79c336968ed7308d562aeff4ede8dd2736/app/src/beta/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/beta/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | GankDailyBeta 3 | 意见反馈 4 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 17 | 18 | 19 | 22 | 25 | 28 | 29 | 32 | 33 | 34 | 35 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 47 | 48 | 51 | 52 | 55 | 56 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /app/src/main/assets/about_gank_app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 23 | 28 | 29 | 30 | 31 |

32 | GankDaily,每日提供技术干货的App。 33 |

34 |
35 | 本App中所有数据均来自 干货集中营 。 36 |
37 |

38 | 作者  咕咚
39 | 个人主页   40 | 微博   41 | 知乎   42 | Github   43 |
44 |

45 |

46 | 项目开源地址:https://github.com/maoruibin/GankDaily 47 |

48 |

49 | 报告错误或提出需求:https://github.com/maoruibin/GankDaily/issues 50 |

51 |

52 | 感谢  @代码家  @drakeet 53 |

54 | -------------------------------------------------------------------------------- /app/src/main/assets/about_gank_site.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 23 | 24 | 25 | 26 |

27 | 干货集中营是一个技术干货共享平台。 28 |

29 |
30 | 每个工作日,网站都会分享一些技术干货信息,包括Android、iOS、App等技术干货,除此之外还有福利和休息视频可供你享用。 31 | 如果你是移动开发者,这个App一定很适合你。当然,如果你是一个宅男,也许你会对每天的福利更感兴趣。Enjoy it。 32 |
33 |

34 | 作者  代码家
35 |

    36 |
  1. Github  
  2. 37 |
  3. 微博  
  4. 38 |
39 |

40 |

41 | 干货集中营:http://gank.io/ 42 |

43 | -------------------------------------------------------------------------------- /app/src/main/assets/changelog.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 23 | 28 | 29 | 30 | 31 |

Version 1.3

32 |

33 | GankDaily,每日提供技术干货的App。 34 |

35 |
    36 |
  1. 优化:更新了主题色
  2. 37 |
  3. 新增:关于页面
  4. 38 |
  5. 删除:纯妹子页面
  6. 39 |
  7. 优化:妹子大图页面
  8. 40 |
41 |

获取最新GankDaily的动态,可通过以下方式

42 | 微博  @大侠咕咚
43 |

44 | 关于GankDaily 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/GankApp.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio; 21 | 22 | import android.app.Application; 23 | import android.content.Context; 24 | 25 | import com.orhanobut.logger.LogLevel; 26 | import com.orhanobut.logger.Logger; 27 | 28 | /** 29 | * Created by GuDong on 10/14/15 23:42. 30 | * Contact with gudong.name@gmail.com. 31 | */ 32 | public class GankApp extends Application { 33 | public static Context sContext; 34 | @Override 35 | public void onCreate() { 36 | super.onCreate(); 37 | sContext = this; 38 | //只有调试模式下 才启用日志输出 39 | if(BuildConfig.DEBUG){ 40 | Logger.init("Gank").hideThreadInfo().setMethodCount(0); 41 | }else{ 42 | Logger.init("Gank").setLogLevel(LogLevel.NONE); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/core/GankCategory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.core; 21 | 22 | public enum GankCategory { 23 | 福利, 24 | iOS, 25 | Android, 26 | App, 27 | 拓展资源, 28 | 瞎推荐, 29 | 休息视频; 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/core/GuDong.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.core; 21 | 22 | import com.gudong.gankio.data.GankData; 23 | import com.gudong.gankio.data.PrettyGirlData; 24 | import com.gudong.gankio.data.RestData; 25 | 26 | import retrofit.http.GET; 27 | import retrofit.http.Path; 28 | import rx.Observable; 29 | 30 | /** 31 | * Created by GuDong on 9/27/15. 32 | * Contact with gudong.name@gmail.com 33 | */ 34 | public interface GuDong { 35 | 36 | @GET("/data/福利/{pagesize}/{page}") 37 | Observable getPrettyGirlData(@Path("pagesize") int pagesize,@Path("page") int page); 38 | 39 | @GET("/data/休息视频/{pagesize}/{page}") 40 | Observable get休息视频Data(@Path("pagesize") int pagesize, @Path("page")int page); 41 | 42 | @GET("/day/{year}/{month}/{day}") 43 | Observable getGankData(@Path("year")int year,@Path("month")int month,@Path("day")int day); 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/core/MainFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.core; 21 | 22 | /** 23 | * Created by GuDong on 15/10/8. 24 | * Contact with gudong.name@gmail.com 25 | */ 26 | public class MainFactory { 27 | /** 28 | * 数据主机地址 29 | */ 30 | public static final String HOST = "http://gank.io/api"; 31 | 32 | private static GuDong mGuDong; 33 | 34 | protected static final Object monitor = new Object(); 35 | 36 | public static GuDong getGuDongInstance(){ 37 | synchronized (monitor){ 38 | if(mGuDong==null){ 39 | mGuDong = new MainRetrofit().getService(); 40 | } 41 | return mGuDong; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/core/MainRetrofit.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.core; 21 | 22 | import com.google.gson.Gson; 23 | import com.google.gson.GsonBuilder; 24 | import com.squareup.okhttp.OkHttpClient; 25 | 26 | import java.util.concurrent.TimeUnit; 27 | 28 | import retrofit.RestAdapter; 29 | import retrofit.client.OkClient; 30 | import retrofit.converter.GsonConverter; 31 | 32 | /** 33 | * Created by GuDong on 15/10/8. 34 | * Contact with gudong.name@gmail.com 35 | */ 36 | public class MainRetrofit { 37 | 38 | final GuDong mService; 39 | 40 | final Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").serializeNulls().create(); 41 | 42 | MainRetrofit() { 43 | OkHttpClient client = new OkHttpClient(); 44 | client.setReadTimeout(21, TimeUnit.SECONDS); 45 | RestAdapter restAdapter = new RestAdapter.Builder() 46 | .setClient(new OkClient(client)) 47 | .setEndpoint(MainFactory.HOST) 48 | .setConverter(new GsonConverter(gson)) 49 | .setLogLevel(RestAdapter.LogLevel.FULL) 50 | .build(); 51 | mService = restAdapter.create(GuDong.class); 52 | } 53 | 54 | public GuDong getService(){ 55 | return mService; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/data/BaseData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.data; 21 | 22 | /** 23 | * Created by GuDong on 9/28/15. 24 | * Contact with gudong.name@gmail.com 25 | */ 26 | public class BaseData { 27 | public boolean error; 28 | 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/data/GankData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.data; 21 | 22 | import com.gudong.gankio.data.entity.Gank; 23 | import com.google.gson.annotations.SerializedName; 24 | 25 | import java.util.List; 26 | 27 | /** 28 | * Created by GuDong on 10/9/15 22:20. 29 | * Contact with gudong.name@gmail.com. 30 | */ 31 | public class GankData extends BaseData { 32 | 33 | public List category; 34 | public Result results; 35 | 36 | public class Result { 37 | @SerializedName("Android") public List androidList; 38 | @SerializedName("休息视频") public List 休息视频List; 39 | @SerializedName("iOS") public List iOSList; 40 | @SerializedName("福利") public List 妹纸List; 41 | @SerializedName("拓展资源") public List 拓展资源List; 42 | @SerializedName("瞎推荐") public List 瞎推荐List; 43 | @SerializedName("App") public List appList; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/data/PrettyGirlData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.data; 21 | 22 | import com.gudong.gankio.data.entity.Girl; 23 | 24 | import java.util.List; 25 | 26 | /** 27 | * 妹子数据集合对象 28 | * Created by GuDong on 9/28/15. 29 | * Contact with gudong.name@gmail.com 30 | */ 31 | public class PrettyGirlData extends BaseData { 32 | public Listresults; 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/data/RestData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.data; 21 | 22 | import com.gudong.gankio.data.entity.Gank; 23 | 24 | import java.util.List; 25 | 26 | /** 27 | * Created by GuDong on 15/10/8. 28 | * Contact with gudong.name@gmail.com 29 | */ 30 | public class RestData extends BaseData { 31 | public Listresults; 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/data/entity/Gank.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.data.entity; 21 | 22 | import com.gudong.gankio.core.GankCategory; 23 | 24 | import java.io.Serializable; 25 | import java.util.Date; 26 | 27 | /** 28 | * Created by GuDong on 15/10/8. 29 | * Contact with gudong.name@gmail.com 30 | */ 31 | public class Gank extends Soul implements Cloneable,Serializable{ 32 | 33 | /** 34 | * createdAt : 2015-10-06T08:23:35.565Z 35 | * publishedAt : 2015-10-08T01:29:48.811Z 36 | * used : true 37 | * type : 休息视频 38 | * url : http://v.youku.com/v_show/id_XMTY4OTE3OTQ4.html 39 | * who : lxxself 40 | * desc : 耐克还有这广告,我良辰服气 41 | * updatedAt : 2015-10-08T01:29:49.219Z 42 | */ 43 | 44 | public boolean used; 45 | public String type; 46 | public String url; 47 | public String who; 48 | public String desc; 49 | public Date updatedAt; 50 | public Date createdAt; 51 | public Date publishedAt; 52 | 53 | /** 54 | * this item is header type of gank or not,if true, this item will show category name 55 | */ 56 | public boolean isHeader; 57 | 58 | public boolean is妹子(){ 59 | return type.equals(GankCategory.福利.name()); 60 | } 61 | 62 | @Override 63 | public Gank clone() { 64 | Gank gank = null; 65 | try{ 66 | gank = (Gank)super.clone(); 67 | }catch(CloneNotSupportedException e) { 68 | e.printStackTrace(); 69 | } 70 | return gank; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/data/entity/Girl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.data.entity; 21 | 22 | 23 | import java.util.Date; 24 | 25 | /** 26 | * Created by GuDong on 15/10/8. 27 | * Contact with gudong.name@gmail.com 28 | */ 29 | public class Girl extends Soul { 30 | 31 | /** 32 | * createdAt : 2015-10-07T05:42:23.910Z 33 | * publishedAt : 2015-10-08T01:29:48.812Z 34 | * used : true 35 | * type : 福利 36 | * url : http://ww4.sinaimg.cn/large/7a8aed7bgw1ewsip9thfoj20hs0qo774.jpg 37 | * who : 张涵宇 38 | * desc : 10.8 39 | * updatedAt : 2015-10-08T01:29:49.400Z 40 | */ 41 | 42 | public boolean used; 43 | public String type; 44 | public String url; 45 | public String who; 46 | public String desc; 47 | public Date createdAt; 48 | public Date publishedAt; 49 | public Date updatedAt; 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/data/entity/Soul.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.data.entity; 21 | 22 | /** 23 | * Created by GuDong on 15/10/8. 24 | * Contact with gudong.name@gmail.com 25 | */ 26 | public class Soul { 27 | protected long id; 28 | public String objectId; 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/presenter/BasePresenter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.presenter; 21 | 22 | import android.app.Activity; 23 | 24 | import com.gudong.gankio.core.GuDong; 25 | import com.gudong.gankio.core.MainFactory; 26 | import com.gudong.gankio.ui.view.IBaseView; 27 | 28 | /** 29 | * Created by GuDong on 10/29/15 14:08. 30 | * Contact with gudong.name@gmail.com. 31 | */ 32 | public class BasePresenter { 33 | 34 | protected GV mView; 35 | /** 36 | * TODO 这里用是否用Activity待考证 37 | */ 38 | protected Activity mContext; 39 | 40 | public static final GuDong mGuDong = MainFactory.getGuDongInstance(); 41 | 42 | public BasePresenter(Activity context, GV view) { 43 | mContext = context; 44 | mView = view; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/presenter/CustomDialogPresenter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.presenter; 21 | 22 | import android.app.Activity; 23 | import android.content.DialogInterface; 24 | import android.graphics.Color; 25 | import android.os.Bundle; 26 | import android.support.v4.app.Fragment; 27 | import android.support.v7.app.AlertDialog; 28 | import android.view.View; 29 | import android.webkit.WebSettings; 30 | import android.webkit.WebView; 31 | 32 | import com.gudong.gankio.R; 33 | import com.gudong.gankio.ui.view.ICustomDialog; 34 | import com.gudong.gankio.ui.fragment.CustomWebViewDialog; 35 | 36 | import java.io.BufferedReader; 37 | import java.io.InputStream; 38 | import java.io.InputStreamReader; 39 | 40 | /** 41 | * Created by GuDong on 11/6/15 16:00. 42 | * Contact with gudong.name@gmail.com. 43 | */ 44 | public class CustomDialogPresenter extends BasePresenter { 45 | 46 | private static final String EXTRA_DIALOG_TITLE = "DIALOG_TITLE"; 47 | private static final String EXTRA_HTML_FILE_NAME = "HTML_FILE_NAME"; 48 | private static final String EXTRA_ACCENT_COLOR = "ACCENT_COLOR"; 49 | 50 | private static final String KEY_UTF_8 = "UTF_8"; 51 | 52 | public CustomDialogPresenter(Activity context, ICustomDialog view) { 53 | super(context, view); 54 | } 55 | 56 | /** 57 | * create a custom dialog use web view load layout by html file 58 | * @param dialogTitle dialog title 59 | * @param htmlFileName html file name 60 | * @param accentColor accent color 61 | * @return a instance of CustomWebViewDialog 62 | */ 63 | public static CustomWebViewDialog create(String dialogTitle, String htmlFileName, int accentColor) { 64 | CustomWebViewDialog dialog = new CustomWebViewDialog(); 65 | Bundle args = new Bundle(); 66 | args.putString(EXTRA_DIALOG_TITLE, dialogTitle); 67 | args.putString(EXTRA_HTML_FILE_NAME, htmlFileName); 68 | args.putInt(EXTRA_ACCENT_COLOR, accentColor); 69 | dialog.setArguments(args); 70 | return dialog; 71 | } 72 | 73 | 74 | public AlertDialog makeOkDialog(Fragment fragment, View customView) { 75 | String dialogTitle = fragment.getArguments().getString(EXTRA_DIALOG_TITLE); 76 | String htmlFileName = fragment.getArguments().getString(EXTRA_HTML_FILE_NAME); 77 | int accentColor = fragment.getArguments().getInt(EXTRA_ACCENT_COLOR); 78 | 79 | final WebView webView = (WebView) customView.findViewById(R.id.webview); 80 | setWebView(webView); 81 | loadData(webView, htmlFileName, accentColor); 82 | 83 | AlertDialog dialog = new AlertDialog.Builder(mContext) 84 | .setTitle(dialogTitle) 85 | .setView(customView) 86 | .setPositiveButton(android.R.string.ok, null) 87 | .show(); 88 | 89 | return dialog; 90 | } 91 | 92 | /** 93 | * show positive na 94 | * @param fragment 95 | * @param customView 96 | * @return 97 | */ 98 | public AlertDialog makeMulActionDialog(Fragment fragment, View customView, 99 | String ok, DialogInterface.OnClickListener okListener, 100 | String negative, DialogInterface.OnClickListener negativeListener, 101 | String neutral,DialogInterface.OnClickListener neutralListener) { 102 | String dialogTitle = fragment.getArguments().getString(EXTRA_DIALOG_TITLE); 103 | String htmlFileName = fragment.getArguments().getString(EXTRA_HTML_FILE_NAME); 104 | int accentColor = fragment.getArguments().getInt(EXTRA_ACCENT_COLOR); 105 | 106 | final WebView webView = (WebView) customView.findViewById(R.id.webview); 107 | setWebView(webView); 108 | loadData(webView, htmlFileName, accentColor); 109 | 110 | AlertDialog dialog = new AlertDialog.Builder(mContext) 111 | .setTitle(dialogTitle) 112 | .setView(customView) 113 | .setPositiveButton(ok, okListener) 114 | .setNegativeButton(negative,negativeListener) 115 | .setNeutralButton(neutral,neutralListener) 116 | .show(); 117 | 118 | return dialog; 119 | } 120 | 121 | private void setWebView(WebView webView){ 122 | WebSettings settings = webView.getSettings(); 123 | settings.setDefaultTextEncodingName(KEY_UTF_8); 124 | settings.setJavaScriptEnabled(true); 125 | } 126 | 127 | private void loadData(WebView webView,String htmlFileName,int accentColor){ 128 | try { 129 | StringBuilder buf = new StringBuilder(); 130 | InputStream json = mContext.getAssets().open(htmlFileName); 131 | BufferedReader in = new BufferedReader(new InputStreamReader(json,KEY_UTF_8)); 132 | String str; 133 | while ((str = in.readLine()) != null) 134 | buf.append(str); 135 | in.close(); 136 | 137 | String formatLodString = buf.toString() 138 | .replace("{style-placeholder}", "body { background-color: #ffffff; color: #000; }") 139 | .replace("{link-color}", colorToHex(shiftColor(accentColor, true))) 140 | .replace("{link-color-active}", colorToHex(accentColor)); 141 | webView.loadDataWithBaseURL(null, formatLodString, "text/html", KEY_UTF_8, null); 142 | } catch (Throwable e) { 143 | webView.loadData("

Unable to load

" + e.getLocalizedMessage() + "

", "text/html", KEY_UTF_8); 144 | } 145 | } 146 | 147 | private String colorToHex(int color) { 148 | return Integer.toHexString(color).substring(2); 149 | } 150 | 151 | private int shiftColor(int color, boolean up) { 152 | float[] hsv = new float[3]; 153 | Color.colorToHSV(color, hsv); 154 | hsv[2] *= (up ? 1.1f : 0.9f); // value component 155 | return Color.HSVToColor(hsv); 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/presenter/GirlFacePresenter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.presenter; 21 | 22 | import android.app.Activity; 23 | import android.content.Context; 24 | import android.content.Intent; 25 | import android.graphics.Bitmap; 26 | import android.net.Uri; 27 | import android.os.AsyncTask; 28 | import android.os.Environment; 29 | import android.provider.MediaStore; 30 | import android.text.TextUtils; 31 | import android.widget.ImageView; 32 | 33 | import com.bumptech.glide.Glide; 34 | import com.gudong.gankio.R; 35 | import com.gudong.gankio.ui.view.IGirlFaceView; 36 | import com.gudong.gankio.util.TaskUtils; 37 | import com.orhanobut.logger.Logger; 38 | 39 | import java.io.File; 40 | import java.io.FileNotFoundException; 41 | import java.io.FileOutputStream; 42 | import java.io.IOException; 43 | import java.util.concurrent.ExecutionException; 44 | 45 | /** 46 | * Created by GuDong on 11/2/15 18:22. 47 | * Contact with gudong.name@gmail.com. 48 | */ 49 | public class GirlFacePresenter extends BasePresenter { 50 | public GirlFacePresenter(Activity context, IGirlFaceView view) { 51 | super(context, view); 52 | } 53 | 54 | public void saveFace(final String url, final ImageView ivGirlDetail) { 55 | if (!TextUtils.isEmpty(url)) { 56 | final String fileName = url.substring(url.lastIndexOf("/")+1); 57 | 58 | ivGirlDetail.post(new Runnable() { 59 | @Override 60 | public void run() { 61 | int width = ivGirlDetail.getWidth(); 62 | int height = ivGirlDetail.getHeight(); 63 | saveImageToSdCard(mContext, url, fileName,width,height); 64 | } 65 | }); 66 | } 67 | } 68 | 69 | private void saveImageToSdCard(final Context context, final String url, final String title, final int w, final int h){ 70 | TaskUtils.executeAsyncTask(new AsyncTask() { 71 | @Override 72 | protected Boolean doInBackground(Object... params) { 73 | Bitmap bmp = null; 74 | try { 75 | bmp = Glide.with(context).load(url).asBitmap().into(w,h).get(); 76 | } catch (InterruptedException e) { 77 | e.printStackTrace(); 78 | } catch (ExecutionException e) { 79 | e.printStackTrace(); 80 | } 81 | if (bmp == null) { 82 | return false; 83 | } 84 | 85 | // 首先保存图片 86 | File appDir = new File(getSDPath(), "Meizhi2"); 87 | if (!appDir.exists()) { 88 | boolean is = appDir.mkdir(); 89 | if(is){ 90 | Logger.i("create suc"); 91 | }else{ 92 | Logger.i("create fail"); 93 | } 94 | } 95 | File file = new File(appDir, title); 96 | 97 | try { 98 | FileOutputStream fos = new FileOutputStream(file); 99 | bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos); 100 | fos.flush(); 101 | fos.close(); 102 | } catch (IOException e) { 103 | e.printStackTrace(); 104 | return false; 105 | } 106 | 107 | // 其次把文件插入到系统图库 108 | try { 109 | MediaStore.Images.Media.insertImage(context.getContentResolver(), 110 | file.getAbsolutePath(), title, null); 111 | } catch (FileNotFoundException e) { 112 | e.printStackTrace(); 113 | } 114 | 115 | // 最后通知图库更新 116 | Intent scannerIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, 117 | Uri.parse("file://" + file.getAbsolutePath())); 118 | context.sendBroadcast(scannerIntent); 119 | 120 | return true; 121 | } 122 | 123 | @Override 124 | protected void onPostExecute(Boolean result) { 125 | super.onPostExecute(result); 126 | String msg; 127 | if (result) { 128 | File appDir = new File(Environment.getExternalStorageDirectory(), "Meizhi"); 129 | if (!appDir.exists()) { 130 | appDir.mkdir(); 131 | } 132 | msg = String.format(context.getString(R.string.picture_has_save_to), 133 | appDir.getAbsolutePath()); 134 | mView.saveSuccess(msg); 135 | } else { 136 | msg = context.getString(R.string.picture_save_fail); 137 | mView.showFailInfo(msg); 138 | } 139 | 140 | } 141 | }); 142 | } 143 | 144 | public String getSDPath(){ 145 | return Environment.getExternalStorageDirectory().toString(); 146 | } 147 | 148 | 149 | } 150 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/presenter/ViewListPresenter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.presenter; 21 | 22 | import android.app.Activity; 23 | 24 | import com.gudong.gankio.data.PrettyGirlData; 25 | import com.gudong.gankio.data.entity.Girl; 26 | import com.gudong.gankio.data.RestData; 27 | import com.gudong.gankio.ui.view.IViewListView; 28 | 29 | import java.util.List; 30 | 31 | import rx.Observable; 32 | import rx.Subscriber; 33 | import rx.android.schedulers.AndroidSchedulers; 34 | import rx.functions.Func1; 35 | import rx.functions.Func2; 36 | 37 | /** 38 | * 首页视图控制器 39 | * Created by GuDong on 10/29/15 14:07. 40 | * Contact with gudong.name@gmail.com. 41 | */ 42 | public class ViewListPresenter extends BasePresenter{ 43 | 44 | private int mCurrentPage = 1; 45 | 46 | /** 47 | * the count of the size of one request 48 | */ 49 | private static final int PAGE_SIZE = 10; 50 | 51 | public ViewListPresenter(Activity context, IViewListView view) { 52 | super(context, view); 53 | } 54 | 55 | public void resetCurrentPage(){ 56 | mCurrentPage = 1; 57 | } 58 | 59 | /** 60 | * 只有当前只加载了第一页 那么下拉刷新才应该去执行数据请求,如果加载的页数超过两页, 61 | * 则不去执行重新加载的数据请求,此时的刷新为假刷新,不去请求数据。这是一种良好的用户体验。愚以为~ 62 | * @return 63 | */ 64 | public boolean shouldRefillGirls(){ 65 | return mCurrentPage <= 2; 66 | } 67 | 68 | /** 69 | * reload girls data it will clear history girls so bad ! 70 | */ 71 | public void refillGirls(){ 72 | Observable.zip( 73 | mGuDong.getPrettyGirlData(PAGE_SIZE, mCurrentPage), 74 | mGuDong.get休息视频Data(PAGE_SIZE, mCurrentPage), 75 | new Func2() { 76 | @Override 77 | public PrettyGirlData call(PrettyGirlData prettyGirlData, RestData RestData) { 78 | return createGirlInfoWith休息视频(prettyGirlData, RestData); 79 | } 80 | }) 81 | .map(new Func1>() { 82 | @Override 83 | public List call(PrettyGirlData prettyGirlData) { 84 | return prettyGirlData.results; 85 | } 86 | }) 87 | .flatMap(new Func1, Observable>() { 88 | @Override 89 | public Observable call(List girls) { 90 | return Observable.from(girls); 91 | } 92 | }) 93 | .toSortedList(new Func2() { 94 | @Override 95 | public Integer call(Girl girl, Girl girl2) { 96 | return girl2.publishedAt.compareTo(girl.publishedAt); 97 | } 98 | }) 99 | .observeOn(AndroidSchedulers.mainThread()) 100 | .subscribe(new Subscriber>() { 101 | @Override 102 | public void onCompleted() { 103 | 104 | } 105 | 106 | @Override 107 | public void onError(Throwable e) { 108 | mView.showErrorView(e); 109 | mView.getDataFinish(); 110 | } 111 | 112 | @Override 113 | public void onNext(List girls) { 114 | if (girls.isEmpty()) { 115 | mView.showEmptyView(); 116 | } else if (girls.size() < PAGE_SIZE) { 117 | mView.fillData(girls); 118 | mView.hasNoMoreData(); 119 | } else if (girls.size() == PAGE_SIZE) { 120 | mView.fillData(girls); 121 | mCurrentPage++; 122 | } 123 | mView.getDataFinish(); 124 | } 125 | }); 126 | } 127 | 128 | public void getDataMore(){ 129 | Observable.zip( 130 | mGuDong.getPrettyGirlData(PAGE_SIZE,mCurrentPage), 131 | mGuDong.get休息视频Data(PAGE_SIZE,mCurrentPage), 132 | new Func2() { 133 | @Override 134 | public PrettyGirlData call(PrettyGirlData prettyGirlData, RestData RestData) { 135 | return createGirlInfoWith休息视频(prettyGirlData, RestData); 136 | } 137 | }) 138 | .map(new Func1>() { 139 | @Override 140 | public List call(PrettyGirlData prettyGirlData) { 141 | return prettyGirlData.results; 142 | } 143 | }) 144 | .flatMap(new Func1, Observable>() { 145 | @Override 146 | public Observable call(List girls) { 147 | return Observable.from(girls); 148 | } 149 | }) 150 | .toSortedList(new Func2() { 151 | @Override 152 | public Integer call(Girl girl, Girl girl2) { 153 | return girl2.publishedAt.compareTo(girl.publishedAt); 154 | } 155 | }) 156 | .observeOn(AndroidSchedulers.mainThread()) 157 | .subscribe(new Subscriber>() { 158 | @Override 159 | public void onCompleted() { 160 | 161 | } 162 | 163 | @Override 164 | public void onError(Throwable e) { 165 | mView.showErrorView(e); 166 | mView.getDataFinish(); 167 | } 168 | 169 | @Override 170 | public void onNext(List girls) { 171 | if (girls.isEmpty()) { 172 | mView.hasNoMoreData(); 173 | } else if (girls.size() < PAGE_SIZE) { 174 | mView.appendMoreDataToView(girls); 175 | mView.hasNoMoreData(); 176 | } else if (girls.size() == PAGE_SIZE) { 177 | mView.appendMoreDataToView(girls); 178 | mCurrentPage++; 179 | } 180 | mView.getDataFinish(); 181 | } 182 | }); 183 | } 184 | 185 | private PrettyGirlData createGirlInfoWith休息视频(PrettyGirlData girlData,RestData data){ 186 | int restSize = data.results.size(); 187 | for (int i = 0; i < girlData.results.size(); i++) { 188 | if(i<=restSize-1){ 189 | Girl girl = girlData.results.get(i); 190 | girl.desc+=" "+data.results.get(i).desc; 191 | }else{ 192 | break; 193 | } 194 | } 195 | return girlData; 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/presenter/WebPresenter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.presenter; 21 | 22 | import android.app.Activity; 23 | import android.graphics.Bitmap; 24 | import android.net.Uri; 25 | import android.text.TextUtils; 26 | import android.webkit.WebSettings; 27 | import android.webkit.WebView; 28 | import android.webkit.WebViewClient; 29 | 30 | import com.gudong.gankio.ui.view.IWebView; 31 | 32 | /** 33 | * Created by GuDong on 11/2/15 17:05. 34 | * Contact with gudong.name@gmail.com. 35 | */ 36 | public class WebPresenter extends BasePresenter { 37 | public WebPresenter(Activity context, IWebView view) { 38 | super(context, view); 39 | } 40 | 41 | public void setUpWebView(WebView webView){ 42 | WebSettings settings = webView.getSettings(); 43 | settings.setJavaScriptEnabled(true); 44 | settings.setLoadWithOverviewMode(true); 45 | settings.setAppCacheEnabled(true); 46 | settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN); 47 | settings.setSupportZoom(true); 48 | webView.setWebViewClient(new LoveClient()); 49 | } 50 | 51 | public void loadUrl(WebView webView,String url){ 52 | webView.loadUrl(url); 53 | } 54 | 55 | private class LoveClient extends WebViewClient { 56 | 57 | public boolean shouldOverrideUrlLoading(WebView view, String url) { 58 | if (TextUtils.isEmpty(url)){ 59 | return true; 60 | } 61 | if(Uri.parse(url).getHost().equals("github.com")){ 62 | return false; 63 | } 64 | view.loadUrl(url); 65 | return true; 66 | } 67 | 68 | @Override 69 | public void onPageStarted(WebView view, String url, Bitmap favicon) { 70 | super.onPageStarted(view, url, favicon); 71 | mView.showRefresh(); 72 | } 73 | 74 | @Override 75 | public void onPageFinished(WebView view, String url) { 76 | super.onPageFinished(view, url); 77 | mView.hideRefresh(); 78 | } 79 | 80 | @Override 81 | public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { 82 | super.onReceivedError(view, errorCode, description, failingUrl); 83 | mView.hideRefresh(); 84 | mView.showLoadErrorMessage(description); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/ui/activity/AboutActivity.java: -------------------------------------------------------------------------------- 1 | package com.gudong.gankio.ui.activity; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.content.pm.PackageManager; 6 | import android.net.Uri; 7 | import android.support.annotation.NonNull; 8 | import android.support.v4.content.ContextCompat; 9 | import android.view.MenuItem; 10 | 11 | import com.danielstone.materialaboutlibrary.ConvenienceBuilder; 12 | import com.danielstone.materialaboutlibrary.MaterialAboutActivity; 13 | import com.danielstone.materialaboutlibrary.items.MaterialAboutActionItem; 14 | import com.danielstone.materialaboutlibrary.model.MaterialAboutCard; 15 | import com.danielstone.materialaboutlibrary.model.MaterialAboutList; 16 | import com.gudong.gankio.R; 17 | 18 | import static com.gudong.gankio.R.string.website; 19 | 20 | public class AboutActivity extends MaterialAboutActivity { 21 | 22 | public static void gotoAboutActivity(Context context){ 23 | context.startActivity(new Intent(context,AboutActivity.class)); 24 | } 25 | @Override @NonNull protected MaterialAboutList getMaterialAboutList(@NonNull Context context) { 26 | MaterialAboutCard.Builder appCardBuilder = new MaterialAboutCard.Builder(); 27 | try { 28 | appCardBuilder.addItem( 29 | ConvenienceBuilder.createVersionActionItem( 30 | context, 31 | ContextCompat.getDrawable(context, R.drawable.ic_issues), 32 | getString(R.string.version), 33 | false) 34 | ); 35 | } catch (PackageManager.NameNotFoundException e) { 36 | e.printStackTrace(); 37 | } 38 | 39 | appCardBuilder.addItem(ConvenienceBuilder.createRateActionItem(context, ContextCompat.getDrawable(context, R.drawable.ic_star_filled), 40 | getString(R.string.rate_app), null)); 41 | 42 | appCardBuilder.addItem(new MaterialAboutActionItem.Builder() 43 | .text(R.string.report_issue) 44 | .subText(R.string.report_issue_here) 45 | .icon(ContextCompat.getDrawable(context, R.drawable.ic_bug)) 46 | .setOnClickListener(ConvenienceBuilder.createWebsiteOnClickAction(AboutActivity.this, Uri.parse("https://github.com/maoruibin/GankDaily/issues"))) 47 | .build()); 48 | 49 | MaterialAboutCard.Builder authorCardBuilder = new MaterialAboutCard.Builder(); 50 | authorCardBuilder.title(R.string.author); 51 | authorCardBuilder.addItem(new MaterialAboutActionItem.Builder() 52 | .text("咕咚") 53 | .subText("maoruibin") 54 | .icon(ContextCompat.getDrawable(context, R.drawable.ic_profile)) 55 | .setOnClickListener(ConvenienceBuilder.createWebsiteOnClickAction(AboutActivity.this, Uri.parse("http://gudong.name/"))) 56 | .build()); 57 | authorCardBuilder.addItem(new MaterialAboutActionItem.Builder() 58 | .text(R.string.fork_github) 59 | .icon(ContextCompat.getDrawable(context, R.drawable.ic_github)) 60 | .setOnClickListener(ConvenienceBuilder.createWebsiteOnClickAction(AboutActivity.this, Uri.parse("https://github.com/maoruibin/GankDaily"))) 61 | .build()); 62 | 63 | authorCardBuilder.addItem(ConvenienceBuilder.createEmailItem(context, ContextCompat.getDrawable(context, R.drawable.ic_email), 64 | getString(R.string.send_email), true, getString(R.string.email_address), getString(R.string.question_concerning_fasthub))); 65 | 66 | MaterialAboutCard.Builder logoAuthor = new MaterialAboutCard.Builder(); 67 | logoAuthor.title(getString(R.string.contact)); 68 | 69 | logoAuthor.addItem(new MaterialAboutActionItem.Builder() 70 | .text(website) 71 | .subText(R.string.website_sub) 72 | .icon(ContextCompat.getDrawable(context, R.drawable.ic_brower)) 73 | .setOnClickListener(ConvenienceBuilder.createWebsiteOnClickAction(AboutActivity.this, Uri.parse("http://gudong.name/"))) 74 | .build()); 75 | logoAuthor.addItem(new MaterialAboutActionItem.Builder() 76 | .text(R.string.weibo) 77 | .subText(R.string.weibo_nick) 78 | .icon(ContextCompat.getDrawable(context, R.drawable.ic_profile)) 79 | .setOnClickListener(ConvenienceBuilder.createWebsiteOnClickAction(AboutActivity.this, Uri.parse("http://weibo.com/maoruibin"))) 80 | .build()); 81 | logoAuthor.addItem(new MaterialAboutActionItem.Builder() 82 | .text(R.string.github) 83 | .subText(R.string.github_id) 84 | .icon(ContextCompat.getDrawable(context, R.drawable.ic_github)) 85 | .setOnClickListener(ConvenienceBuilder.createWebsiteOnClickAction(AboutActivity.this, Uri.parse("https://github.com/maoruibin"))) 86 | .build()); 87 | 88 | return new MaterialAboutList(appCardBuilder.build(), authorCardBuilder.build(), logoAuthor.build()); 89 | } 90 | 91 | @Override protected CharSequence getActivityTitle() { 92 | return getString(R.string.app_name); 93 | } 94 | 95 | 96 | @Override public boolean onOptionsItemSelected(MenuItem item) { 97 | if (item.getItemId() == android.R.id.home) { 98 | finish(); 99 | } 100 | return false;//override 101 | } 102 | 103 | } -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/ui/activity/BaseActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.ui.activity; 21 | 22 | import android.os.Bundle; 23 | import android.support.v7.app.AppCompatActivity; 24 | import android.support.v7.widget.Toolbar; 25 | import android.view.Menu; 26 | import android.view.MenuItem; 27 | 28 | import com.gudong.gankio.R; 29 | import com.gudong.gankio.presenter.BasePresenter; 30 | import com.umeng.analytics.MobclickAgent; 31 | 32 | import butterknife.Bind; 33 | import butterknife.ButterKnife; 34 | 35 | /** 36 | * Created by GuDong on 10/14/15 23:05. 37 | * Contact with gudong.name@gmail.com. 38 | */ 39 | public abstract class BaseActivity

extends AppCompatActivity { 40 | @Bind(R.id.toolbar) 41 | protected Toolbar mToolbar; 42 | /** 43 | * the presenter of this Activity 44 | */ 45 | protected P mPresenter; 46 | 47 | /** 48 | * TODO use Dagger2 instance Presenter 49 | */ 50 | protected abstract void initPresenter(); 51 | 52 | /** 53 | * set layout of this activity 54 | * 55 | * @return the id of layout 56 | */ 57 | protected abstract int getLayout(); 58 | 59 | @Override 60 | protected void onCreate(Bundle savedInstanceState) { 61 | super.onCreate(savedInstanceState); 62 | setContentView(getLayout()); 63 | ButterKnife.bind(this); 64 | initPresenter(); 65 | checkPresenterIsNull(); 66 | initToolBar(); 67 | } 68 | 69 | @Override 70 | protected void onResume() { 71 | super.onResume(); 72 | MobclickAgent.onResume(this); 73 | } 74 | 75 | @Override 76 | protected void onPause() { 77 | super.onPause(); 78 | MobclickAgent.onPause(this); 79 | } 80 | 81 | private void checkPresenterIsNull() { 82 | if (mPresenter == null) { 83 | throw new IllegalStateException("please init mPresenter in initPresenter() method "); 84 | } 85 | } 86 | 87 | /** 88 | * set the id of menu 89 | * 90 | * @return if values is less then zero ,and the activity will not show menu 91 | */ 92 | protected int getMenuRes() { 93 | return -1; 94 | } 95 | 96 | ; 97 | 98 | @Override 99 | public boolean onCreateOptionsMenu(Menu menu) { 100 | if (getMenuRes() < 0) return true; 101 | getMenuInflater().inflate(getMenuRes(), menu); 102 | return true; 103 | } 104 | 105 | @Override 106 | public boolean onOptionsItemSelected(MenuItem item) { 107 | switch (item.getItemId()) { 108 | case android.R.id.home: 109 | //don't use finish() and use onBackPressed() will be a good practice , trust me ! 110 | onBackPressed(); 111 | break; 112 | } 113 | return super.onOptionsItemSelected(item); 114 | } 115 | 116 | final private void initToolBar() { 117 | if (mToolbar == null) { 118 | throw new NullPointerException("please add a Toolbar in your layout."); 119 | } 120 | setSupportActionBar(mToolbar); 121 | } 122 | 123 | public void setTitle(String strTitle, boolean showHome) { 124 | setTitle(strTitle); 125 | getSupportActionBar().setDisplayShowHomeEnabled(showHome); 126 | getSupportActionBar().setDisplayHomeAsUpEnabled(showHome); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/ui/activity/BaseSwipeRefreshActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.ui.activity; 21 | 22 | import android.os.Bundle; 23 | import android.support.annotation.CheckResult; 24 | import android.support.v4.widget.SwipeRefreshLayout; 25 | 26 | import com.gudong.gankio.R; 27 | import com.gudong.gankio.presenter.BasePresenter; 28 | import com.gudong.gankio.ui.view.ISwipeRefreshView; 29 | 30 | import butterknife.Bind; 31 | 32 | /** 33 | * base activity for that have a function with swipe refresh 34 | * Created by GuDong on 10/29/15 18:06. 35 | * Contact with gudong.name@gmail.com. 36 | */ 37 | public abstract class BaseSwipeRefreshActivity

extends BaseActivity

implements ISwipeRefreshView { 38 | 39 | @Bind(R.id.swipe_refresh_layout) 40 | protected SwipeRefreshLayout mSwipeRefreshLayout; 41 | 42 | @Override 43 | protected void onCreate(Bundle savedInstanceState) { 44 | super.onCreate(savedInstanceState); 45 | initSwipeLayout(); 46 | } 47 | 48 | private void initSwipeLayout(){ 49 | mSwipeRefreshLayout.setColorSchemeResources(R.color.colorPrimary, R.color.colorPrimaryDark, R.color.colorAccent); 50 | mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { 51 | @Override 52 | public void onRefresh() { 53 | if (prepareRefresh()) { 54 | onRefreshStarted(); 55 | } else { 56 | //产生一个加载数据的假象 57 | hideRefresh(); 58 | } 59 | } 60 | }); 61 | } 62 | 63 | /** 64 | * check data status 65 | * @return return true indicate it should load data really else indicate don't refresh 66 | */ 67 | protected boolean prepareRefresh(){ 68 | return true; 69 | } 70 | 71 | /** 72 | * the method of get data 73 | */ 74 | protected abstract void onRefreshStarted(); 75 | 76 | @Override 77 | public void hideRefresh() { 78 | // 防止刷新消失太快,让子弹飞一会儿. do not use lambda!! 79 | mSwipeRefreshLayout.postDelayed(new Runnable() { 80 | @Override 81 | public void run() { 82 | if(mSwipeRefreshLayout != null){ 83 | mSwipeRefreshLayout.setRefreshing(false); 84 | } 85 | } 86 | },1000); 87 | } 88 | 89 | @Override 90 | public void showRefresh() { 91 | mSwipeRefreshLayout.setRefreshing(true); 92 | } 93 | 94 | /** 95 | * check refresh layout is refreshing 96 | * @return if the refresh layout is refreshing return true else return false 97 | */ 98 | @CheckResult 99 | protected boolean isRefreshing(){ 100 | return mSwipeRefreshLayout.isRefreshing(); 101 | } 102 | 103 | @Override 104 | public void getDataFinish() { 105 | hideRefresh(); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/ui/activity/GirlFaceActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.ui.activity; 21 | 22 | import android.annotation.TargetApi; 23 | import android.content.Intent; 24 | import android.os.Build; 25 | import android.os.Bundle; 26 | import android.support.v4.app.ActivityCompat; 27 | import android.support.v4.app.ActivityOptionsCompat; 28 | import android.support.v4.util.Pair; 29 | import android.support.v4.view.ViewCompat; 30 | import android.transition.Transition; 31 | import android.view.MenuItem; 32 | import android.view.View; 33 | 34 | import com.bumptech.glide.Glide; 35 | import com.bumptech.glide.load.engine.DiskCacheStrategy; 36 | import com.github.chrisbanes.photoview.PhotoView; 37 | import com.gudong.gankio.R; 38 | import com.gudong.gankio.presenter.GirlFacePresenter; 39 | import com.gudong.gankio.ui.view.IGirlFaceView; 40 | import com.gudong.gankio.util.ToastUtils; 41 | 42 | import butterknife.Bind; 43 | import butterknife.OnClick; 44 | 45 | public class GirlFaceActivity extends BaseActivity implements IGirlFaceView { 46 | 47 | private static final String EXTRA_BUNDLE_URL = "BUNDLE_URL"; 48 | private static final String EXTRA_BUNDLE_TITLE = "BUNDLE_TITLE"; 49 | 50 | private static final String VIEW_NAME_HEADER_IMAGE = "detail:header:image"; 51 | private static final String VIEW_NAME_HEADER_TITLE = "detail:header:title"; 52 | 53 | @Bind(R.id.iv_girl_detail) 54 | PhotoView mIvGirlDetail; 55 | 56 | private String mUrl; 57 | 58 | 59 | public static void gotoWatchGirlDetail(BaseActivity context, String url, String title, final View viewImage, final View viewText) { 60 | Intent intent = new Intent(context, GirlFaceActivity.class); 61 | intent.putExtra(EXTRA_BUNDLE_URL, url); 62 | intent.putExtra(EXTRA_BUNDLE_TITLE, title); 63 | 64 | ActivityOptionsCompat activityOptions = ActivityOptionsCompat.makeSceneTransitionAnimation( 65 | context, new Pair(viewImage, 66 | VIEW_NAME_HEADER_IMAGE)); 67 | 68 | ActivityCompat.startActivity(context, intent, activityOptions.toBundle()); 69 | } 70 | 71 | 72 | @Override 73 | protected int getLayout() { 74 | return R.layout.activity_girl_detail; 75 | } 76 | 77 | @Override 78 | protected void onCreate(Bundle savedInstanceState) { 79 | super.onCreate(savedInstanceState); 80 | 81 | mUrl = getIntent().getStringExtra(EXTRA_BUNDLE_URL); 82 | setTitle("", true); 83 | ViewCompat.setTransitionName(mIvGirlDetail, VIEW_NAME_HEADER_IMAGE); 84 | loadItem(); 85 | } 86 | 87 | private void loadItem() { 88 | Glide.with(this) 89 | .load(mUrl) 90 | .diskCacheStrategy(DiskCacheStrategy.ALL) 91 | .dontAnimate() 92 | .into(mIvGirlDetail); 93 | } 94 | 95 | @Override 96 | protected void initPresenter() { 97 | mPresenter = new GirlFacePresenter(this, this); 98 | } 99 | 100 | @Override 101 | protected int getMenuRes() { 102 | return R.menu.menu_girl_detail; 103 | } 104 | 105 | @Override 106 | public boolean onOptionsItemSelected(MenuItem item) { 107 | int id = item.getItemId(); 108 | if (id == R.id.action_save) { 109 | mPresenter.saveFace(getIntent().getStringExtra(EXTRA_BUNDLE_URL), mIvGirlDetail); 110 | return true; 111 | } 112 | return super.onOptionsItemSelected(item); 113 | } 114 | 115 | 116 | @Override 117 | public void saveSuccess(String message) { 118 | ToastUtils.showShort(message); 119 | } 120 | 121 | @Override 122 | public void showFailInfo(String error) { 123 | ToastUtils.showShort(error); 124 | } 125 | 126 | /** 127 | * Try and add a {@link Transition.TransitionListener} to the entering shared element 128 | * {@link Transition}. We do this so that we can load the full-size image after the transition 129 | * has completed. 130 | * 131 | * @return true if we were successful in adding a listener to the enter transition 132 | */ 133 | @TargetApi(Build.VERSION_CODES.LOLLIPOP) 134 | private boolean addTransitionListener() { 135 | final Transition transition = getWindow().getSharedElementEnterTransition(); 136 | 137 | if (transition != null) { 138 | // There is an entering shared element transition so add a listener to it 139 | transition.addListener(new Transition.TransitionListener() { 140 | @Override 141 | public void onTransitionEnd(Transition transition) { 142 | // As the transition has ended, we can now load the full-size image 143 | loadItem(); 144 | 145 | // Make sure we remove ourselves as a listener 146 | transition.removeListener(this); 147 | } 148 | 149 | @Override 150 | public void onTransitionStart(Transition transition) { 151 | // No-op 152 | } 153 | 154 | @Override 155 | public void onTransitionCancel(Transition transition) { 156 | // Make sure we remove ourselves as a listener 157 | transition.removeListener(this); 158 | } 159 | 160 | @Override 161 | public void onTransitionPause(Transition transition) { 162 | // No-op 163 | } 164 | 165 | @Override 166 | public void onTransitionResume(Transition transition) { 167 | // No-op 168 | } 169 | }); 170 | return true; 171 | } 172 | // If we reach here then we have not added a listener 173 | return false; 174 | } 175 | 176 | @OnClick(R.id.iv_girl_detail) 177 | public void onViewClicked() { 178 | if(getSupportActionBar().isShowing()){ 179 | getSupportActionBar().hide(); 180 | }else{ 181 | getSupportActionBar().show(); 182 | } 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/ui/activity/MainActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.ui.activity; 21 | 22 | import android.content.Intent; 23 | import android.os.Bundle; 24 | import android.os.Handler; 25 | import android.support.design.widget.Snackbar; 26 | import android.support.v7.widget.LinearLayoutManager; 27 | import android.support.v7.widget.RecyclerView; 28 | import android.view.MenuItem; 29 | import android.view.View; 30 | 31 | import com.gudong.gankio.R; 32 | import com.gudong.gankio.data.entity.Gank; 33 | import com.gudong.gankio.presenter.MainPresenter; 34 | import com.gudong.gankio.ui.adapter.MainListAdapter; 35 | import com.gudong.gankio.ui.view.IMainView; 36 | import com.gudong.gankio.util.DateUtil; 37 | import com.gudong.gankio.util.DialogUtil; 38 | 39 | import java.util.Date; 40 | import java.util.List; 41 | 42 | import butterknife.Bind; 43 | 44 | /** 45 | * this Activity is use to MainActivity and when scroll bottom , it will load more data. 46 | * at the same time, it is also use to show the gank info of one day ( I don't know is it good like this and design it) 47 | * if getIntent() contains bundle of EXTRA_BUNDLE_GANK ,it indicate this Activity is MainActivity , 48 | * otherwise this Activity is a GankActivity used to show Gank info of one day 49 | */ 50 | public class MainActivity extends BaseSwipeRefreshActivity implements IMainView,MainListAdapter.IClickMainItem { 51 | 52 | @Bind(R.id.rv_gank) 53 | RecyclerView mRvGank; 54 | MainListAdapter mAdapter; 55 | 56 | /** 57 | * the flag of has more data or not 58 | */ 59 | private boolean mHasMoreData = true; 60 | 61 | 62 | @Override 63 | protected int getLayout() { 64 | return R.layout.activity_main; 65 | } 66 | 67 | @Override 68 | protected void initPresenter() { 69 | mPresenter = new MainPresenter(this, this); 70 | } 71 | 72 | @Override 73 | protected void onCreate(Bundle savedInstanceState) { 74 | super.onCreate(savedInstanceState); 75 | mPresenter.checkAutoUpdateByUmeng(); 76 | initRecycleView(); 77 | setTitle(getString(R.string.app_name), false); 78 | //check update info by Umeng 79 | mPresenter.checkVersionInfo(); 80 | } 81 | 82 | @Override 83 | protected void onPostCreate(Bundle savedInstanceState) { 84 | super.onPostCreate(savedInstanceState); 85 | // make swipeRefreshLayout visible manually 86 | new Handler().postDelayed(new Runnable() { 87 | @Override 88 | public void run() { 89 | showRefresh(); 90 | } 91 | }, 568); 92 | getData(); 93 | } 94 | 95 | @Override 96 | protected void onRefreshStarted() { 97 | getData(); 98 | } 99 | 100 | @Override 101 | protected boolean prepareRefresh() { 102 | return mPresenter.shouldRefillData(); 103 | } 104 | 105 | @Override 106 | protected int getMenuRes() { 107 | return R.menu.menu_main; 108 | } 109 | 110 | @Override 111 | public boolean onOptionsItemSelected(MenuItem item) { 112 | int id = item.getItemId(); 113 | switch (id){ 114 | case R.id.action_view_list: 115 | startActivity(new Intent(this,ViewListActivity.class)); 116 | break; 117 | case R.id.action_github_tending: 118 | String url = getString(R.string.url_github_trending); 119 | String title = getString(R.string.action_github_trending); 120 | WebActivity.gotoWebActivity(this,url,title); 121 | break; 122 | case R.id.action_about: 123 | AboutActivity.gotoAboutActivity(this); 124 | break; 125 | case R.id.action_opinion: 126 | String urlOpinion = getString(R.string.url_github_issue); 127 | String titleOpinion = getString(R.string.action_github_issue); 128 | WebActivity.gotoWebActivity(this,urlOpinion,titleOpinion); 129 | break; 130 | } 131 | return super.onOptionsItemSelected(item); 132 | } 133 | 134 | @Override 135 | public void fillData(List data) { 136 | mAdapter.updateWithClear(data); 137 | } 138 | 139 | @Override 140 | public void appendMoreDataToView(List data) { 141 | mAdapter.update(data); 142 | } 143 | 144 | @Override 145 | public void hasNoMoreData() { 146 | mHasMoreData = false; 147 | Snackbar.make(mRvGank, R.string.no_more_gank, Snackbar.LENGTH_LONG) 148 | .setAction(R.string.action_to_top, new View.OnClickListener() { 149 | @Override 150 | public void onClick(View v) { 151 | (mRvGank.getLayoutManager()).smoothScrollToPosition(mRvGank,null,0); 152 | } 153 | }) 154 | .show(); 155 | } 156 | 157 | @Override 158 | public void showChangeLogInfo(String assetFileName) { 159 | DialogUtil.showCustomDialog(this, getSupportFragmentManager(), getString(R.string.change_log), assetFileName, ""); 160 | } 161 | 162 | @Override 163 | public void showEmptyView() { 164 | //our meizi will not empty and we can new it 165 | } 166 | 167 | @Override 168 | public void showErrorView(Throwable throwable) { 169 | throwable.printStackTrace(); 170 | } 171 | 172 | @Override 173 | public void onClickGankItemGirl(Gank gank, View viewImage, View viewText) { 174 | GirlFaceActivity.gotoWatchGirlDetail(this, gank.url, DateUtil.toDate(gank.publishedAt), viewImage, viewText); 175 | } 176 | 177 | @Override 178 | public void onClickGankItemNormal(Gank gank, View view) { 179 | WebActivity.gotoWebActivity(this, gank.url, gank.desc); 180 | } 181 | 182 | private void getData() { 183 | mPresenter.getData(new Date(System.currentTimeMillis())); 184 | } 185 | 186 | 187 | private void initRecycleView() { 188 | final LinearLayoutManager layoutManager = new LinearLayoutManager(this); 189 | mRvGank.setLayoutManager(layoutManager); 190 | mAdapter = new MainListAdapter(this); 191 | mAdapter.setIClickItem(this); 192 | mRvGank.setAdapter(mAdapter); 193 | 194 | mRvGank.addOnScrollListener(new RecyclerView.OnScrollListener() { 195 | @Override 196 | public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 197 | super.onScrolled(recyclerView, dx, dy); 198 | boolean isBottom = 199 | layoutManager.findLastCompletelyVisibleItemPosition() >= mAdapter.getItemCount() - 4; 200 | if (!mSwipeRefreshLayout.isRefreshing() && isBottom && mHasMoreData) { 201 | showRefresh(); 202 | mPresenter.getDataMore(); 203 | } else if (!mHasMoreData) { 204 | hasNoMoreData(); 205 | } 206 | } 207 | }); 208 | } 209 | } 210 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/ui/activity/ViewListActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.ui.activity; 21 | 22 | import android.os.Bundle; 23 | import android.support.annotation.CheckResult; 24 | import android.support.design.widget.Snackbar; 25 | import android.support.v7.widget.RecyclerView; 26 | import android.support.v7.widget.StaggeredGridLayoutManager; 27 | import android.view.View; 28 | 29 | import com.gudong.gankio.R; 30 | import com.gudong.gankio.data.entity.Gank; 31 | import com.gudong.gankio.data.entity.Girl; 32 | import com.gudong.gankio.presenter.ViewListPresenter; 33 | import com.gudong.gankio.ui.view.IViewListView; 34 | import com.gudong.gankio.ui.adapter.ViewListAdapter; 35 | import com.gudong.gankio.util.DateUtil; 36 | 37 | import java.util.List; 38 | 39 | import butterknife.Bind; 40 | 41 | 42 | /** 43 | * show all meizis on this activity ,enjoy it 44 | * Created by GuDong on 9/27/15. 45 | * Contact with gudong.name@gmail.com 46 | */ 47 | public class ViewListActivity extends BaseSwipeRefreshActivity implements ViewListAdapter.IClickItem,IViewListView { 48 | 49 | @Bind(R.id.rcv_index_content) 50 | RecyclerView mRcvIndexContent; 51 | 52 | private ViewListAdapter mAdapter; 53 | private boolean mHasMoreData = true; 54 | 55 | @Override 56 | protected int getLayout() { 57 | return R.layout.activity_view_list; 58 | } 59 | 60 | @Override 61 | protected void onCreate(Bundle savedInstanceState) { 62 | super.onCreate(savedInstanceState); 63 | setTitle(getString(R.string.title_activity_view_list),true); 64 | initRecycleView(); 65 | } 66 | 67 | @Override 68 | protected void initPresenter() { 69 | mPresenter = new ViewListPresenter(this,this); 70 | } 71 | 72 | private void initRecycleView(){ 73 | final StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL); 74 | mRcvIndexContent.setLayoutManager(layoutManager); 75 | mAdapter = new ViewListAdapter(this); 76 | mAdapter.setIClickItem(this); 77 | mRcvIndexContent.setAdapter(mAdapter); 78 | 79 | mRcvIndexContent.addOnScrollListener(new RecyclerView.OnScrollListener() { 80 | @Override 81 | public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 82 | super.onScrolled(recyclerView, dx, dy); 83 | boolean isBottom = 84 | layoutManager.findLastCompletelyVisibleItemPositions(new int[2])[1] 85 | >= mAdapter.getItemCount() - 4; 86 | if (!mSwipeRefreshLayout.isRefreshing() && isBottom && mHasMoreData) { 87 | showRefresh(); 88 | mPresenter.getDataMore(); 89 | } 90 | } 91 | }); 92 | } 93 | 94 | @Override 95 | protected void onPostCreate(Bundle savedInstanceState) { 96 | super.onPostCreate(savedInstanceState); 97 | mPresenter.refillGirls(); 98 | } 99 | 100 | @Override @CheckResult 101 | protected boolean prepareRefresh() { 102 | if(mPresenter.shouldRefillGirls()){ 103 | mPresenter.resetCurrentPage(); 104 | if(!isRefreshing()){ 105 | showRefresh(); 106 | } 107 | return true; 108 | }else{ 109 | return false; 110 | } 111 | } 112 | 113 | @Override 114 | protected void onRefreshStarted() { 115 | mPresenter.refillGirls(); 116 | } 117 | 118 | @Override 119 | public void onClickPhoto(int position, View viewImage,View viewText) { 120 | Girl clickGirl = mAdapter.getGirl(position); 121 | if(clickGirl!=null){ 122 | Gank gank = new Gank(); 123 | gank.type = clickGirl.type; 124 | gank.url = clickGirl.url; 125 | gank.publishedAt = clickGirl.publishedAt; 126 | GirlFaceActivity.gotoWatchGirlDetail(this, gank.url, DateUtil.toDate(gank.publishedAt), viewImage, viewText); 127 | } 128 | } 129 | 130 | @Override 131 | public void appendMoreDataToView(List data) { 132 | mAdapter.update(data); 133 | } 134 | 135 | @Override 136 | public void fillData(List data) { 137 | mAdapter.updateWithClear(data); 138 | } 139 | 140 | @Override 141 | public void showEmptyView() { 142 | Snackbar.make(mRcvIndexContent, R.string.empty_data_of_girls,Snackbar.LENGTH_SHORT).show(); 143 | } 144 | 145 | @Override 146 | public void showErrorView(Throwable throwable){ 147 | throwable.printStackTrace(); 148 | 149 | final Snackbar errorSnack = Snackbar.make(mRcvIndexContent, R.string.error_index_load,Snackbar.LENGTH_INDEFINITE); 150 | errorSnack.getView().setOnClickListener(new View.OnClickListener() { 151 | @Override 152 | public void onClick(View v) { 153 | errorSnack.dismiss(); 154 | onRefreshStarted(); 155 | } 156 | }); 157 | errorSnack.show(); 158 | } 159 | 160 | @Override 161 | public void hasNoMoreData() { 162 | mHasMoreData = false; 163 | Snackbar.make(mRcvIndexContent, R.string.no_more_girls,Snackbar.LENGTH_SHORT) 164 | .setAction(R.string.action_to_top, new View.OnClickListener() { 165 | @Override 166 | public void onClick(View v) { 167 | (mRcvIndexContent.getLayoutManager()).smoothScrollToPosition(mRcvIndexContent,null,0); 168 | } 169 | }) 170 | .show(); 171 | } 172 | 173 | } 174 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/ui/activity/WebActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.ui.activity; 21 | 22 | import android.content.Intent; 23 | import android.net.Uri; 24 | import android.os.Bundle; 25 | import android.support.design.widget.Snackbar; 26 | import android.text.TextUtils; 27 | import android.view.KeyEvent; 28 | import android.view.MenuItem; 29 | import android.webkit.WebView; 30 | import android.widget.Toast; 31 | 32 | import com.gudong.gankio.R; 33 | import com.gudong.gankio.presenter.WebPresenter; 34 | import com.gudong.gankio.ui.view.IWebView; 35 | import com.gudong.gankio.util.AndroidUtils; 36 | 37 | import butterknife.Bind; 38 | import butterknife.ButterKnife; 39 | 40 | public class WebActivity extends BaseSwipeRefreshActivity implements IWebView{ 41 | private static final String EXTRA_URL = "URL"; 42 | private static final String EXTRA_TITLE = "TITLE"; 43 | 44 | @Bind(R.id.wb_content) 45 | WebView mWbContent; 46 | 47 | public static void gotoWebActivity(BaseActivity context,String url,String title){ 48 | Intent intent = new Intent(context,WebActivity.class); 49 | intent.putExtra(EXTRA_URL,url); 50 | intent.putExtra(EXTRA_TITLE, title); 51 | context.startActivity(intent); 52 | } 53 | 54 | @Override 55 | protected void onCreate(Bundle savedInstanceState) { 56 | super.onCreate(savedInstanceState); 57 | 58 | String url = getIntent().getStringExtra(EXTRA_URL); 59 | String title = getIntent().getStringExtra(EXTRA_TITLE); 60 | 61 | if(!TextUtils.isEmpty(title)){ 62 | setTitle(title,true); 63 | } 64 | mPresenter.setUpWebView(mWbContent); 65 | mPresenter.loadUrl(mWbContent,url); 66 | } 67 | 68 | @Override 69 | protected int getLayout() { 70 | return R.layout.activity_web; 71 | } 72 | 73 | @Override 74 | protected int getMenuRes() { 75 | return R.menu.menu_web; 76 | } 77 | 78 | @Override 79 | protected void onRefreshStarted() { 80 | refresh(); 81 | } 82 | 83 | @Override 84 | protected void initPresenter() { 85 | mPresenter = new WebPresenter(this,this); 86 | } 87 | 88 | private void refresh(){ 89 | mWbContent.reload(); 90 | } 91 | 92 | @Override 93 | public boolean onOptionsItemSelected(MenuItem item) { 94 | int id = item.getItemId(); 95 | switch (id) { 96 | case R.id.action_copy_url: 97 | String copyDone = getString(R.string.toast_copy_done); 98 | AndroidUtils.copyToClipBoard(this, mWbContent.getUrl(), copyDone); 99 | return true; 100 | case R.id.action_share_url: 101 | AndroidUtils.shareText(this, mWbContent.getUrl()); 102 | return true; 103 | case R.id.action_open_url: 104 | Intent intent = new Intent(); 105 | intent.setAction(Intent.ACTION_VIEW); 106 | Uri uri = Uri.parse(mWbContent.getUrl()); 107 | intent.setData(uri); 108 | if (intent.resolveActivity(getPackageManager()) != null) { 109 | startActivity(intent); 110 | } else { 111 | Toast.makeText(WebActivity.this, R.string.toast_open_fail, Toast.LENGTH_SHORT).show(); 112 | } 113 | return true; 114 | } 115 | return super.onOptionsItemSelected(item); 116 | } 117 | 118 | @Override 119 | public void showEmptyView() { 120 | 121 | } 122 | 123 | @Override 124 | public void showErrorView(Throwable throwable) { 125 | throwable.printStackTrace(); 126 | } 127 | 128 | @Override 129 | protected void onResume() { 130 | super.onResume(); 131 | if (mWbContent != null) mWbContent.onResume(); 132 | } 133 | 134 | @Override 135 | protected void onDestroy() { 136 | super.onDestroy(); 137 | if (mWbContent != null) mWbContent.destroy(); 138 | ButterKnife.unbind(this); 139 | } 140 | 141 | @Override 142 | protected void onPause() { 143 | if (mWbContent != null) mWbContent.onPause(); 144 | super.onPause(); 145 | } 146 | 147 | @Override 148 | public void showLoadErrorMessage(String message) { 149 | Snackbar.make(mWbContent,message,Snackbar.LENGTH_SHORT).show(); 150 | } 151 | 152 | @Override 153 | public boolean onKeyDown(int keyCode, KeyEvent event) { 154 | if ((keyCode == KeyEvent.KEYCODE_BACK) && mWbContent.canGoBack()) { 155 | mWbContent.goBack(); 156 | return true; 157 | } 158 | return super.onKeyDown(keyCode, event); 159 | } 160 | 161 | } 162 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/ui/adapter/ViewListAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.ui.adapter; 21 | 22 | import android.content.Context; 23 | import android.graphics.ColorFilter; 24 | import android.graphics.ColorMatrix; 25 | import android.graphics.ColorMatrixColorFilter; 26 | import android.support.v7.widget.RecyclerView; 27 | import android.view.LayoutInflater; 28 | import android.view.View; 29 | import android.view.ViewGroup; 30 | import android.widget.TextView; 31 | 32 | import com.bumptech.glide.Glide; 33 | import com.bumptech.glide.load.engine.DiskCacheStrategy; 34 | import com.bumptech.glide.request.target.SizeReadyCallback; 35 | import com.gudong.gankio.R; 36 | import com.gudong.gankio.data.entity.Girl; 37 | import com.gudong.gankio.ui.widget.RatioImageView; 38 | import com.gudong.gankio.util.DateUtil; 39 | 40 | import java.util.ArrayList; 41 | import java.util.List; 42 | 43 | import butterknife.Bind; 44 | import butterknife.ButterKnife; 45 | 46 | /** 47 | * 主页数据显示Adapter 48 | * Created by GuDong on 9/28/15. 49 | * Contact with gudong.name@gmail.com 50 | */ 51 | public class ViewListAdapter extends RecyclerView.Adapter { 52 | private List mListData; 53 | private Context mContext; 54 | private IClickItem mIClickItem; 55 | //blur meizi 56 | private static ColorFilter mColorFilter; 57 | public ViewListAdapter(Context context) { 58 | mContext = context; 59 | mListData = new ArrayList<>(); 60 | 61 | float[]array = new float[]{ 62 | 1,0,0,0,-70, 63 | 0,1,0,0,-70, 64 | 0,0,1,0,-70, 65 | 0,0,0,1,0, 66 | }; 67 | mColorFilter = new ColorMatrixColorFilter(new ColorMatrix(array)); 68 | } 69 | 70 | public void setIClickItem(IClickItem IClickItem) { 71 | mIClickItem = IClickItem; 72 | } 73 | 74 | /** 75 | * before add data , it will remove history data 76 | * @param data 77 | */ 78 | public void updateWithClear(List data){ 79 | mListData.clear(); 80 | mListData.addAll(data); 81 | notifyDataSetChanged(); 82 | } 83 | 84 | /** 85 | * add data append to history data 86 | * @param data new data 87 | */ 88 | public void update(List data){ 89 | mListData.addAll(data); 90 | notifyDataSetChanged(); 91 | } 92 | 93 | public Girl getGirl(int position){ 94 | return mListData.get(position); 95 | } 96 | 97 | @Override 98 | public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 99 | View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.index_item, null); 100 | ViewHolder holder = new ViewHolder(view); 101 | return holder; 102 | } 103 | 104 | @Override 105 | public void onBindViewHolder(final ViewHolder holder,final int position) { 106 | Girl entity = mListData.get(position); 107 | 108 | Glide.with(mContext) 109 | .load(entity.url) 110 | .centerCrop() 111 | .diskCacheStrategy(DiskCacheStrategy.ALL) 112 | .dontAnimate() 113 | .into(holder.mIvIndexPhoto) 114 | .getSize(new SizeReadyCallback() { 115 | @Override 116 | public void onSizeReady(int width, int height) { 117 | //holder.mIvIndexPhoto.setColorFilter(mColorFilter); 118 | } 119 | }); 120 | holder.mTvTime.setText(DateUtil.toDate(entity.publishedAt)); 121 | if(mIClickItem!=null){ 122 | holder.mIvIndexPhoto.setOnClickListener(new View.OnClickListener() { 123 | @Override 124 | public void onClick(View v) { 125 | mIClickItem.onClickPhoto(position, holder.mIvIndexPhoto,holder.mTvTime); 126 | } 127 | }); 128 | } 129 | } 130 | 131 | public interface IClickItem{ 132 | void onClickPhoto(int position,View view,View textView); 133 | } 134 | 135 | @Override 136 | public int getItemCount() { 137 | return mListData.size(); 138 | } 139 | 140 | /** 141 | * This class contains all butterknife-injected Views & Layouts from layout file 'index_listitem.xml' 142 | * for easy to all layout elements. 143 | * 144 | * @author ButterKnifeZelezny, plugin for Android Studio by Avast Developers (http://github.com/avast) 145 | */ 146 | public static class ViewHolder extends RecyclerView.ViewHolder{ 147 | @Bind(R.id.iv_index_photo) 148 | RatioImageView mIvIndexPhoto; 149 | @Bind(R.id.tv_time) 150 | TextView mTvTime; 151 | 152 | ViewHolder(View view) { 153 | super(view); 154 | ButterKnife.bind(this, view); 155 | 156 | mIvIndexPhoto.setOriginalSize(50,50); 157 | } 158 | } 159 | 160 | } 161 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/ui/fragment/CustomWebViewDialog.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.ui.fragment; 21 | 22 | import android.app.Dialog; 23 | import android.content.Context; 24 | import android.os.Bundle; 25 | import android.support.annotation.NonNull; 26 | import android.support.v4.app.DialogFragment; 27 | import android.view.InflateException; 28 | import android.view.LayoutInflater; 29 | import android.view.View; 30 | import android.webkit.JavascriptInterface; 31 | import android.webkit.WebView; 32 | import android.widget.Toast; 33 | 34 | import com.gudong.gankio.R; 35 | import com.gudong.gankio.presenter.CustomDialogPresenter; 36 | import com.gudong.gankio.ui.view.ICustomDialog; 37 | import com.gudong.gankio.util.DialogUtil; 38 | 39 | /** 40 | * CustomWebViewDialog 41 | * @author mao 42 | */ 43 | public class CustomWebViewDialog extends DialogFragment implements ICustomDialog { 44 | private CustomDialogPresenter mPresenter; 45 | private WebView mWebView; 46 | @Override 47 | public void onCreate(Bundle savedInstanceState) { 48 | super.onCreate(savedInstanceState); 49 | mPresenter = new CustomDialogPresenter(getActivity(),this); 50 | } 51 | 52 | @NonNull 53 | @Override 54 | public Dialog onCreateDialog(Bundle savedInstanceState) { 55 | final View customView; 56 | try { 57 | customView = LayoutInflater.from(getActivity()).inflate(R.layout.dialog_webview, null); 58 | mWebView = (WebView) customView.findViewById(R.id.webview); 59 | mWebView.addJavascriptInterface(new WebAppInterface(customView.getContext()),"Android"); 60 | } catch (InflateException e) { 61 | throw new IllegalStateException("This device does not support Web Views."); 62 | } 63 | return mPresenter.makeOkDialog(this,customView); 64 | } 65 | 66 | public class WebAppInterface { 67 | Context mContext; 68 | 69 | /** Instantiate the interface and set the context */ 70 | WebAppInterface(Context c) { 71 | mContext = c; 72 | } 73 | 74 | /** Show a toast from the web page */ 75 | @JavascriptInterface 76 | public void showToast(String toast) { 77 | Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show(); 78 | } 79 | 80 | /** Show a dialog about app **/ 81 | @JavascriptInterface 82 | public void showAbout(){ 83 | DialogUtil.showCustomDialog(getActivity(), getFragmentManager(), getString(R.string.action_about), "about_gank_app.html", "app"); 84 | } 85 | 86 | /** Show a dialog about gank site **/ 87 | @JavascriptInterface 88 | public void showAboutGank(){ 89 | DialogUtil.showCustomDialog(getActivity(), getFragmentManager(), getString(R.string.action_about_gank), "about_gank_site.html", "site"); 90 | } 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/ui/view/IBaseView.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.ui.view; 21 | 22 | /** 23 | * 所有项目View的基类 恩,目前是这么想的 24 | * Created by GuDong on 10/29/15 14:23. 25 | * Contact with gudong.name@gmail.com. 26 | */ 27 | public interface IBaseView { 28 | 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/ui/view/ICustomDialog.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.ui.view; 21 | 22 | /** 23 | * Created by GuDong on 11/6/15 15:59. 24 | * Contact with gudong.name@gmail.com. 25 | */ 26 | public interface ICustomDialog extends IBaseView { 27 | 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/ui/view/IGirlFaceView.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.ui.view; 21 | 22 | /** 23 | * Created by GuDong on 11/2/15 18:21. 24 | * Contact with gudong.name@gmail.com. 25 | */ 26 | public interface IGirlFaceView extends IBaseView { 27 | 28 | void saveSuccess(String message); 29 | void showFailInfo(String error); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/ui/view/IMainView.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.ui.view; 21 | 22 | import com.gudong.gankio.data.entity.Soul; 23 | 24 | import java.util.List; 25 | 26 | /** 27 | * Created by GuDong on 11/2/15 14:39. 28 | * Contact with gudong.name@gmail.com. 29 | */ 30 | public interface IMainView extends ISwipeRefreshView { 31 | /** 32 | * load data successfully 33 | * @param data 34 | */ 35 | void fillData(List data); 36 | 37 | /** 38 | * append data to history list(load more) 39 | * @param data 40 | */ 41 | void appendMoreDataToView(List data); 42 | 43 | /** 44 | * no more data for show and this condition is hard to appear,it need you scroll main view long time 45 | * I think it has no body do it like this ,even though,I deal this condition also, In case someone does it. 46 | */ 47 | void hasNoMoreData(); 48 | 49 | /** 50 | * show change log info in a dialog 51 | * @param assetFileName the name of local html file like "changelog.html" 52 | */ 53 | void showChangeLogInfo(String assetFileName); 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/ui/view/ISwipeRefreshView.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.ui.view; 21 | 22 | /** 23 | * if you implement ISwipeRefreshView , you view should be a list view 24 | * Created by GuDong on 10/29/15 18:08. 25 | * Contact with gudong.name@gmail.com. 26 | */ 27 | public interface ISwipeRefreshView extends IBaseView { 28 | 29 | 30 | void getDataFinish(); 31 | 32 | void showEmptyView(); 33 | 34 | void showErrorView(Throwable throwable); 35 | 36 | void showRefresh(); 37 | 38 | void hideRefresh(); 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/ui/view/IViewListView.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.ui.view; 21 | 22 | import com.gudong.gankio.data.entity.Soul; 23 | 24 | import java.util.List; 25 | 26 | /** 27 | * index view 28 | * Created by GuDong on 10/29/15 14:10. 29 | * Contact with gudong.name@gmail.com. 30 | */ 31 | public interface IViewListView extends ISwipeRefreshView{ 32 | /** 33 | * load data successfully 34 | * @param data 35 | */ 36 | void fillData(List data); 37 | 38 | /** 39 | * append data to history list(load more) 40 | * @param data 41 | */ 42 | void appendMoreDataToView(List data); 43 | 44 | /** 45 | * no more data 46 | */ 47 | void hasNoMoreData(); 48 | 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/ui/view/IWebView.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.ui.view; 21 | 22 | /** 23 | * Created by GuDong on 11/2/15 17:04. 24 | * Contact with gudong.name@gmail.com. 25 | */ 26 | public interface IWebView extends ISwipeRefreshView { 27 | void showLoadErrorMessage(String message); 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/ui/widget/RatioImageView.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.ui.widget; 21 | 22 | import android.content.Context; 23 | import android.util.AttributeSet; 24 | import android.widget.ImageView; 25 | 26 | /** 27 | * Created by GuDong on 10/29/15 21:05. 28 | * Contact with gudong.name@gmail.com. 29 | */ 30 | public class RatioImageView extends ImageView { 31 | private int originalWidth; 32 | private int originalHeight; 33 | 34 | 35 | private int measureWidth; 36 | private int measureHeight; 37 | 38 | public RatioImageView(Context context) { 39 | this(context, null); 40 | } 41 | 42 | public RatioImageView(Context context, AttributeSet attrs) { 43 | this(context, attrs, 0); 44 | } 45 | 46 | public RatioImageView(Context context, AttributeSet attrs, int defStyleAttr) { 47 | super(context, attrs, defStyleAttr); 48 | initView(); 49 | } 50 | 51 | private void initView() { 52 | } 53 | 54 | public void setOriginalSize(int originalWidth, int originalHeight) { 55 | this.originalWidth = originalWidth; 56 | this.originalHeight = originalHeight; 57 | } 58 | 59 | 60 | @Override 61 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 62 | if(originalHeight>0 && originalWidth>0){ 63 | float radio = (float)originalWidth/(float)originalHeight; 64 | 65 | measureWidth = MeasureSpec.getSize(widthMeasureSpec); 66 | measureHeight = MeasureSpec.getSize(heightMeasureSpec); 67 | 68 | if(measureWidth>0){ 69 | measureHeight = (int) ((float)measureWidth/radio); 70 | } 71 | setMeasuredDimension(measureWidth,measureHeight); 72 | }else{ 73 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/util/AndroidUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.util; 21 | 22 | import android.content.ClipData; 23 | import android.content.ClipboardManager; 24 | import android.content.Context; 25 | import android.content.Intent; 26 | import android.content.SharedPreferences; 27 | import android.content.pm.PackageInfo; 28 | import android.content.res.Resources; 29 | import android.os.Build; 30 | import android.preference.PreferenceManager; 31 | import android.support.v7.widget.Toolbar; 32 | import android.util.TypedValue; 33 | import android.widget.TextView; 34 | 35 | import com.gudong.gankio.R; 36 | 37 | import java.lang.reflect.Field; 38 | 39 | /** 40 | * Created by GuDong on 10/14/15 22:22. 41 | * Contact with gudong.name@gmail.com. 42 | */ 43 | public class AndroidUtils { 44 | public static void copyToClipBoard(Context context, String text, String success) { 45 | ClipData clipData = ClipData.newPlainText("meizhi_copy", text); 46 | ClipboardManager manager = 47 | (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); 48 | manager.setPrimaryClip(clipData); 49 | ToastUtils.showShort(success); 50 | } 51 | 52 | /** 53 | * get accent color 54 | * @param context 55 | * @return 56 | */ 57 | public static int getAccentColor(Context context){ 58 | TypedValue typedValue = new TypedValue(); 59 | Resources.Theme theme = context.getTheme(); 60 | theme.resolveAttribute(R.attr.colorPrimary, typedValue, true); 61 | return typedValue.data; 62 | } 63 | 64 | public static boolean isAndroidL(){ 65 | return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; 66 | } 67 | 68 | /** 69 | * base on Toolbar get the TitleView by reflect way 70 | * @param obj Toolbar 71 | * @return the title text view in Toolbar 72 | */ 73 | public static TextView getTitleViewInToolbar(Toolbar obj){ 74 | TextView textView = null; 75 | try { 76 | Field title = obj.getClass().getDeclaredField("mTitleTextView"); 77 | title.setAccessible(true); 78 | textView = (TextView) title.get(obj); 79 | } catch (NoSuchFieldException e) { 80 | e.printStackTrace(); 81 | } catch (IllegalAccessException e) { 82 | e.printStackTrace(); 83 | } 84 | return textView; 85 | } 86 | 87 | /** 88 | * get app version info 89 | * @param context context 90 | * @return app version info if occur exception return unknow 91 | */ 92 | public static String getAppVersion(Context context){ 93 | try { 94 | PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0); 95 | return info.versionName; 96 | } catch (Exception e) { 97 | e.printStackTrace(); 98 | return context.getString(R.string.unknow); 99 | } 100 | } 101 | 102 | public static void setCurrentVersion(Context context,String version){ 103 | putStringPreference(context,"current_version",version); 104 | } 105 | 106 | public static String getLocalVersion(Context context){ 107 | return getStringPreference(context, "current_version", ""); 108 | } 109 | 110 | public static String getStringPreference(Context context,String key,String def){ 111 | SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); 112 | return sp.getString(key, def); 113 | } 114 | 115 | public static void putStringPreference(Context context,String key,String value){ 116 | SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); 117 | sp.edit().putString(key, value).apply(); 118 | } 119 | 120 | public static void shareText(Context context, String text){ 121 | Intent sendIntent = new Intent(); 122 | sendIntent.setAction(Intent.ACTION_SEND); 123 | sendIntent.putExtra(Intent.EXTRA_TEXT,text); 124 | sendIntent.setType("text/plain"); 125 | context.startActivity(Intent.createChooser(sendIntent, "发送")); 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/util/DateUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.util; 21 | 22 | import java.text.DateFormat; 23 | import java.text.SimpleDateFormat; 24 | import java.util.Calendar; 25 | import java.util.Date; 26 | 27 | /** 28 | * Created by GuDong on 10/9/15 22:06. 29 | * Contact with gudong.name@gmail.com. 30 | */ 31 | public class DateUtil { 32 | 33 | public static String toDate(Date date) { 34 | DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd"); 35 | return dateFormat.format(date); 36 | } 37 | 38 | public static String toDate(Date date, int add) { 39 | Calendar calendar = Calendar.getInstance(); 40 | calendar.setTime(date); 41 | calendar.add(Calendar.DATE, add); 42 | return toDate(calendar.getTime()); 43 | } 44 | 45 | public static Date getLastdayDate(Date date) { 46 | Calendar calendar = Calendar.getInstance(); 47 | calendar.setTime(date); 48 | calendar.add(Calendar.DATE, -1); 49 | return calendar.getTime(); 50 | } 51 | 52 | public static Date getNextdayDate(Date date) { 53 | Calendar calendar = Calendar.getInstance(); 54 | calendar.setTime(date); 55 | calendar.add(Calendar.DATE, 1); 56 | return calendar.getTime(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/util/DialogUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.util; 21 | 22 | import android.content.Context; 23 | import android.support.v4.app.FragmentManager; 24 | import android.support.v7.app.AlertDialog; 25 | 26 | import com.gudong.gankio.R; 27 | import com.gudong.gankio.presenter.CustomDialogPresenter; 28 | 29 | 30 | /** 31 | * tool for dialog 32 | * Created by mao on 7/19/15. 33 | */ 34 | public class DialogUtil { 35 | /** 36 | * show a dialog which it contain one point message only 37 | * @param context context 38 | */ 39 | public static void showSinglePointDialog(Context context, String message){ 40 | new AlertDialog.Builder(context) 41 | .setTitle(R.string.title_point) 42 | .setMessage(message) 43 | .setPositiveButton(R.string.dialog_confirm, null) 44 | .show(); 45 | } 46 | 47 | 48 | /** 49 | * show a custom dialog use a local html file 50 | * @param context 51 | * @param fragmentManager 52 | * @param dialogTitle title 53 | * @param htmlFileName file name 54 | * @param tag 55 | */ 56 | public static void showCustomDialog(Context context, FragmentManager fragmentManager, String dialogTitle, String htmlFileName, String tag) { 57 | int accentColor = AndroidUtils.getAccentColor(context); 58 | CustomDialogPresenter.create(dialogTitle, htmlFileName, accentColor) 59 | .show(fragmentManager, tag); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/util/StringStyleUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.util; 21 | 22 | import android.content.Context; 23 | import android.text.SpannableString; 24 | import android.text.SpannableStringBuilder; 25 | import android.text.style.TextAppearanceSpan; 26 | 27 | import com.gudong.gankio.R; 28 | import com.gudong.gankio.data.entity.Gank; 29 | 30 | public class StringStyleUtils { 31 | 32 | public static SpannableString format(Context context, String text, int style) { 33 | SpannableString spannableString = new SpannableString(text); 34 | spannableString.setSpan(new TextAppearanceSpan(context, style), 0, text.length(), 0); 35 | return spannableString; 36 | } 37 | 38 | public static CharSequence getGankInfoSequence(Context context,Gank mGank) { 39 | SpannableStringBuilder builder = new SpannableStringBuilder(mGank.desc).append( 40 | StringStyleUtils.format(context, " (via. " + mGank.who + ")", R.style.ViaTextAppearance)); 41 | return builder.subSequence(0, builder.length()); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/util/TaskUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.util; 21 | 22 | import android.os.AsyncTask; 23 | import android.os.Build; 24 | 25 | /** 26 | * Created by drak11t on 8/16/14. 27 | */ 28 | public class TaskUtils { 29 | 30 | @SafeVarargs public static void executeAsyncTask( 31 | AsyncTask task, Params... params) { 32 | if (Build.VERSION.SDK_INT >= 11) { 33 | task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params); 34 | } 35 | else { 36 | task.execute(params); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/com/gudong/gankio/util/ToastUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2015 Drakeet 4 | * Copyright (C) 2015 GuDong 5 | * 6 | * Meizhi is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Meizhi is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Meizhi. If not, see . 18 | */ 19 | 20 | package com.gudong.gankio.util; 21 | 22 | import android.content.Context; 23 | import android.widget.Toast; 24 | 25 | import com.gudong.gankio.GankApp; 26 | 27 | /** 28 | * Created by drakeet on 9/27/14. 29 | */ 30 | public class ToastUtils { 31 | 32 | Context mContext; 33 | 34 | private ToastUtils() { 35 | } 36 | 37 | private static void show(Context context, int resId, int duration) { 38 | Toast.makeText(context, resId, duration).show(); 39 | } 40 | 41 | private static void show(Context context, String message, int duration) { 42 | Toast.makeText(context, message, duration).show(); 43 | } 44 | 45 | public static void showShort(int resId) { 46 | Toast.makeText(GankApp.sContext, resId, Toast.LENGTH_SHORT).show(); 47 | } 48 | 49 | public static void showShort(String message) { 50 | Toast.makeText(GankApp.sContext, message, Toast.LENGTH_SHORT).show(); 51 | } 52 | 53 | public static void showLong(int resId) { 54 | Toast.makeText(GankApp.sContext, resId, Toast.LENGTH_LONG).show(); 55 | } 56 | 57 | public static void showLong(String message) { 58 | Toast.makeText(GankApp.sContext, message, Toast.LENGTH_LONG).show(); 59 | } 60 | 61 | public static void showLongLong(String message) { 62 | showLong(message); 63 | showLong(message); 64 | } 65 | 66 | public static void showLongLong(int resId) { 67 | showLong(resId); 68 | showLong(resId); 69 | } 70 | 71 | public static void showLongLongLong(int resId) { 72 | showLong(resId); 73 | showLong(resId); 74 | showShort(resId); 75 | } 76 | 77 | public static void showLongLongLong(String message) { 78 | showLong(message); 79 | showLong(message); 80 | showShort(message); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/umeng_update_btn_check_off_focused_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maoruibin/GankDaily/bbdf5a79c336968ed7308d562aeff4ede8dd2736/app/src/main/res/drawable-hdpi/umeng_update_btn_check_off_focused_holo_light.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/umeng_update_btn_check_off_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maoruibin/GankDaily/bbdf5a79c336968ed7308d562aeff4ede8dd2736/app/src/main/res/drawable-hdpi/umeng_update_btn_check_off_holo_light.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/umeng_update_btn_check_off_pressed_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maoruibin/GankDaily/bbdf5a79c336968ed7308d562aeff4ede8dd2736/app/src/main/res/drawable-hdpi/umeng_update_btn_check_off_pressed_holo_light.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/umeng_update_btn_check_on_focused_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maoruibin/GankDaily/bbdf5a79c336968ed7308d562aeff4ede8dd2736/app/src/main/res/drawable-hdpi/umeng_update_btn_check_on_focused_holo_light.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/umeng_update_btn_check_on_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maoruibin/GankDaily/bbdf5a79c336968ed7308d562aeff4ede8dd2736/app/src/main/res/drawable-hdpi/umeng_update_btn_check_on_holo_light.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/umeng_update_btn_check_on_pressed_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maoruibin/GankDaily/bbdf5a79c336968ed7308d562aeff4ede8dd2736/app/src/main/res/drawable-hdpi/umeng_update_btn_check_on_pressed_holo_light.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/umeng_update_close_bg_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maoruibin/GankDaily/bbdf5a79c336968ed7308d562aeff4ede8dd2736/app/src/main/res/drawable-hdpi/umeng_update_close_bg_normal.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/umeng_update_close_bg_tap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maoruibin/GankDaily/bbdf5a79c336968ed7308d562aeff4ede8dd2736/app/src/main/res/drawable-hdpi/umeng_update_close_bg_tap.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/bg_card.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maoruibin/GankDaily/bbdf5a79c336968ed7308d562aeff4ede8dd2736/app/src/main/res/drawable-xhdpi/bg_card.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/splash_5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maoruibin/GankDaily/bbdf5a79c336968ed7308d562aeff4ede8dd2736/app/src/main/res/drawable-xhdpi/splash_5.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_brower.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_bug.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_describe.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_email.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_github.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_issues.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_issues_white.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_profile.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_star_filled.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_material_button_press.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tb_munion_icon.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tb_munion_item_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_common_gradient_green.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_common_gradient_orange.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_common_gradient_red.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_update_button_cancel_bg_focused.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_update_button_cancel_bg_normal.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_update_button_cancel_bg_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 8 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_update_button_cancel_bg_tap.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_update_button_check_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 9 | 10 | 13 | 16 | 17 | 20 | 23 | 24 | 27 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_update_button_close_bg_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 8 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_update_button_ok_bg_focused.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_update_button_ok_bg_normal.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_update_button_ok_bg_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 8 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_update_button_ok_bg_tap.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_update_dialog_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_update_title_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_update_wifi_disable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maoruibin/GankDaily/bbdf5a79c336968ed7308d562aeff4ede8dd2736/app/src/main/res/drawable/umeng_update_wifi_disable.png -------------------------------------------------------------------------------- /app/src/main/res/layout-v9/umeng_common_download_notification.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 13 | 14 | 19 | 20 | 27 | 28 | 29 | 35 | 36 | 46 | 47 |