├── .gitignore ├── .idea ├── caches │ └── build_file_checksums.ser ├── codeStyles │ └── Project.xml ├── gradle.xml ├── inspectionProfiles │ └── Project_Default.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── libs │ └── picasso-2.5.2.jar ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── me │ │ └── wavever │ │ └── ganklock │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── assets │ │ └── migrations │ │ │ └── 4.sql │ ├── ic_launcher-web.png │ ├── icon-web.png │ ├── java │ │ └── me │ │ │ └── wavever │ │ │ └── ganklock │ │ │ ├── MyApplication.java │ │ │ ├── config │ │ │ ├── Config.java │ │ │ └── GankApi.java │ │ │ ├── db │ │ │ └── DBHelper.java │ │ │ ├── event │ │ │ ├── ClickEvent.java │ │ │ ├── RxBus.java │ │ │ ├── SettingEvent.java │ │ │ └── StatusEvent.java │ │ │ ├── model │ │ │ ├── bean │ │ │ │ ├── Gank.java │ │ │ │ ├── GankContent.java │ │ │ │ ├── GankDaily.java │ │ │ │ ├── GankDailyContent.java │ │ │ │ └── Like.java │ │ │ ├── data │ │ │ │ ├── ContentGankData.java │ │ │ │ └── DailyGankData.java │ │ │ └── http │ │ │ │ ├── GankService.java │ │ │ │ └── RetrofitUtil.java │ │ │ ├── presenter │ │ │ ├── BasePresenter.java │ │ │ ├── DailyGankPresenter.java │ │ │ ├── GankContentPresenter.java │ │ │ ├── IPresenter.java │ │ │ ├── LikePresenter.java │ │ │ ├── LockPresenter.java │ │ │ ├── MeiZhiPresenter.java │ │ │ ├── MorePresenter.java │ │ │ └── WebViewPresenter.java │ │ │ ├── receiver │ │ │ └── GankLockReceiver.java │ │ │ ├── service │ │ │ └── LockService.java │ │ │ ├── ui │ │ │ ├── activity │ │ │ │ ├── AboutActivity.java │ │ │ │ ├── BaseActivity.java │ │ │ │ ├── BaseMvpActivity.java │ │ │ │ ├── GankContentActivity.java │ │ │ │ ├── LicenseActivity.java │ │ │ │ ├── LockActivity.java │ │ │ │ ├── MainActivity.java │ │ │ │ ├── PhotoActivity.java │ │ │ │ ├── SettingActivity.java │ │ │ │ └── WebViewActivity.java │ │ │ ├── adapter │ │ │ │ ├── BaseRVAdapter.java │ │ │ │ ├── DailyListAdapter.java │ │ │ │ ├── GankListAdapter.java │ │ │ │ ├── LikeRecyclerViewAdapter.java │ │ │ │ └── MeizhiRecyclerViewAdapter.java │ │ │ ├── fragment │ │ │ │ ├── BaseFragment.java │ │ │ │ ├── DailyGankFragment.java │ │ │ │ ├── LikeFragment.java │ │ │ │ ├── MeizhiFragment.java │ │ │ │ ├── MoreFragment.java │ │ │ │ └── SettingFragment.java │ │ │ └── widget │ │ │ │ ├── ColorfulCircleView.java │ │ │ │ ├── RatioImageView.java │ │ │ │ ├── SwipeUnLockLayout.java │ │ │ │ ├── UnlockArrow.java │ │ │ │ └── UnlockArrowHolder.java │ │ │ ├── utils │ │ │ ├── DateUtil.java │ │ │ ├── DialogUtil.java │ │ │ ├── LogUtil.java │ │ │ ├── PhotoUtil.java │ │ │ ├── PreferenceUtil.java │ │ │ ├── StringUtil.java │ │ │ ├── SystemUtil.java │ │ │ ├── ToastUtil.java │ │ │ └── UIUtil.java │ │ │ └── view │ │ │ ├── IBaseView.java │ │ │ ├── IDailyGankView.java │ │ │ ├── IGankContentView.java │ │ │ ├── ILikeView.java │ │ │ ├── ILockView.java │ │ │ ├── IMeiZhiView.java │ │ │ ├── IMoreView.java │ │ │ └── IWebView.java │ └── res │ │ ├── color │ │ └── selector_primary_click.xml │ │ ├── drawable-hdpi │ │ └── ic_settings_white_36dp.png │ │ ├── drawable-xhdpi │ │ ├── ic_card_48dp.png │ │ ├── ic_check_white_18dp.png │ │ ├── ic_favorite_grey_500_24dp.png │ │ ├── ic_favorite_red_500_24dp.png │ │ └── ic_share_grey_500_24dp.png │ │ ├── drawable-xxhdpi │ │ ├── empty_icon.png │ │ ├── l_new_tip.png │ │ └── test_image.jpg │ │ ├── drawable-xxxhdpi │ │ ├── ic_cloud_white_24dp.png │ │ ├── ic_format_list_numbered_white_24dp.png │ │ ├── ic_portrait_white_24dp.png │ │ └── ic_star_white_24dp.png │ │ ├── drawable │ │ ├── bg_card_nopic.xml │ │ ├── bg_more_fragment_item.xml │ │ ├── daily_mask.xml │ │ ├── lock_date_mask.xml │ │ ├── more_item_line_divider.xml │ │ ├── selector_pick_item.xml │ │ └── toolbar_shadow_view.xml │ │ ├── layout │ │ ├── activity_about.xml │ │ ├── activity_gank_content.xml │ │ ├── activity_lock.xml │ │ ├── activity_main.xml │ │ ├── activity_photo.xml │ │ ├── activity_setting.xml │ │ ├── activity_web_view.xml │ │ ├── dialog_theme_picker.xml │ │ ├── fragment_daily.xml │ │ ├── fragment_license.xml │ │ ├── fragment_like.xml │ │ ├── fragment_meizhi.xml │ │ ├── fragment_more.xml │ │ ├── item_daily_recycler_view.xml │ │ ├── item_gank_rv_content.xml │ │ ├── item_like_rv.xml │ │ ├── item_meizhi_recycler_view.xml │ │ ├── layout_lock_time.xml │ │ ├── toolbar.xml │ │ └── toolbar_shadow.xml │ │ ├── menu │ │ ├── main_menu.xml │ │ └── navigation.xml │ │ ├── mipmap-hdpi │ │ └── icon.png │ │ ├── mipmap-mdpi │ │ └── icon.png │ │ ├── mipmap-xhdpi │ │ └── icon.png │ │ ├── mipmap-xxhdpi │ │ └── icon.png │ │ ├── mipmap-xxxhdpi │ │ └── icon.png │ │ ├── values-v19 │ │ └── style.xml │ │ ├── values-v21 │ │ └── styles.xml │ │ ├── values-w820dp │ │ └── dimens.xml │ │ ├── values │ │ ├── android_material_design_colours.xml │ │ ├── attrs.xml │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ │ └── xml │ │ └── preferences.xml │ └── test │ └── java │ └── me │ └── wavever │ └── ganklock │ └── ExampleUnitTest.java ├── build.gradle ├── config.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /keystore.properties 5 | .idea 6 | .DS_Store 7 | /build 8 | /buildsystem 9 | /captures 10 | *.jks -------------------------------------------------------------------------------- /.idea/caches/build_file_checksums.ser: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wavever/GankLock/cf8f53cea137c302d069346efb5744ca29633ba3/.idea/caches/build_file_checksums.ser -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15 | 16 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 31 | 32 | 33 | 34 | 35 | 36 | 38 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## GankLock 2 | 3 | Rebuilding.... 4 | 5 | ## License 6 | 7 | /* 8 | * Copyright (C) 2016 wavever 9 | * 10 | * GankLock is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * GankLock is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with GankLock. If not, see . 22 | */ 23 | 24 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | 5 | useLibrary 'org.apache.http.legacy' 6 | 7 | compileSdkVersion rootProject.ext.android.compileSdkVersion 8 | 9 | defaultConfig { 10 | minSdkVersion rootProject.ext.android.minSdkVersion 11 | targetSdkVersion rootProject.ext.android.targetSdkVersion 12 | versionCode rootProject.ext.android.versionCode 13 | versionName rootProject.ext.android.versionName 14 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 15 | vectorDrawables.useSupportLibrary = true 16 | } 17 | 18 | buildTypes { 19 | release { 20 | minifyEnabled false 21 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 22 | } 23 | } 24 | } 25 | 26 | repositories { 27 | mavenCentral() 28 | maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } 29 | } 30 | 31 | dependencies { 32 | implementation fileTree(include: ['*.jar'], dir: 'libs') 33 | implementation libraries.appcompat_v7 34 | implementation libraries.recyclerView 35 | implementation libraries.cardView 36 | implementation libraries.design 37 | implementation libraries.gson 38 | implementation libraries.rxJava 39 | implementation libraries.rxAndroid 40 | implementation libraries.retrofit2 41 | implementation libraries.retrofit2_converter_gson 42 | implementation libraries.retrofit2_adapter_rxjava 43 | implementation libraries.okhttp3 44 | implementation libraries.okhttp3_logging_interceptor 45 | implementation libraries.materialPreference 46 | implementation libraries.activeAndroid 47 | implementation libraries.photoView 48 | implementation libraries.licence_fragment 49 | implementation libraries.constraint_layout 50 | //noinspection GradleCompatible 51 | testImplementation 'junit:junit:4.12' 52 | //noinspection GradleCompatible 53 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 54 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 55 | } 56 | -------------------------------------------------------------------------------- /app/libs/picasso-2.5.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wavever/GankLock/cf8f53cea137c302d069346efb5744ca29633ba3/app/libs/picasso-2.5.2.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 E:\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 | # ProGuard configurations for Bugtags 19 | -keepattributes LineNumberTable,SourceFile 20 | 21 | -keep class com.bugtags.library.** {*;} 22 | -dontwarn com.bugtags.library.** 23 | -keep class io.bugtags.** {*;} 24 | -dontwarn io.bugtags.** 25 | -dontwarn org.apache.http.** 26 | -dontwarn android.net.http.AndroidHttpClient 27 | 28 | # End Bugtags 29 | -------------------------------------------------------------------------------- /app/src/androidTest/java/me/wavever/ganklock/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 23 | 24 | 25 | 28 | 31 | 34 | 35 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 49 | 52 | 55 | 58 | 62 | 65 | 68 | 69 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /app/src/main/assets/migrations/4.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE Ganks ADD COLUMN _id text; -------------------------------------------------------------------------------- /app/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wavever/GankLock/cf8f53cea137c302d069346efb5744ca29633ba3/app/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /app/src/main/icon-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wavever/GankLock/cf8f53cea137c302d069346efb5744ca29633ba3/app/src/main/icon-web.png -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/MyApplication.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.support.annotation.ColorInt; 6 | import android.support.annotation.ColorRes; 7 | 8 | import com.activeandroid.app.Application; 9 | 10 | import me.wavever.ganklock.config.Config; 11 | import me.wavever.ganklock.service.LockService; 12 | import me.wavever.ganklock.utils.PreferenceUtil; 13 | 14 | /** 15 | * Created by wavever on 2016/3/2. 16 | */ 17 | public class MyApplication extends Application{ 18 | 19 | private static Context context; 20 | 21 | private static PreferenceUtil sp; 22 | 23 | @Override 24 | public void onCreate() { 25 | super.onCreate(); 26 | context = getApplicationContext(); 27 | if (PreferenceUtil.getBoolean(Config.GANK_LOCK_IS_OPEN)) { 28 | context.startService(new Intent(context, LockService.class)); 29 | } 30 | } 31 | 32 | /** 33 | * 获得一个全局的Context对象 34 | */ 35 | public static Context getContext() { 36 | return context; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/config/Config.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.config; 2 | 3 | /** 4 | * Created by wavever on 2016/3/10. 5 | */ 6 | public class Config { 7 | 8 | public static final String IS_FIRST_RUN = "IS_FIRST_RUN"; 9 | 10 | public static final String GANK_LOCK_IS_OPEN = "LOCK_IS_OPEN"; 11 | 12 | public static final String LAST_GET_DATE = "LAST_GET_DATE"; 13 | 14 | public static final String GET_TODAY_DATA = "GET_DATA"; 15 | 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/config/GankApi.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.config; 2 | 3 | /** 4 | * Created by wavever on 2015/12/24. 5 | */ 6 | public class GankApi { 7 | 8 | public static final String BASE_URL = "http://gank.io/api/"; 9 | 10 | /** 11 | * 获取每日数据 12 | * http://gank.io/api/day/2015/08/06 13 | * 注: http://gank.io/api/day/年/月/日 14 | */ 15 | public static final String GET_DAY_DATA = "http://gank.io/api/day/"; 16 | 17 | /** 18 | * 获取某几日干货数据 19 | * http://gank.io/api/history/content/2/1 20 | * 注: 2 代表 2 个数据,1 代表:取第一页数据 21 | */ 22 | public static final String GET_HISTORY_DATA = "http://gank.io/api/history/content/"; 23 | 24 | /* 25 | http://gank.io/api/data/福利/10/1 26 | 分类数据: http://gank.io/api/data/数据类型/请求个数/第几页 27 | 数据类型: 福利 | Android | iOS | 休息视频 | 拓展资源 | 前端 | all 28 | 请求个数: 数字,大于0 29 | 第几页:数字,大于0 30 | */ 31 | public static final String GET_CATEGORY_DATA = "http://gank.io/api/data/"; 32 | 33 | public static final String GET_GIRL_DATA = "http://gank.io/api/data/福利/"; 34 | 35 | /* 36 | 随机数据:http://gank.io/api/random/data/分类/个数 37 | 数据类型:福利 | Android | iOS | 休息视频 | 拓展资源 | 前端 38 | 个数: 数字,大于0 39 | */ 40 | public static final String GET_RANDOM_DATA = "http://gank.io/api/random/data/"; 41 | 42 | 43 | /** 44 | * 搜索API http://gank.io/api/search/query/listview/category/Android/count/10/page/1 45 | * category 后面可接受参数 all | Android | iOS | 休息视频 | 福利 | 拓展资源 | 前端 | 瞎推荐 | App 46 | * count 最大 50 47 | */ 48 | public static final String SEARCH_CATEGORY_DATA = "http://gank.io/api/search/query/listview/category/"; 49 | 50 | /** 51 | * 获取闲读的主分类 52 | */ 53 | public static final String XIANDU_CATERORIES = "http://gank.io/api/xiandu/categories"; 54 | 55 | /** 56 | * 获取闲读的子分类 57 | * category 后面可接受参数为主分类返回的en_name,例如【apps, wow, android,iOS】 58 | */ 59 | public static final String XIANDU_ITEMS = "http://gank.io/api/xiandu/category/"; 60 | 61 | /** 62 | * 获取闲读数据 63 | * id 后面可接受参数为子分类返回的id 64 | * page 第几页,从1开始 65 | * count 每页的个数 66 | */ 67 | public static final String XIANDU_DATA = "http://gank.io/api/xiandu/data/id/appinn/count/10/page/1"; 68 | 69 | /** 70 | * 方法:POST 71 | * 参数:username,password 72 | * 登录后会在cookie中返回账号密码,只要在客户端做cookie持久化存储即可自动登录验证。 73 | */ 74 | public static final String LOGIN = "http://www.wanandroid.com/user/login"; 75 | 76 | /** 77 | * 方法:POST 78 | * 参数:username,password,repassword 79 | */ 80 | public static final String REGISTER = "http://www.wanandroid.com/user/register"; 81 | 82 | /** 83 | * 方法:GET 84 | * 访问了 logout 后,服务端会让客户端清除 Cookie(即cookie max-Age=0), 85 | * 如果客户端 Cookie 实现合理,可以实现自动清理,如果本地做了用户账号密码和保存,及时清理。 86 | */ 87 | public static final String LOGOUT = "http://www.wanandroid.com/user/logout/json"; 88 | 89 | /** 90 | * http://www.wanandroid.com/lg/collect/list/0/json 91 | * 方法:GET 92 | * 参数:页码:拼接在链接中,从0开始。 93 | */ 94 | public static final String COLLECT_LIST = "http://www.wanandroid.com/lg/collect/list/0/json"; 95 | 96 | } 97 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/db/DBHelper.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.db; 2 | 3 | import com.activeandroid.Model; 4 | 5 | /** 6 | * Created by wavever on 2016/10/17. 7 | */ 8 | 9 | public class DBHelper { 10 | public static boolean isTableExist(Class table){ 11 | 12 | 13 | 14 | return false; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/event/ClickEvent.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.event; 2 | 3 | import me.wavever.ganklock.model.bean.GankDaily; 4 | 5 | /** 6 | * Created by wavever on 2016/9/26. 7 | */ 8 | 9 | public class ClickEvent { 10 | 11 | public static final int CLICK_TYPE_DAILY_PHOTO = 0; 12 | public static final int CLICK_TYPE_DAILY_TITLE = 1; 13 | 14 | public static final int CLICK_TYPE_MEIZHI = 2; 15 | 16 | public static final int CLICK_TYPE_LIKE = 3; 17 | 18 | public int eventType; 19 | 20 | public GankDaily gankDaily; 21 | 22 | public int position; 23 | 24 | public ClickEvent(int eventType,GankDaily gankDaily) { 25 | this.eventType = eventType; 26 | this.gankDaily = gankDaily; 27 | } 28 | 29 | public ClickEvent(int eventType,int position) { 30 | this.eventType = eventType; 31 | this.position = position; 32 | } 33 | 34 | 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/event/RxBus.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.event; 2 | 3 | import rx.Observable; 4 | import rx.subjects.PublishSubject; 5 | import rx.subjects.SerializedSubject; 6 | 7 | /** 8 | * 使用RxJava实现事件总线 9 | */ 10 | public class RxBus { 11 | 12 | private static volatile RxBus instance; 13 | 14 | private final SerializedSubject subject; 15 | 16 | private RxBus() { 17 | subject = new SerializedSubject<>(PublishSubject.create()); 18 | } 19 | 20 | /** 21 | * 单例模式获取RxBus 22 | * 23 | * @return 24 | */ 25 | public static RxBus getInstance() { 26 | RxBus rxBus = instance; 27 | if (instance == null) { 28 | synchronized (RxBus.class) { 29 | rxBus = instance; 30 | if (instance == null) { 31 | rxBus = new RxBus(); 32 | instance = rxBus; 33 | } 34 | } 35 | } 36 | return rxBus; 37 | } 38 | 39 | /** 40 | * 发送一个新的事件 41 | * 42 | * @param object 43 | */ 44 | public void post(Object object) { 45 | subject.onNext(object); 46 | } 47 | 48 | /** 49 | * 根据传递的eventType类型返回特定的被观察者 50 | * @param eventType 51 | * @param 52 | * @return 53 | */ 54 | public Observable tObservable(Class eventType) { 55 | return subject.ofType(eventType); 56 | } 57 | 58 | public boolean hasObservers() { 59 | return subject.hasObservers(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/event/SettingEvent.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.event; 2 | 3 | /** 4 | * Created by wavever on 2016/9/26. 5 | */ 6 | 7 | public class SettingEvent { 8 | 9 | public String key; 10 | 11 | public SettingEvent(String key) { 12 | this.key = key; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/event/StatusEvent.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.event; 2 | 3 | import android.os.Bundle; 4 | 5 | /** 6 | * Created by wavever on 2016/9/29. 7 | */ 8 | 9 | public class StatusEvent { 10 | 11 | public static String TYPE_ON_PHOTO_FILE_CHANGE = "file_change"; 12 | public static String TYPE_ON_LIKE_CHANGE = "like_change"; 13 | public static String TYPE_OPEN_GANK_LOCK = "open_gank_lock"; 14 | public static String TYPE_CLOSE_GANK_LOCK = "close_gank_lock"; 15 | 16 | public String type; 17 | 18 | public Bundle bundle; 19 | 20 | 21 | public StatusEvent(String type) { 22 | this(type, null); 23 | } 24 | 25 | 26 | public StatusEvent(String type, Bundle bundle) { 27 | this.type = type; 28 | this.bundle = bundle; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/model/bean/Gank.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.model.bean; 2 | 3 | import com.activeandroid.Model; 4 | import com.activeandroid.annotation.Column; 5 | import com.activeandroid.annotation.Table; 6 | import java.io.Serializable; 7 | import java.util.Date; 8 | 9 | /** 10 | * Created by wavever on 2015/12/24. 11 | */ 12 | @Table(name = "Ganks") public class Gank extends Model implements Serializable { 13 | 14 | @Column(name = "_id") private String _id; 15 | @Column(name = "url") private String url; 16 | @Column(name = "desc") private String desc; 17 | @Column(name = "who") private String who; 18 | @Column(name = "type") private String type; 19 | @Column(name = "used") private boolean used; 20 | @Column(name = "createdAt") private Date createdAt; 21 | //2016-03-10T12:54:31.68Z->2016/03/10 22 | @Column(name = "publishedAt") private Date publishedAt; 23 | private boolean isLike; 24 | 25 | 26 | public String get_id() { 27 | return _id; 28 | } 29 | 30 | 31 | public Date getCreatedAt() { 32 | return createdAt; 33 | } 34 | 35 | 36 | public String getUrl() { 37 | return url; 38 | } 39 | 40 | 41 | public String getDesc() { 42 | return desc; 43 | } 44 | 45 | 46 | public String getWho() { 47 | return who; 48 | } 49 | 50 | 51 | public String getType() { 52 | return type; 53 | } 54 | 55 | 56 | public boolean isUsed() { 57 | return used; 58 | } 59 | 60 | 61 | public Date getCreateAt() { 62 | return createdAt; 63 | } 64 | 65 | 66 | public Date getPublishedAt() { 67 | return publishedAt; 68 | } 69 | 70 | 71 | public void setIsLike(boolean like) { 72 | isLike = like; 73 | } 74 | 75 | public boolean getIsLike() { 76 | return isLike; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/model/bean/GankContent.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.model.bean; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import java.util.List; 5 | 6 | /** 7 | * Created by wavever on 2016/3/5. 8 | */ 9 | public class GankContent { 10 | 11 | @SerializedName(value = "category") 12 | public List category; 13 | 14 | @SerializedName(value = "error") 15 | public boolean error; 16 | 17 | public Result results; 18 | 19 | public class Result { 20 | @SerializedName(value = "Android") public List androidList; 21 | @SerializedName(value = "iOS") public List iosList; 22 | @SerializedName(value = "App") public List appList; 23 | @SerializedName(value = "前端") public List htmlList; 24 | @SerializedName(value = "瞎推荐") public List recommendList; 25 | @SerializedName(value = "休息视频") public List restVideoList; 26 | @SerializedName(value = "拓展资源") public List extendRespurseList; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/model/bean/GankDaily.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.model.bean; 2 | 3 | import com.activeandroid.Model; 4 | import com.activeandroid.annotation.Column; 5 | import com.activeandroid.annotation.Table; 6 | import com.google.gson.annotations.SerializedName; 7 | 8 | /** 9 | * Created by wavever on 2016/9/9. 10 | */ 11 | @Table(name = "GankDaily") 12 | public class GankDaily extends Model { 13 | @SerializedName(value = "_id") 14 | @Column(name = "_id") 15 | public String _id; 16 | @SerializedName(value = "publishedAt") 17 | @Column(name = "publishedAt") 18 | public String publishedAt; 19 | @SerializedName(value = "title") 20 | @Column(name = "title") 21 | public String title; 22 | @SerializedName(value = "content") 23 | @Column(name = "content") 24 | public String content;//妹纸图的url 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/model/bean/GankDailyContent.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.model.bean; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import java.util.List; 5 | 6 | /** 7 | * Created by wavever on 2016/9/21. 8 | */ 9 | 10 | public class GankDailyContent { 11 | 12 | @SerializedName(value = "error") 13 | public String error; 14 | 15 | @SerializedName(value = "results") 16 | public List results; 17 | 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/model/bean/Like.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.model.bean; 2 | 3 | import com.activeandroid.Model; 4 | import com.activeandroid.annotation.Column; 5 | import com.activeandroid.annotation.Table; 6 | 7 | /** 8 | * Created by wavever on 2016/10/13. 9 | */ 10 | @Table(name = "Likes") 11 | public class Like extends Model{ 12 | 13 | @Column(name = "_id") 14 | public String _id; 15 | @Column(name = "desc") 16 | public String desc; 17 | @Column(name = "publishedAt") 18 | public String publishedAt; 19 | @Column(name = "type") 20 | public String type; 21 | @Column(name = "url") 22 | public String url; 23 | @Column(name = "who") 24 | public String who; 25 | 26 | 27 | public Like(String _id, String desc, String publishedAt, String type, String url, String who) { 28 | this._id = _id; 29 | this.desc = desc; 30 | this.publishedAt = publishedAt; 31 | this.type = type; 32 | this.url = url; 33 | this.who = who; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/model/data/ContentGankData.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.model.data; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import io.reactivex.Observer; 7 | import io.reactivex.android.schedulers.AndroidSchedulers; 8 | import io.reactivex.functions.Function; 9 | import io.reactivex.schedulers.Schedulers; 10 | import me.wavever.ganklock.model.bean.Gank; 11 | import me.wavever.ganklock.model.bean.GankContent; 12 | import me.wavever.ganklock.model.http.GankService; 13 | import me.wavever.ganklock.model.http.RetrofitUtil; 14 | 15 | /** 16 | * Created by wavever on 2016/9/20. 17 | */ 18 | 19 | public class ContentGankData { 20 | 21 | private GankService service = RetrofitUtil.getSingleton(); 22 | private List mList = new ArrayList<>(); 23 | 24 | public void getDailyGankDataFromServer(String date, Observer observer) { 25 | 26 | service.getGankData(date) 27 | .map(new Function() { 28 | @Override 29 | public GankContent.Result apply(GankContent gankContent) throws Exception { 30 | return gankContent.results; 31 | } 32 | }).map(new Function>() { 33 | @Override 34 | public List apply(GankContent.Result result) throws Exception { 35 | return addAllResult(result); 36 | } 37 | }).subscribeOn(Schedulers.io()) //在io线程进行数据的读取 放在任何地方都可以 38 | .observeOn(AndroidSchedulers.mainThread()) //在主线程处理数据 指定的是它之后的操作的线程,因此如果需要多次切换线程,可指定多次 39 | .subscribe(observer); 40 | /*service.getGankData(date).flatMap(new Func1>() { 41 | @Override public Observable call(GankContent gankContent) { 42 | return Observable.from(gankContent.results); 43 | } 44 | }) 45 | .subscribeOn(Schedulers.io()) 46 | .observeOn(AndroidSchedulers.mainThread()).subscribe(subscriber);*/ 47 | } 48 | 49 | 50 | private List addAllResult(GankContent.Result results) { 51 | if (!mList.isEmpty()) mList.clear(); 52 | if (results.androidList != null) mList.addAll(0, results.androidList); 53 | if (results.iosList != null) mList.addAll(results.iosList); 54 | if (results.htmlList != null) mList.addAll(results.htmlList); 55 | if (results.appList != null) mList.addAll(results.appList); 56 | if (results.recommendList != null) mList.addAll(results.recommendList); 57 | if(results.extendRespurseList != null) mList.addAll(results.extendRespurseList); 58 | if (results.restVideoList != null) mList.addAll(results.restVideoList); 59 | return mList; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/model/data/DailyGankData.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.model.data; 2 | 3 | import com.activeandroid.query.Select; 4 | 5 | import java.util.List; 6 | 7 | import io.reactivex.Observable; 8 | import io.reactivex.ObservableEmitter; 9 | import io.reactivex.ObservableOnSubscribe; 10 | import io.reactivex.ObservableSource; 11 | import io.reactivex.Observer; 12 | import io.reactivex.android.schedulers.AndroidSchedulers; 13 | import io.reactivex.disposables.Disposable; 14 | import io.reactivex.functions.Consumer; 15 | import io.reactivex.functions.Function; 16 | import io.reactivex.schedulers.Schedulers; 17 | import me.wavever.ganklock.model.bean.GankDaily; 18 | import me.wavever.ganklock.model.bean.GankDailyContent; 19 | import me.wavever.ganklock.model.http.GankService; 20 | import me.wavever.ganklock.model.http.RetrofitUtil; 21 | import me.wavever.ganklock.utils.LogUtil; 22 | 23 | /** 24 | * Created by wavever on 2016/9/1. 25 | */ 26 | public class DailyGankData { 27 | 28 | private static String TAG = DailyGankData.class.getSimpleName() + "-->"; 29 | 30 | private GankService service = RetrofitUtil.getSingleton(); 31 | 32 | private List mList; 33 | 34 | public List getDailyDataFromDB(Observer> observer) { 35 | Observable.create(new ObservableOnSubscribe>() { 36 | @Override 37 | public void subscribe(ObservableEmitter> emitter) throws Exception { 38 | List list = new Select().from(GankDaily.class) 39 | .orderBy("publishedAt DESC")//DESC ASC 40 | .execute(); 41 | emitter.onNext(list); 42 | } 43 | }).subscribeOn(Schedulers.io()) 44 | .subscribe(observer); 45 | return mList; 46 | } 47 | 48 | public void getDailyDataFromServer(Observer observer, int count, int pager) { 49 | service.getDailyData(count, pager) 50 | .flatMap(new Function>() { 51 | @Override 52 | public ObservableSource apply(GankDailyContent gankDailyContent) throws Exception { 53 | return Observable.fromIterable(gankDailyContent.results); 54 | } 55 | }).subscribeOn(Schedulers.io()) 56 | .subscribe(observer); 57 | } 58 | 59 | public void saveDailyDataToDB(List datas) { 60 | Observable.fromIterable(datas) 61 | .doOnNext(new Consumer() { 62 | @Override 63 | public void accept(GankDaily gankDaily) throws Exception { 64 | if (!new Select().from(GankDaily.class) 65 | .where("_id=?", gankDaily._id) 66 | .exists()) { 67 | gankDaily.save(); 68 | LogUtil.d(TAG + "保存成功" + gankDaily.publishedAt); 69 | } 70 | LogUtil.d(TAG + "已经存在" + gankDaily.publishedAt); 71 | } 72 | }).subscribeOn(Schedulers.io()) 73 | .observeOn(AndroidSchedulers.mainThread()) 74 | .subscribe(new Observer() { 75 | @Override 76 | public void onSubscribe(Disposable d) { 77 | 78 | } 79 | 80 | @Override 81 | public void onNext(GankDaily gankDaily) { 82 | 83 | } 84 | 85 | @Override 86 | public void onError(Throwable e) { 87 | LogUtil.d(TAG + "保存失败" + e); 88 | } 89 | 90 | @Override 91 | public void onComplete() { 92 | 93 | } 94 | }); 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/model/http/GankService.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.model.http; 2 | 3 | import io.reactivex.Observable; 4 | import me.wavever.ganklock.model.bean.GankContent; 5 | import me.wavever.ganklock.model.bean.GankDailyContent; 6 | import retrofit2.http.GET; 7 | import retrofit2.http.Path; 8 | import retrofit2.http.Query; 9 | 10 | /** 11 | * Created by wavever on 2016/3/4. 12 | */ 13 | public interface GankService { 14 | @GET("day/{date}") 15 | Observable getGankData(@Path("date") String date); 16 | 17 | @GET("history/content/{count}/{page}") 18 | Observable getDailyData(@Path("count")int count, @Path("page")int page); 19 | 20 | @GET("data/福利/{number}/{page}") 21 | Observable getGirlData(@Path("number") int number, @Path("page") int page); 22 | 23 | @GET("category/{}/count/{}/page/{}") 24 | Observable searchGankData(@Query("category") String category,@Path("count") int count,@Path("page") int page); 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/model/http/RetrofitUtil.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.model.http; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.GsonBuilder; 5 | import java.lang.reflect.Modifier; 6 | import java.util.concurrent.TimeUnit; 7 | import me.wavever.ganklock.config.GankApi; 8 | import okhttp3.OkHttpClient; 9 | import okhttp3.logging.HttpLoggingInterceptor; 10 | import retrofit2.Retrofit; 11 | import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; 12 | import retrofit2.converter.gson.GsonConverterFactory; 13 | 14 | /** 15 | * Created by wavever on 2016/3/26. 16 | */ 17 | public class RetrofitUtil { 18 | 19 | private static GankService sService; 20 | private static Gson sGson; 21 | private static OkHttpClient sOkHttpClient; 22 | 23 | static { 24 | sGson = new GsonBuilder() 25 | .excludeFieldsWithModifiers(Modifier.FINAL, Modifier.TRANSIENT, Modifier.STATIC) 26 | //.setDateFormat("yyyy-MM-dd'T'HH:mm:ss" + ".SSS'Z'") 27 | .setDateFormat("yyyy/MM/dd") 28 | .serializeNulls() //导出null值 29 | .create(); 30 | HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(); 31 | loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY); 32 | sOkHttpClient = new OkHttpClient.Builder() 33 | .addInterceptor(loggingInterceptor) 34 | .retryOnConnectionFailure(true) 35 | .connectTimeout(15, TimeUnit.SECONDS) 36 | .build(); 37 | } 38 | 39 | 40 | public static GankService getSingleton() { 41 | 42 | if (sService == null) { 43 | synchronized (RetrofitUtil.class) { 44 | if (sService == null) { 45 | String api = GankApi.BASE_URL; 46 | Retrofit retrofit = new Retrofit.Builder() 47 | .baseUrl(api) 48 | .client(sOkHttpClient) 49 | .addConverterFactory(GsonConverterFactory.create(sGson)) 50 | .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) 51 | .build(); 52 | sService = retrofit.create(GankService.class); 53 | } 54 | } 55 | } 56 | 57 | return sService; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/presenter/BasePresenter.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.presenter; 2 | 3 | import java.lang.ref.Reference; 4 | import java.lang.ref.WeakReference; 5 | 6 | /** 7 | * Created by wavever on 2016/8/12. 8 | */ 9 | public abstract class BasePresenter { 10 | 11 | protected Reference mViewRef; 12 | 13 | public BasePresenter(){} 14 | 15 | public void attachView(V view) { 16 | mViewRef = new WeakReference<>(view); 17 | } 18 | 19 | public V getView() { 20 | return mViewRef.get(); 21 | } 22 | 23 | public boolean isViewAttached() { 24 | return mViewRef != null && mViewRef.get() != null; 25 | } 26 | 27 | public void detachView() { 28 | if (mViewRef.get() != null) { 29 | mViewRef.clear(); 30 | mViewRef = null; 31 | } 32 | } 33 | 34 | //在Presenter中实现Activity的生命周期 35 | public void onActivityLifeCreate() {} 36 | 37 | public void onActivityLifeStart() {} 38 | 39 | public void onActivityLifeResume() {} 40 | 41 | public void onActivityLifePause() {} 42 | 43 | public void onActivityLifeStop() {} 44 | 45 | public void onActivityLifeDestory() {} 46 | 47 | 48 | //在Presenter中实现Fragment的生命周期 49 | 50 | public void onFragmentLifeAttach(){}//Fragment与Activity关联时调用 51 | 52 | public void onFragmentLifeCreate(){} 53 | 54 | public void onFragmentLifeCreateView(){}//Fragment加载布局时调用 55 | 56 | public void onFragmentLifeActivityCreated(){} 57 | 58 | public void onFragmentLifeStart(){} 59 | 60 | public void onFragmentLifeResume(){} 61 | 62 | public void onFragmentLifePause(){} 63 | 64 | public void onFragmentLifeStop(){} 65 | 66 | public void onFragmentLifeDestroyView(){}//Fragment中的布局被移除时调用 67 | 68 | public void onFragmentLifeDestory(){} 69 | 70 | public void onFragmentLifeDetach(){}//Fragment与Activity解除关联时调用 71 | } 72 | 73 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/presenter/DailyGankPresenter.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.presenter; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import io.reactivex.Observer; 7 | import io.reactivex.disposables.Disposable; 8 | import me.wavever.ganklock.model.bean.GankDaily; 9 | import me.wavever.ganklock.model.data.DailyGankData; 10 | import me.wavever.ganklock.utils.PreferenceUtil; 11 | import me.wavever.ganklock.utils.SystemUtil; 12 | import me.wavever.ganklock.view.IDailyGankView; 13 | 14 | /** 15 | * Created by wavever on 2016/8/14. 16 | */ 17 | public class DailyGankPresenter extends BasePresenter { 18 | 19 | private static String TAG = DailyGankPresenter.class.getSimpleName() + "-->"; 20 | 21 | private static final int COUNT = 5;//每页加载的数据个数 22 | 23 | private DailyGankData dailyGankData = new DailyGankData(); 24 | private List mList = new ArrayList<>(); 25 | 26 | public void loadDailyData(int page) { 27 | if (!SystemUtil.isNetworkAvailable()) { 28 | Observer> observer = new Observer>() { 29 | 30 | @Override public void onError(Throwable e) { 31 | getView().loadFailure(); 32 | } 33 | 34 | @Override 35 | public void onComplete() { 36 | 37 | } 38 | 39 | @Override 40 | public void onSubscribe(Disposable d) { 41 | 42 | } 43 | 44 | @Override public void onNext(List gankDailies) { 45 | getView().showDailyData(gankDailies); 46 | } 47 | }; 48 | dailyGankData.getDailyDataFromDB(observer); 49 | 50 | } else { 51 | Observer observer = new Observer() { 52 | 53 | @Override public void onError(Throwable e) { 54 | getView().loadFailure(); 55 | } 56 | 57 | @Override 58 | public void onComplete() { 59 | getView().showDailyData(mList); 60 | PreferenceUtil.putString("url", mList.get(0).content); 61 | dailyGankData.saveDailyDataToDB(mList); 62 | } 63 | 64 | @Override 65 | public void onSubscribe(Disposable d) { 66 | 67 | } 68 | 69 | @Override public void onNext(GankDaily gankDaily) { 70 | gankDaily.content = convertContent2Url(gankDaily.content); 71 | mList.add(gankDaily); 72 | } 73 | }; 74 | dailyGankData.getDailyDataFromServer(observer, COUNT, page); 75 | } 76 | 77 | } 78 | 79 | 80 | private String convertContent2Url(String content) { 81 | int start = content.indexOf("src=") + 5; 82 | int end = content.indexOf("jpg") + 3; 83 | return content.substring(start, end); 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/presenter/GankContentPresenter.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.presenter; 2 | 3 | 4 | import java.util.List; 5 | 6 | import io.reactivex.Observer; 7 | import io.reactivex.disposables.Disposable; 8 | import me.wavever.ganklock.model.bean.Gank; 9 | import me.wavever.ganklock.model.data.ContentGankData; 10 | import me.wavever.ganklock.view.IGankContentView; 11 | 12 | /** 13 | * Created by wavever on 2016/3/4. 14 | */ 15 | public class GankContentPresenter extends BasePresenter { 16 | 17 | private static final String TAG = "GankContentPresenter-->"; 18 | private final ContentGankData contentGankData = new ContentGankData(); 19 | 20 | public void loadContentData(String date) { 21 | 22 | Observer observer = new Observer>() { 23 | @Override 24 | public void onSubscribe(Disposable d) { 25 | 26 | } 27 | 28 | @Override 29 | public void onNext(List list) { 30 | getView().showData(list); 31 | } 32 | 33 | @Override 34 | public void onError(Throwable e) { 35 | getView().showError(); 36 | } 37 | 38 | @Override 39 | public void onComplete() { 40 | 41 | } 42 | }; 43 | contentGankData.getDailyGankDataFromServer(date, observer); 44 | } 45 | 46 | 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/presenter/IPresenter.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.presenter; 2 | 3 | /** 4 | * Created by wavever on 2016/8/30. 5 | */ 6 | public interface IPresenter

{ 7 | P createPresenter(); 8 | 9 | P getPresenter(); 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/presenter/LikePresenter.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.presenter; 2 | 3 | import com.activeandroid.query.Select; 4 | import java.util.List; 5 | import me.wavever.ganklock.model.bean.Gank; 6 | import me.wavever.ganklock.utils.LogUtil; 7 | import me.wavever.ganklock.view.ILikeView; 8 | 9 | /** 10 | * Created by wavever on 2016/9/2. 11 | */ 12 | public class LikePresenter extends BasePresenter{ 13 | 14 | private static final String TAG = LikePresenter.class.getSimpleName()+"-->"; 15 | 16 | public void getLikeList(){ 17 | List list = new Select().from(Gank.class).execute(); 18 | for(Gank gank:list){ 19 | LogUtil.d(TAG+"收藏"+gank.getDesc()); 20 | } 21 | if(list == null || list.isEmpty()){ 22 | getView().showEmptyTip(); 23 | }else { 24 | getView().showLikeData(list); 25 | } 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/presenter/LockPresenter.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.presenter; 2 | 3 | import me.wavever.ganklock.view.ILockView; 4 | 5 | public class LockPresenter extends BasePresenter { 6 | } 7 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/presenter/MeiZhiPresenter.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.presenter; 2 | 3 | import android.os.Environment; 4 | import java.io.File; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import io.reactivex.Observer; 9 | import io.reactivex.android.schedulers.AndroidSchedulers; 10 | import io.reactivex.disposables.Disposable; 11 | import io.reactivex.functions.Predicate; 12 | import io.reactivex.schedulers.Schedulers; 13 | import me.wavever.ganklock.view.IMeiZhiView; 14 | import io.reactivex.Observable; 15 | 16 | /** 17 | * Created by wavever on 2016/9/2. 18 | */ 19 | public class MeiZhiPresenter extends BasePresenter { 20 | 21 | private static final String TAG = "MeiZhiPresenter-->"; 22 | 23 | private List mList = new ArrayList<>(); 24 | 25 | public void loadMeizhi() { 26 | File fileDir = new File(Environment.getExternalStorageDirectory(), "GankLock"); 27 | if (!fileDir.exists()||fileDir.listFiles().length==0) { 28 | getView().showEmptyView(); 29 | return; 30 | } 31 | if(!mList.isEmpty()){ 32 | mList.clear(); 33 | } 34 | Observable.fromArray(fileDir.listFiles()) 35 | .filter(new Predicate() { 36 | @Override 37 | public boolean test(File file) { 38 | return file.getName().endsWith(".jpg"); 39 | } 40 | }) 41 | .subscribeOn(Schedulers.io()) 42 | .observeOn(AndroidSchedulers.mainThread()) 43 | .unsubscribeOn(AndroidSchedulers.mainThread()) 44 | .subscribe(new Observer() { 45 | @Override 46 | public void onSubscribe(Disposable d) { 47 | 48 | } 49 | 50 | @Override 51 | public void onNext(File file) { 52 | mList.add(file); 53 | } 54 | 55 | @Override 56 | public void onError(Throwable e) { 57 | } 58 | 59 | @Override 60 | public void onComplete() { 61 | if (getView() != null) { 62 | getView().showMeizhi(mList); 63 | } 64 | } 65 | }); 66 | } 67 | 68 | 69 | } 70 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/presenter/MorePresenter.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.presenter; 2 | 3 | import me.wavever.ganklock.view.IMoreView; 4 | 5 | /** 6 | * Created by waveverht on 2016/9/18. 7 | */ 8 | 9 | public class MorePresenter extends BasePresenter { 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/presenter/WebViewPresenter.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.presenter; 2 | 3 | import me.wavever.ganklock.view.IWebView; 4 | 5 | /** 6 | * Created by wavever. on 2016/10/18. 7 | */ 8 | 9 | public class WebViewPresenter extends BasePresenter{ 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/receiver/GankLockReceiver.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.receiver; 2 | 3 | import android.content.BroadcastReceiver; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.telephony.TelephonyManager; 7 | import me.wavever.ganklock.MyApplication; 8 | import me.wavever.ganklock.ui.activity.LockActivity; 9 | 10 | /** 11 | * Created by wavever on 2015/12/24. 12 | */ 13 | public class GankLockReceiver extends BroadcastReceiver { 14 | 15 | private static final String TAG = GankLockReceiver.class.getSimpleName(); 16 | 17 | 18 | @Override 19 | public void onReceive(Context context, Intent intent) { 20 | String action = intent.getAction(); 21 | /*if (action.equals(Intent.ACTION_SCREEN_ON)) { 22 | LockManager.createLockView(); 23 | onPhoneRing(); 24 | }*/ 25 | if (action.equals(Intent.ACTION_SCREEN_OFF)) { 26 | Intent mLockIntent = new Intent(context, LockActivity.class); 27 | mLockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK 28 | | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 29 | context.startActivity(mLockIntent); 30 | } 31 | } 32 | 33 | 34 | public void onPhoneRing() { 35 | //手机处于响铃状态 36 | if (((TelephonyManager) MyApplication.getContext() 37 | .getSystemService("phone")).getCallState() == TelephonyManager.CALL_STATE_IDLE) { 38 | } 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/service/LockService.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.service; 2 | 3 | import android.app.Service; 4 | import android.content.BroadcastReceiver; 5 | import android.content.Intent; 6 | import android.content.IntentFilter; 7 | import android.os.IBinder; 8 | import me.wavever.ganklock.config.Config; 9 | import me.wavever.ganklock.receiver.GankLockReceiver; 10 | import me.wavever.ganklock.utils.PreferenceUtil; 11 | 12 | /** 13 | * Created by wavever on 2015/12/26. 14 | */ 15 | public class LockService extends Service { 16 | 17 | private BroadcastReceiver receiver; 18 | 19 | @Override 20 | public void onCreate() { 21 | super.onCreate(); 22 | IntentFilter intentFilter = new IntentFilter(); 23 | intentFilter.addAction(Intent.ACTION_SCREEN_ON); 24 | intentFilter.addAction(Intent.ACTION_SCREEN_OFF); 25 | receiver = new GankLockReceiver(); 26 | registerReceiver(receiver, intentFilter); 27 | } 28 | 29 | @Override 30 | public int onStartCommand(Intent intent, int flags, int startId) { 31 | return Service.START_STICKY; 32 | } 33 | 34 | @Override 35 | public void onDestroy() { 36 | super.onDestroy(); 37 | if(PreferenceUtil.getBoolean(Config.GANK_LOCK_IS_OPEN)){ 38 | //LockManager.startLock(false); 39 | startService(new Intent(LockService.this,LockService.class)); 40 | return; 41 | } 42 | unregisterReceiver(receiver); 43 | } 44 | 45 | @Override 46 | public IBinder onBind(Intent intent) { 47 | return null; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/ui/activity/AboutActivity.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.ui.activity; 2 | 3 | import android.os.Bundle; 4 | import android.widget.TextView; 5 | import me.wavever.ganklock.BuildConfig; 6 | import me.wavever.ganklock.R; 7 | 8 | /** 9 | * Created by wavever on 2016/3/12. 10 | */ 11 | public class AboutActivity extends BaseActivity { 12 | 13 | private TextView mTvVersion; 14 | 15 | @Override protected int loadView() { 16 | return R.layout.activity_about; 17 | } 18 | 19 | @Override protected void initView() { 20 | mTvVersion = (TextView) findViewById(R.id.tv_version); 21 | } 22 | 23 | @Override 24 | protected void onCreate(Bundle savedInstanceState) { 25 | super.onCreate(savedInstanceState); 26 | if (mToolbar != null && getSupportActionBar() != null) { 27 | getSupportActionBar().setDisplayHomeAsUpEnabled(true); 28 | } 29 | mTvVersion.setText(getResources().getString(R.string.app_version_code)+BuildConfig.VERSION_NAME); 30 | } 31 | 32 | 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/ui/activity/BaseActivity.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.ui.activity; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.support.v7.widget.Toolbar; 7 | import android.view.MenuItem; 8 | import android.view.MotionEvent; 9 | import me.wavever.ganklock.R; 10 | 11 | /** 12 | * Created by waveverht on 2016/10/19. 13 | */ 14 | 15 | public abstract class BaseActivity extends AppCompatActivity{ 16 | 17 | protected Toolbar mToolbar; 18 | 19 | protected abstract int loadView(); 20 | protected abstract void initView(); 21 | 22 | 23 | @Override protected void onCreate(@Nullable Bundle savedInstanceState) { 24 | super.onCreate(savedInstanceState); 25 | setContentView(loadView()); 26 | initToolbar(); 27 | initView(); 28 | } 29 | 30 | protected void initToolbar() { 31 | mToolbar = (Toolbar) findViewById(R.id.toolbar); 32 | if (mToolbar != null) { 33 | setSupportActionBar(mToolbar); 34 | } 35 | } 36 | 37 | @Override 38 | public boolean onOptionsItemSelected(MenuItem item) { 39 | if (item.getItemId() == android.R.id.home) { 40 | onBackPressed(); 41 | return true; 42 | } 43 | return super.onOptionsItemSelected(item); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/ui/activity/BaseMvpActivity.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.ui.activity; 2 | 3 | import android.os.Bundle; 4 | import me.wavever.ganklock.presenter.BasePresenter; 5 | import me.wavever.ganklock.presenter.IPresenter; 6 | 7 | /** 8 | * Created by wavever on 2015/12/26. 9 | */ 10 | public abstract class BaseMvpActivity> extends BaseActivity implements IPresenter

{ 11 | 12 | protected P mPresenter; 13 | 14 | @Override 15 | protected void onCreate(Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | if (mPresenter == null) { 18 | mPresenter = createPresenter(); 19 | mPresenter.attachView((V) this); 20 | } 21 | } 22 | 23 | @Override 24 | public P getPresenter() { 25 | if (mPresenter != null) { 26 | return mPresenter; 27 | } 28 | return null; 29 | } 30 | 31 | @Override 32 | protected void onStart() { 33 | super.onStart(); 34 | if (mPresenter != null) { 35 | mPresenter.onActivityLifeStart(); 36 | } 37 | } 38 | 39 | 40 | @Override 41 | protected void onResume() { 42 | super.onResume(); 43 | } 44 | 45 | 46 | @Override 47 | protected void onPause() { 48 | super.onPause(); 49 | } 50 | 51 | 52 | @Override 53 | protected void onStop() { 54 | super.onStop(); 55 | } 56 | 57 | 58 | @Override 59 | protected void onDestroy() { 60 | super.onDestroy(); 61 | if (mPresenter != null) { 62 | mPresenter.onActivityLifeDestory(); 63 | mPresenter.detachView(); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/ui/activity/LicenseActivity.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.ui.activity; 2 | 3 | import android.app.FragmentManager; 4 | import android.os.Bundle; 5 | import android.support.annotation.Nullable; 6 | import android.support.v7.widget.Toolbar; 7 | import android.view.MenuItem; 8 | import com.artitk.licensefragment.ScrollViewLicenseFragment; 9 | import com.artitk.licensefragment.model.License; 10 | import com.artitk.licensefragment.model.LicenseID; 11 | import com.artitk.licensefragment.model.LicenseType; 12 | import java.util.ArrayList; 13 | import me.wavever.ganklock.R; 14 | 15 | /** 16 | * Created by waveverht on 2016/10/18. 17 | */ 18 | 19 | public class LicenseActivity extends BaseActivity { 20 | 21 | @Override protected int loadView() { 22 | return R.layout.fragment_license; 23 | } 24 | 25 | 26 | @Override protected void initView() { 27 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 28 | setTitle(R.string.more_fragment_item_open_source); 29 | if (toolbar != null) { 30 | setSupportActionBar(toolbar); 31 | } 32 | if (getSupportActionBar() != null) { 33 | getSupportActionBar().setDisplayHomeAsUpEnabled(true); 34 | } 35 | FragmentManager fragmentManager = getFragmentManager(); 36 | ScrollViewLicenseFragment licenseFragment 37 | = (ScrollViewLicenseFragment) fragmentManager.findFragmentById(R.id.fragment_license); 38 | licenseFragment.setLog(true); 39 | licenseFragment.addLicense( 40 | new int[] { LicenseID.GSON, LicenseID.LICENSE_FRAGMENT, LicenseID.OKHTTP, 41 | LicenseID.RETROFIT, LicenseID.PICASSO }); 42 | ArrayList customLicenses = new ArrayList<>(); 43 | customLicenses.add( 44 | new License(this, "MaterialPreference", LicenseType.MIT_LICENSE, "2015", 45 | "Jens Driller")); 46 | customLicenses.add( 47 | new License(this, "ActiveAndroid", LicenseType.APACHE_LICENSE_20, "2010", 48 | "Michael Pardo")); 49 | customLicenses.add( 50 | new License(this, "MaterialBottomNavigation ", LicenseType.MIT_LICENSE, "2016", 51 | " Alessandro Crugnola")); 52 | customLicenses.add( 53 | new License(this, "PhotoView", LicenseType.APACHE_LICENSE_20, "2011-2012", 54 | "Chris Banes")); 55 | customLicenses.add( 56 | new License(this, "MagicaSakura", LicenseType.APACHE_LICENSE_20, "2016", "Bilibili")); 57 | customLicenses.add( 58 | new License(this, "Android Open Source Project", LicenseType.APACHE_LICENSE_20, 59 | "2009-2012", "Android Open Source Project")); 60 | licenseFragment.addCustomLicense(customLicenses); 61 | } 62 | 63 | 64 | @Override protected void onCreate(@Nullable Bundle savedInstanceState) { 65 | super.onCreate(savedInstanceState); 66 | } 67 | 68 | 69 | @Override 70 | public boolean onOptionsItemSelected(MenuItem item) { 71 | if (item.getItemId() == android.R.id.home) { 72 | onBackPressed(); 73 | return true; 74 | } 75 | return super.onOptionsItemSelected(item); 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/ui/activity/LockActivity.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.ui.activity; 2 | 3 | import android.graphics.Bitmap; 4 | import android.os.Build.VERSION; 5 | import android.os.Build.VERSION_CODES; 6 | import android.view.View; 7 | import android.view.Window; 8 | import android.view.WindowManager; 9 | import android.view.WindowManager.LayoutParams; 10 | import android.widget.ImageView; 11 | import android.widget.TextView; 12 | import android.widget.ViewSwitcher; 13 | import com.squareup.picasso.Picasso; 14 | import java.io.IOException; 15 | 16 | import io.reactivex.Observable; 17 | import io.reactivex.ObservableEmitter; 18 | import io.reactivex.ObservableOnSubscribe; 19 | import io.reactivex.android.schedulers.AndroidSchedulers; 20 | import io.reactivex.functions.Consumer; 21 | import io.reactivex.schedulers.Schedulers; 22 | import me.wavever.ganklock.R; 23 | import me.wavever.ganklock.presenter.LockPresenter; 24 | import me.wavever.ganklock.ui.widget.SwipeUnLockLayout; 25 | import me.wavever.ganklock.utils.DateUtil; 26 | import me.wavever.ganklock.utils.PreferenceUtil; 27 | import me.wavever.ganklock.view.ILockView; 28 | 29 | /** 30 | * Created by wavever on 2016/10/14. 31 | */ 32 | 33 | public class LockActivity extends BaseMvpActivity implements ILockView,SwipeUnLockLayout.OnSwipeListener { 34 | 35 | private static final String TAG = "LockActivity-->"; 36 | 37 | private ViewSwitcher mViewSwitcher; 38 | private ImageView mImg; 39 | private TextView mTitle; 40 | private Bitmap bitmap; 41 | private String url; 42 | 43 | @Override protected int loadView() { 44 | return R.layout.activity_lock; 45 | } 46 | 47 | @Override protected void initView() { 48 | getWindow().addFlags(LayoutParams.FLAG_DISMISS_KEYGUARD); 49 | getWindow().addFlags(LayoutParams.FLAG_SHOW_WHEN_LOCKED); 50 | setUI(); 51 | SwipeUnLockLayout swipeUnLockLayout = (SwipeUnLockLayout) findViewById( 52 | R.id.slide_layout); 53 | swipeUnLockLayout.setOnSwipeListener(this); 54 | mViewSwitcher = (ViewSwitcher) findViewById(R.id.lock_view_switcher); 55 | mTitle = (TextView) findViewById(R.id.lock_view_gank_title); 56 | TextView mLockViewDate = (TextView) findViewById(R.id.lock_view_date); 57 | final String lockDateText = DateUtil.getLockDateText(); 58 | mLockViewDate.setText(lockDateText); 59 | mImg = (ImageView) findViewById(R.id.lock_view_img); 60 | url = PreferenceUtil.getString("url"); 61 | if (url.isEmpty()) { 62 | mImg.setImageResource(R.drawable.test_image); 63 | } else { 64 | getBitmap(); 65 | } 66 | mImg.setOnClickListener(new View.OnClickListener() { 67 | @Override public void onClick(View v) { 68 | mViewSwitcher.showNext(); 69 | } 70 | }); 71 | 72 | } 73 | 74 | private void setUI() { 75 | Window window = getWindow(); 76 | window.getDecorView().setSystemUiVisibility( 77 | View.SYSTEM_UI_FLAG_LAYOUT_STABLE 78 | | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 79 | | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY 80 | | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 81 | | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 82 | ); 83 | if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) { 84 | window.addFlags(LayoutParams.FLAG_TRANSLUCENT_STATUS); 85 | } 86 | if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { 87 | window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); 88 | //这个属性重复设置会导致NAVIGATION BAR显示 89 | //window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); 90 | window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); 91 | window.setStatusBarColor(0); 92 | } 93 | } 94 | 95 | @Override public void onSwipeFinish() { 96 | finish(); 97 | } 98 | 99 | @Override public LockPresenter createPresenter() { 100 | return new LockPresenter(); 101 | } 102 | 103 | @Override 104 | public void onWindowFocusChanged(boolean hasFocus) { 105 | super.onWindowFocusChanged(hasFocus); 106 | if (hasFocus) { 107 | setUI(); 108 | } 109 | } 110 | 111 | private void getBitmap(){ 112 | 113 | Observable.create(new ObservableOnSubscribe() { 114 | @Override 115 | public void subscribe(ObservableEmitter emitter) throws Exception { 116 | try { 117 | bitmap = Picasso.with(LockActivity.this).load(url).get(); 118 | emitter.onNext(bitmap); 119 | } catch (IOException e) { 120 | e.printStackTrace(); 121 | } 122 | } 123 | }).subscribeOn(Schedulers.io()) 124 | .observeOn(AndroidSchedulers.mainThread()) 125 | .subscribe(new Consumer() { 126 | @Override 127 | public void accept(Bitmap bitmap) throws Exception { 128 | mImg.setImageBitmap(bitmap); 129 | } 130 | }); 131 | 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/ui/activity/MainActivity.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.ui.activity; 2 | 3 | import android.app.Fragment; 4 | import android.app.FragmentManager; 5 | import android.os.Bundle; 6 | import android.support.annotation.NonNull; 7 | import android.support.design.widget.BottomNavigationView; 8 | import android.support.design.widget.Snackbar; 9 | import android.view.MenuItem; 10 | import android.view.View; 11 | import me.wavever.ganklock.R; 12 | import me.wavever.ganklock.ui.fragment.DailyGankFragment; 13 | import me.wavever.ganklock.ui.fragment.LikeFragment; 14 | import me.wavever.ganklock.ui.fragment.MeizhiFragment; 15 | import me.wavever.ganklock.ui.fragment.MoreFragment; 16 | 17 | /** 18 | * Created by wavever on 2016/5/28. 19 | */ 20 | public class MainActivity extends BaseActivity { 21 | 22 | private Fragment mCurrentFragment; 23 | private DailyGankFragment dailyGankFragment; 24 | private LikeFragment likeFragment; 25 | private MeizhiFragment meizhiFragment; 26 | private MoreFragment moreFragment; 27 | private FragmentManager manager; 28 | 29 | private View mContainer; 30 | 31 | private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener 32 | = new BottomNavigationView.OnNavigationItemSelectedListener() { 33 | 34 | @Override 35 | public boolean onNavigationItemSelected(@NonNull MenuItem item) { 36 | switch (item.getItemId()) { 37 | case R.id.bbn_daliy: 38 | if (mCurrentFragment != dailyGankFragment) { 39 | if (dailyGankFragment == null) { 40 | dailyGankFragment = DailyGankFragment.getInstance(); 41 | } 42 | replaceFragmentByTag(dailyGankFragment); 43 | } 44 | break; 45 | case R.id.bbn_like: 46 | if (mCurrentFragment != likeFragment) { 47 | if (likeFragment == null) { 48 | likeFragment = new LikeFragment(); 49 | } 50 | replaceFragmentByTag(likeFragment); 51 | } 52 | break; 53 | case R.id.bbn_meizhi: 54 | if (mCurrentFragment != meizhiFragment) { 55 | if (meizhiFragment == null) { 56 | meizhiFragment = new MeizhiFragment(); 57 | } 58 | replaceFragmentByTag(meizhiFragment); 59 | } 60 | break; 61 | case R.id.bbn_more: 62 | if (mCurrentFragment != moreFragment) { 63 | if (moreFragment == null) { 64 | moreFragment = new MoreFragment(); 65 | } 66 | replaceFragmentByTag(moreFragment); 67 | } 68 | break; 69 | default: 70 | break; 71 | } 72 | return false; 73 | } 74 | }; 75 | 76 | @Override protected int loadView() { 77 | return R.layout.activity_main; 78 | } 79 | 80 | 81 | @Override protected void initView() { 82 | mContainer = findViewById(R.id.main_activity_container); 83 | BottomNavigationView navigation = findViewById(R.id.navigation); 84 | navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener); 85 | manager = getFragmentManager(); 86 | } 87 | 88 | 89 | @Override 90 | protected void onCreate(Bundle savedInstanceState) { 91 | super.onCreate(savedInstanceState); 92 | //解决内存重启导致Fragment重叠的问题 93 | dailyGankFragment = DailyGankFragment.getInstance(); 94 | replaceFragmentByTag(dailyGankFragment); 95 | } 96 | 97 | 98 | long time = 0; 99 | 100 | @Override 101 | public void onBackPressed() { 102 | if (System.currentTimeMillis() - time > 2000) { 103 | Snackbar.make(mContainer, R.string.exit_with_two_click, Snackbar.LENGTH_SHORT).show(); 104 | time = System.currentTimeMillis(); 105 | } else { 106 | super.onBackPressed(); 107 | } 108 | } 109 | 110 | public void replaceFragmentByTag(Fragment fragment) { 111 | if (mCurrentFragment == null) { 112 | manager.beginTransaction().add(R.id.main_activity_container, fragment, 113 | fragment.getClass().getSimpleName()).commit(); 114 | } else { 115 | if (fragment.isAdded()) { 116 | manager.beginTransaction().hide(mCurrentFragment).show(fragment).commit(); 117 | } else { 118 | manager.beginTransaction().hide(mCurrentFragment) 119 | .add(R.id.main_activity_container, fragment, 120 | fragment.getClass().getSimpleName()) 121 | .commit(); 122 | } 123 | } 124 | mCurrentFragment = fragment; 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/ui/activity/SettingActivity.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.ui.activity; 2 | 3 | import android.app.Fragment; 4 | import android.app.FragmentManager; 5 | import android.os.Bundle; 6 | import android.support.v7.widget.Toolbar; 7 | import android.view.MenuItem; 8 | import me.wavever.ganklock.R; 9 | import me.wavever.ganklock.ui.fragment.SettingFragment; 10 | 11 | /** 12 | * Created by wavever on 2016/2/23. 13 | */ 14 | public class SettingActivity extends BaseActivity { 15 | 16 | private Toolbar mToolbar; 17 | 18 | 19 | @Override protected int loadView() { 20 | return R.layout.activity_setting; 21 | } 22 | 23 | 24 | @Override protected void initView() { 25 | mToolbar = (Toolbar) findViewById(R.id.toolbar); 26 | setSupportActionBar(mToolbar); 27 | setTitle(R.string.action_setting); 28 | getSupportActionBar().setDisplayHomeAsUpEnabled(true); 29 | } 30 | 31 | 32 | @Override protected void onCreate(Bundle savedInstanceState) { 33 | super.onCreate(savedInstanceState); 34 | replaceFragment(R.id.setting_container, new SettingFragment()); 35 | } 36 | 37 | 38 | 39 | public void replaceFragment(int resId, Fragment fragment) { 40 | FragmentManager manager = getFragmentManager(); 41 | manager.beginTransaction().replace(resId, fragment).commit(); 42 | } 43 | 44 | @Override 45 | public boolean onOptionsItemSelected(MenuItem item) { 46 | if (item.getItemId() == android.R.id.home) { 47 | onBackPressed(); 48 | return true; 49 | } 50 | return super.onOptionsItemSelected(item); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/ui/activity/WebViewActivity.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.ui.activity; 2 | 3 | import android.R.id; 4 | import android.view.KeyEvent; 5 | import android.view.Menu; 6 | import android.view.MenuItem; 7 | import android.view.View; 8 | import android.webkit.WebChromeClient; 9 | import android.webkit.WebView; 10 | import android.webkit.WebViewClient; 11 | import android.widget.ProgressBar; 12 | 13 | import me.wavever.ganklock.R; 14 | import me.wavever.ganklock.presenter.WebViewPresenter; 15 | import me.wavever.ganklock.view.IWebView; 16 | 17 | import static android.view.View.GONE; 18 | 19 | /** 20 | * Created by wavever on 2016/10/18. 21 | */ 22 | 23 | public class WebViewActivity extends BaseMvpActivity 24 | implements IWebView { 25 | 26 | private static final String TAG = WebViewActivity.class.getSimpleName(); 27 | public static final String KEY_TITLE = "key_title"; 28 | public static final String KEY_URL = "key_url"; 29 | private ProgressBar mProgressBar; 30 | private WebView mWebView; 31 | private String mTitle; 32 | private String mUrl; 33 | 34 | 35 | @Override protected int loadView() { 36 | return R.layout.activity_web_view; 37 | } 38 | 39 | 40 | @Override protected void initView() { 41 | mUrl = getIntent().getStringExtra(KEY_URL); 42 | mTitle = getIntent().getStringExtra(KEY_TITLE); 43 | setTitle(mTitle); 44 | getSupportActionBar().setDisplayHomeAsUpEnabled(true); 45 | mProgressBar = findViewById(R.id.progress_bar_web_view); 46 | mWebView = findViewById(R.id.web_view); 47 | mWebView.getSettings().setJavaScriptEnabled(true);//支持JavaScript 48 | mWebView.setWebViewClient(new WebViewClient() { 49 | @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { 50 | view.loadUrl(url); 51 | return true; 52 | } 53 | }); 54 | mWebView.setWebChromeClient(new WebChromeClient() { 55 | @Override public void onProgressChanged(WebView view, int newProgress) { 56 | if (newProgress <= 90) { 57 | if (mProgressBar.getVisibility() == GONE) { 58 | mProgressBar.setVisibility(View.VISIBLE); 59 | } 60 | mProgressBar.setProgress(newProgress); 61 | } else { 62 | mProgressBar.setVisibility(GONE); 63 | } 64 | super.onProgressChanged(view, newProgress); 65 | } 66 | }); 67 | mWebView.loadUrl(mUrl); 68 | } 69 | 70 | 71 | @Override public WebViewPresenter createPresenter() { 72 | return new WebViewPresenter(); 73 | } 74 | 75 | 76 | @Override public boolean onCreateOptionsMenu(Menu menu) { 77 | //getMenuInflater().inflate(R.menu.web_view_menu, menu); 78 | return super.onCreateOptionsMenu(menu); 79 | } 80 | 81 | 82 | @Override public boolean onKeyDown(int keyCode, KeyEvent event) { 83 | if (keyCode == KeyEvent.KEYCODE_BACK && mWebView.canGoBack()) { 84 | mWebView.goBack(); 85 | return true; 86 | } 87 | return super.onKeyDown(keyCode, event); 88 | } 89 | 90 | 91 | @Override 92 | public boolean onOptionsItemSelected(MenuItem item) { 93 | switch (item.getItemId()) { 94 | case id.home: 95 | onBackPressed(); 96 | break; 97 | /*case R.id.action_webview_share: 98 | Intent intent = new Intent(); 99 | intent.setAction(Intent.ACTION_SEND); 100 | intent.setType("text/plain"); 101 | intent.putExtra(Intent.EXTRA_TEXT,mTitle+mUrl); 102 | startActivity(Intent.createChooser(intent, "分享到")); 103 | break; 104 | case R.id.action_webview_refresh: 105 | mWebView.reload(); 106 | break; 107 | case R.id.action_webview_copy_url: 108 | ClipboardManager copy = (ClipboardManager) getSystemService( 109 | Context.CLIPBOARD_SERVICE); 110 | copy.setText(mUrl); 111 | ToastUtil.showToastShort(this, "复制成功"); 112 | break; 113 | case R.id.action_webview_open_browser: 114 | mWebView.setWebViewClient(null); 115 | mWebView.loadUrl(mUrl); 116 | break;*/ 117 | } 118 | return true; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/ui/adapter/BaseRVAdapter.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.ui.adapter; 2 | 3 | import android.support.v7.widget.RecyclerView.Adapter; 4 | import android.support.v7.widget.RecyclerView.ViewHolder; 5 | import android.view.ViewGroup; 6 | 7 | /** 8 | * Created by wavever on 2016/9/25. 9 | */ 10 | 11 | public class BaseRVAdapter extends Adapter{ 12 | 13 | @Override public VH onCreateViewHolder(ViewGroup parent, int viewType) { 14 | return null; 15 | 16 | 17 | } 18 | 19 | 20 | @Override public void onBindViewHolder(VH holder, int position) { 21 | 22 | } 23 | 24 | 25 | @Override public int getItemCount() { 26 | return 0; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/ui/adapter/DailyListAdapter.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.ui.adapter; 2 | 3 | import android.app.Activity; 4 | import android.support.v7.widget.RecyclerView.Adapter; 5 | import android.support.v7.widget.RecyclerView.ViewHolder; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.View.OnClickListener; 9 | import android.view.ViewGroup; 10 | import android.widget.ImageView; 11 | import android.widget.TextView; 12 | import com.squareup.picasso.Picasso; 13 | import java.util.List; 14 | import me.wavever.ganklock.R; 15 | import me.wavever.ganklock.event.ClickEvent; 16 | import me.wavever.ganklock.event.RxBus; 17 | import me.wavever.ganklock.model.bean.GankDaily; 18 | import me.wavever.ganklock.utils.DateUtil; 19 | 20 | /** 21 | * Created by wavever on 2016/9/8. 22 | */ 23 | public class DailyListAdapter extends Adapter { 24 | 25 | private static final String TAG = DailyListAdapter.class.getSimpleName()+"-->"; 26 | 27 | private static final int TYPE_DAILY = 0; 28 | private static final int TYPE_FOOTER = 1; 29 | 30 | private List mDatas; 31 | private Activity mContext; 32 | 33 | public DailyListAdapter(List datas,Activity context) { 34 | mDatas = datas; 35 | mContext = context; 36 | } 37 | 38 | @Override 39 | public DailyListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {//设置为null会导致宽度高度失效--》parent 40 | View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_daily_recycler_view,parent,false); 41 | return new DailyListViewHolder(view); 42 | } 43 | 44 | @Override 45 | public void onBindViewHolder(DailyListViewHolder holder, int position) { 46 | holder.gankDaily = mDatas.get(position); 47 | holder.title.setText(mDatas.get(position).title); 48 | holder.date.setText(DateUtil.convertDateNum(mDatas.get(position).publishedAt)); 49 | Picasso.with(mContext).load(mDatas.get(position).content).into(holder.img); 50 | } 51 | 52 | @Override 53 | public int getItemCount() { 54 | return mDatas == null ? 0 : mDatas.size(); 55 | } 56 | 57 | 58 | @Override public int getItemViewType(int position) { 59 | return super.getItemViewType(position); 60 | } 61 | 62 | public class DailyListViewHolder extends ViewHolder{ 63 | 64 | GankDaily gankDaily; 65 | ImageView img; 66 | TextView title; 67 | TextView date; 68 | ImageView newTag; 69 | 70 | public DailyListViewHolder(View itemView) { 71 | super(itemView); 72 | img = (ImageView) itemView.findViewById(R.id.daily_item_image); 73 | img.setOnClickListener(new OnClickListener() { 74 | @Override public void onClick(View v) { 75 | RxBus.getInstance().post(new ClickEvent(ClickEvent.CLICK_TYPE_DAILY_PHOTO,gankDaily)); 76 | } 77 | }); 78 | date = (TextView) itemView.findViewById(R.id.daily_item_date); 79 | title = (TextView) itemView.findViewById(R.id.daily_item_title); 80 | title.setOnClickListener(new OnClickListener() { 81 | @Override public void onClick(View v) { 82 | RxBus.getInstance().post(new ClickEvent(ClickEvent.CLICK_TYPE_DAILY_TITLE,gankDaily)); 83 | } 84 | }); 85 | newTag = (ImageView) itemView.findViewById(R.id.daily_item_new_tag); 86 | } 87 | 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/ui/adapter/GankListAdapter.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.ui.adapter; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.CardView; 5 | import android.support.v7.widget.RecyclerView.Adapter; 6 | import android.support.v7.widget.RecyclerView.ViewHolder; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.widget.ImageView; 11 | import android.widget.TextView; 12 | import com.activeandroid.query.Select; 13 | import java.util.List; 14 | import me.wavever.ganklock.R; 15 | import me.wavever.ganklock.model.bean.Gank; 16 | import me.wavever.ganklock.ui.adapter.GankListAdapter.GankListHolder; 17 | import me.wavever.ganklock.ui.widget.ColorfulCircleView; 18 | 19 | /** 20 | * Created by wavever on 2016/3/5. 21 | */ 22 | public class GankListAdapter extends Adapter { 23 | 24 | private List mList; 25 | private Context mContext; 26 | private OnItemClickListener onItemClickListener; 27 | 28 | private final int ITEM_CATEGORY = 0; 29 | private final int ITEM_TITLE = 1; 30 | 31 | 32 | public GankListAdapter(Context context, List list) { 33 | mContext = context; 34 | mList = list; 35 | } 36 | 37 | 38 | public void setOnItemClickListener(GankListAdapter.OnItemClickListener onItemClickListener) { 39 | this.onItemClickListener = onItemClickListener; 40 | } 41 | 42 | 43 | @Override 44 | public GankListHolder onCreateViewHolder(ViewGroup parent, int viewType) { 45 | View view = LayoutInflater.from(parent.getContext()) 46 | .inflate(R.layout.item_gank_rv_content, parent, false); 47 | if (viewType == ITEM_CATEGORY) { 48 | return new GankListHolder(view, true); 49 | } else { 50 | return new GankListHolder(view, false); 51 | } 52 | } 53 | 54 | 55 | @Override public void onBindViewHolder(GankListHolder holder, int position) { 56 | Gank gank = mList.get(position); 57 | holder.setIsRecyclable(false); 58 | holder.gank = gank; 59 | holder.category.setText(gank.getType()); 60 | holder.ccv.setText(gank.getWho()); 61 | holder.who.setText(gank.getWho()); 62 | holder.desc.setText(gank.getDesc()); 63 | if (new Select().from(Gank.class).where("_id=?", gank.get_id()).exists()) { 64 | holder.like.setImageResource(R.drawable.ic_favorite_red_500_24dp); 65 | } 66 | } 67 | 68 | 69 | @Override public int getItemViewType(int position) { 70 | if (position == 0) { 71 | return ITEM_CATEGORY; 72 | } else { 73 | boolean isSame = mList.get(position - 1) 74 | .getType() 75 | .equals(mList.get(position).getType()); 76 | if (!isSame) { 77 | return ITEM_CATEGORY; 78 | } else { 79 | return ITEM_TITLE; 80 | } 81 | } 82 | } 83 | 84 | 85 | @Override public int getItemCount() { 86 | return mList.size(); 87 | } 88 | 89 | 90 | class GankListHolder extends ViewHolder implements View.OnClickListener { 91 | 92 | Gank gank; 93 | CardView cardView; 94 | TextView category; 95 | ColorfulCircleView ccv; 96 | TextView who; 97 | ImageView like; 98 | ImageView share; 99 | TextView desc; 100 | 101 | 102 | public GankListHolder(View itemView, boolean isShow) { 103 | super(itemView); 104 | cardView = (CardView) itemView.findViewById(R.id.item_gank_card_view); 105 | cardView.setOnClickListener(this); 106 | category = (TextView) itemView.findViewById(R.id.item_gank_category); 107 | ccv = (ColorfulCircleView) itemView.findViewById(R.id.item_gank_ccv); 108 | who = (TextView) itemView.findViewById(R.id.item_gank_who); 109 | like = (ImageView) itemView.findViewById(R.id.item_gank_like); 110 | like.setOnClickListener(this); 111 | share = (ImageView) itemView.findViewById(R.id.item_gank_share); 112 | share.setOnClickListener(this); 113 | desc = (TextView) itemView.findViewById(R.id.item_gank_desc); 114 | if (isShow) { 115 | category.setVisibility(View.VISIBLE); 116 | } else { 117 | category.setVisibility(View.GONE); 118 | } 119 | } 120 | 121 | 122 | @Override public void onClick(View v) { 123 | onItemClickListener.onItemClick(v, cardView, like, share, gank); 124 | } 125 | 126 | } 127 | 128 | 129 | public interface OnItemClickListener { 130 | void onItemClick(View view, View layout, ImageView like, ImageView share, Gank gank); 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/ui/adapter/LikeRecyclerViewAdapter.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.ui.adapter; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.RecyclerView.Adapter; 5 | import android.support.v7.widget.RecyclerView.ViewHolder; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.LinearLayout; 10 | import android.widget.TextView; 11 | import java.util.List; 12 | import me.wavever.ganklock.R; 13 | import me.wavever.ganklock.event.ClickEvent; 14 | import me.wavever.ganklock.event.RxBus; 15 | import me.wavever.ganklock.model.bean.Gank; 16 | import me.wavever.ganklock.ui.adapter.LikeRecyclerViewAdapter.LikeViewHolder; 17 | import me.wavever.ganklock.ui.widget.ColorfulCircleView; 18 | import me.wavever.ganklock.utils.DateUtil; 19 | 20 | /** 21 | * Created by waveverhon 2016/10/13. 22 | */ 23 | 24 | public class LikeRecyclerViewAdapter extends Adapter { 25 | 26 | private Context mContext; 27 | private List mList; 28 | 29 | public LikeRecyclerViewAdapter(Context context) { 30 | mContext = context; 31 | } 32 | 33 | 34 | public void setDataList(List list) { 35 | mList = list; 36 | } 37 | 38 | 39 | @Override 40 | public LikeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 41 | View view = LayoutInflater.from(parent.getContext()) 42 | .inflate(R.layout.item_like_rv, parent, false); 43 | return new LikeViewHolder(view); 44 | } 45 | 46 | 47 | @Override 48 | public void onBindViewHolder(LikeViewHolder holder, int position) { 49 | holder.position = position; 50 | holder.type.setText(mList.get(position).getType()); 51 | holder.ccv.setText(mList.get(position).getType()); 52 | holder.desc.setText(mList.get(position).getDesc()); 53 | holder.date.setText(DateUtil.formatDate(mList.get(position).getPublishedAt())); 54 | } 55 | 56 | 57 | @Override public int getItemCount() { 58 | return mList == null ? 0 : mList.size(); 59 | } 60 | 61 | 62 | class LikeViewHolder extends ViewHolder { 63 | 64 | LinearLayout layout; 65 | int position; 66 | ColorfulCircleView ccv; 67 | TextView type; 68 | TextView desc; 69 | TextView date; 70 | 71 | public LikeViewHolder(View itemView) { 72 | super(itemView); 73 | layout = (LinearLayout) itemView.findViewById(R.id.item_like_layout); 74 | layout.setOnClickListener(new View.OnClickListener() { 75 | @Override public void onClick(View v) { 76 | RxBus.getInstance().post(new ClickEvent(ClickEvent.CLICK_TYPE_LIKE,position)); 77 | } 78 | }); 79 | ccv = (ColorfulCircleView) itemView.findViewById(R.id.item_like_ccv); 80 | type = (TextView) itemView.findViewById(R.id.item_like_type); 81 | desc = (TextView) itemView.findViewById(R.id.item_like_desc); 82 | date = (TextView) itemView.findViewById(R.id.item_like_date); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/ui/adapter/MeizhiRecyclerViewAdapter.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.ui.adapter; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.RecyclerView.Adapter; 5 | import android.support.v7.widget.RecyclerView.ViewHolder; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.ImageView; 10 | import com.squareup.picasso.Picasso; 11 | import java.io.File; 12 | import java.util.List; 13 | import me.wavever.ganklock.R; 14 | import me.wavever.ganklock.event.ClickEvent; 15 | import me.wavever.ganklock.event.RxBus; 16 | import me.wavever.ganklock.ui.adapter.MeizhiRecyclerViewAdapter.MeizhiViewHolder; 17 | 18 | /** 19 | * Created by wavever on 2016/9/27. 20 | */ 21 | 22 | public class MeizhiRecyclerViewAdapter extends Adapter { 23 | 24 | private List mList; 25 | private Context mContext; 26 | 27 | public void setList(List list) { 28 | this.mList = list; 29 | } 30 | 31 | public MeizhiRecyclerViewAdapter(Context context){ 32 | mContext = context; 33 | } 34 | 35 | @Override 36 | public MeizhiViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 37 | View view = LayoutInflater.from(parent.getContext()) 38 | .inflate(R.layout.item_meizhi_recycler_view, parent, false); 39 | return new MeizhiViewHolder(view); 40 | } 41 | 42 | @Override 43 | public void onBindViewHolder(MeizhiViewHolder holder, int position) { 44 | holder.position = position; 45 | Picasso.with(mContext).load(mList.get(position)).resize(300,300).centerCrop().into(holder.img); 46 | } 47 | 48 | 49 | @Override public int getItemCount() { 50 | return mList == null ? 0 : mList.size(); 51 | } 52 | 53 | 54 | class MeizhiViewHolder extends ViewHolder { 55 | 56 | ImageView img; 57 | int position; 58 | 59 | public MeizhiViewHolder(View itemView) { 60 | super(itemView); 61 | img = (ImageView) itemView.findViewById(R.id.item_photo); 62 | img.setOnClickListener(new View.OnClickListener() { 63 | @Override public void onClick(View v) { 64 | RxBus.getInstance() 65 | .post(new ClickEvent(ClickEvent.CLICK_TYPE_MEIZHI, position)); 66 | } 67 | }); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/ui/fragment/BaseFragment.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.ui.fragment; 2 | 3 | 4 | import android.app.Activity; 5 | import android.app.Fragment; 6 | import android.content.Context; 7 | import android.os.Bundle; 8 | import android.view.LayoutInflater; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | import me.wavever.ganklock.presenter.BasePresenter; 12 | import me.wavever.ganklock.presenter.IPresenter; 13 | import rx.Subscription; 14 | 15 | /** 16 | * Created by wavever on 2016/8/12. 17 | */ 18 | public abstract class BaseFragment> extends Fragment implements IPresenter

{ 19 | 20 | protected P mPresenter = null; 21 | protected Activity mContext = null; 22 | protected Subscription mSubscrition = null; 23 | 24 | /** 25 | * 加载xml 26 | * @return xml的id 27 | */ 28 | protected abstract int loadView(); 29 | 30 | /** 31 | * 初始化View 32 | */ 33 | protected abstract void initView(); 34 | 35 | @Override 36 | public P getPresenter() { 37 | return mPresenter; 38 | } 39 | 40 | 41 | @Override 42 | public void onAttach(Context context) { 43 | super.onAttach(context); 44 | } 45 | 46 | @Override 47 | public void onCreate(Bundle savedInstanceState) { 48 | super.onCreate(savedInstanceState); 49 | if (mPresenter != null) { 50 | mPresenter.attachView((V) this); 51 | mPresenter.onFragmentLifeCreate(); 52 | } 53 | mContext = getActivity(); 54 | } 55 | 56 | @Override 57 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 58 | if (mPresenter == null) { 59 | mPresenter = createPresenter(); 60 | if(mPresenter!=null){ 61 | mPresenter.attachView((V) this); 62 | } 63 | } 64 | mPresenter.onFragmentLifeCreateView(); 65 | return inflater.inflate(loadView(), container, false); 66 | } 67 | 68 | @Override 69 | public void onActivityCreated(Bundle savedInstanceState) { 70 | super.onActivityCreated(savedInstanceState); 71 | if (mPresenter != null) { 72 | mPresenter.onFragmentLifeActivityCreated(); 73 | } 74 | initView(); 75 | } 76 | 77 | 78 | @Override 79 | public void onStart() { 80 | super.onStart(); 81 | if (mPresenter != null) { 82 | mPresenter.onFragmentLifeStart(); 83 | } 84 | } 85 | 86 | @Override 87 | public void onResume() { 88 | super.onResume(); 89 | if (mPresenter != null) { 90 | mPresenter.onFragmentLifeResume(); 91 | } 92 | } 93 | 94 | 95 | @Override 96 | public void onPause() { 97 | super.onPause(); 98 | if (mPresenter != null) { 99 | mPresenter.onFragmentLifePause(); 100 | } 101 | } 102 | 103 | @Override 104 | public void onStop() { 105 | super.onStop(); 106 | if (mPresenter != null) { 107 | mPresenter.onFragmentLifeStop(); 108 | } 109 | } 110 | 111 | @Override 112 | public void onDestroyView() { 113 | super.onDestroyView(); 114 | } 115 | 116 | @Override 117 | public void onDestroy() { 118 | super.onDestroy(); 119 | if (mPresenter != null) { 120 | mPresenter.onFragmentLifeDestory(); 121 | } 122 | if(mSubscrition!=null&&mSubscrition.isUnsubscribed()){ 123 | mSubscrition.unsubscribe(); 124 | } 125 | } 126 | 127 | @Override 128 | public void onDetach() { 129 | super.onDetach(); 130 | } 131 | 132 | 133 | } 134 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/ui/fragment/LikeFragment.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.ui.fragment; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.v7.widget.LinearLayoutManager; 6 | import android.support.v7.widget.RecyclerView; 7 | import android.view.View; 8 | import android.widget.ProgressBar; 9 | import android.widget.TextView; 10 | import com.activeandroid.query.Select; 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | import me.wavever.ganklock.R; 14 | import me.wavever.ganklock.event.ClickEvent; 15 | import me.wavever.ganklock.event.RxBus; 16 | import me.wavever.ganklock.model.bean.Gank; 17 | import me.wavever.ganklock.presenter.LikePresenter; 18 | import me.wavever.ganklock.ui.activity.WebViewActivity; 19 | import me.wavever.ganklock.ui.adapter.LikeRecyclerViewAdapter; 20 | import me.wavever.ganklock.utils.LogUtil; 21 | import me.wavever.ganklock.view.ILikeView; 22 | import rx.functions.Action1; 23 | 24 | /** 25 | * Created by wavever on 2016/8/12. 26 | */ 27 | public class LikeFragment extends BaseFragment implements ILikeView { 28 | 29 | private static final String TAG = LikeFragment.class.getSimpleName() + "-->"; 30 | 31 | private RecyclerView mRecyclerView; 32 | private LikeRecyclerViewAdapter mAdapter; 33 | private ProgressBar mProgressBar; 34 | private TextView mTips; 35 | private List mList; 36 | 37 | @Override 38 | protected int loadView() { 39 | return R.layout.fragment_like; 40 | } 41 | 42 | 43 | @Override 44 | protected void initView() { 45 | mRecyclerView = (RecyclerView) mContext.findViewById(R.id.recycler_view_like_fragment); 46 | mRecyclerView.setLayoutManager(new LinearLayoutManager(mContext)); 47 | mAdapter = new LikeRecyclerViewAdapter(mContext); 48 | mRecyclerView.setAdapter(mAdapter); 49 | mTips = (TextView) mContext.findViewById(R.id.empty_tip_like_fragment); 50 | mProgressBar = (ProgressBar) mContext.findViewById(R.id.progress_bar_like_fragment); 51 | mProgressBar.setVisibility(View.VISIBLE); 52 | mList = new ArrayList<>(); 53 | } 54 | 55 | 56 | @Override public void onActivityCreated(Bundle savedInstanceState) { 57 | super.onActivityCreated(savedInstanceState); 58 | loadLikeData(); 59 | LogUtil.d(TAG + "onActivityCreated执行"); 60 | mSubscrition = RxBus.getInstance().tObservable(ClickEvent.class).subscribe( 61 | new Action1() { 62 | @Override public void call(ClickEvent clickEvent) { 63 | if(clickEvent.eventType == ClickEvent.CLICK_TYPE_LIKE){ 64 | Intent intent = new Intent(mContext, WebViewActivity.class); 65 | intent.putExtra(WebViewActivity.KEY_TITLE, mList.get(clickEvent.position).getDesc()); 66 | intent.putExtra(WebViewActivity.KEY_URL, mList.get(clickEvent.position).getUrl()); 67 | startActivity(intent); 68 | } 69 | } 70 | }); 71 | } 72 | 73 | 74 | public void loadLikeData() { 75 | getPresenter().getLikeList(); 76 | } 77 | 78 | 79 | @Override 80 | public LikePresenter createPresenter() { 81 | return new LikePresenter(); 82 | } 83 | 84 | 85 | public void showLikeData(List list) { 86 | if(!mList.isEmpty()){ 87 | mList.clear(); 88 | } 89 | mList = list; 90 | mAdapter.setDataList(list); 91 | mAdapter.notifyDataSetChanged(); 92 | mProgressBar.setVisibility(View.GONE); 93 | mTips.setVisibility(View.GONE); 94 | } 95 | 96 | 97 | @Override public void refreshLikeData(List list) { 98 | } 99 | 100 | 101 | public void showEmptyTip() { 102 | mProgressBar.setVisibility(View.GONE); 103 | mTips.setVisibility(View.VISIBLE); 104 | } 105 | 106 | 107 | /** 108 | * 每次状态改变都会调用 109 | */ 110 | @Override public void onHiddenChanged(boolean hidden) { 111 | super.onHiddenChanged(hidden); 112 | if (!hidden) { 113 | LogUtil.d(TAG + "onHiddenChanged执行--》展示"); 114 | int dbCount = new Select().from(Gank.class).count(); 115 | if (mTips.getVisibility() == View.VISIBLE && dbCount > 0) {//此时的Like为空 116 | loadLikeData(); 117 | } else { 118 | if (dbCount > mAdapter.getItemCount()) { 119 | loadLikeData(); 120 | } 121 | } 122 | } else { 123 | LogUtil.d(TAG + "onHiddenChanged执行--》隐藏"); 124 | } 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/ui/fragment/MeizhiFragment.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.ui.fragment; 2 | 3 | import android.content.Intent; 4 | import android.support.v7.widget.GridLayoutManager; 5 | import android.support.v7.widget.RecyclerView; 6 | import android.view.View; 7 | import android.widget.ProgressBar; 8 | import android.widget.TextView; 9 | import java.io.File; 10 | import java.util.List; 11 | import me.wavever.ganklock.R; 12 | import me.wavever.ganklock.event.ClickEvent; 13 | import me.wavever.ganklock.event.RxBus; 14 | import me.wavever.ganklock.presenter.MeiZhiPresenter; 15 | import me.wavever.ganklock.ui.activity.PhotoActivity; 16 | import me.wavever.ganklock.ui.adapter.MeizhiRecyclerViewAdapter; 17 | import me.wavever.ganklock.view.IMeiZhiView; 18 | import rx.functions.Action1; 19 | 20 | /** 21 | * Created by wavever on 2016/8/12. 22 | */ 23 | public class MeizhiFragment extends BaseFragment 24 | implements IMeiZhiView { 25 | 26 | private static final String TAG = "MeizhiFragment-->"; 27 | private static int sClickCount; 28 | private RecyclerView mRecyclerView; 29 | private MeizhiRecyclerViewAdapter mAdapter; 30 | private TextView mEmptyTip; 31 | private ProgressBar mProgressBar; 32 | private List mList; 33 | 34 | @Override 35 | protected int loadView() { 36 | return R.layout.fragment_meizhi; 37 | } 38 | 39 | @Override 40 | protected void initView() { 41 | mRecyclerView = (RecyclerView) mContext.findViewById(R.id.recycler_view_meizhi_fragment); 42 | GridLayoutManager manager = new GridLayoutManager(mContext, 2); 43 | mRecyclerView.setLayoutManager(manager); 44 | mEmptyTip = (TextView) mContext.findViewById(R.id.empty_tip_meizhi_fragment); 45 | mProgressBar = (ProgressBar) mContext.findViewById(R.id.progress_bar_meizhi_fragment); 46 | mAdapter = new MeizhiRecyclerViewAdapter(mContext); 47 | mRecyclerView.setAdapter(mAdapter); 48 | mProgressBar.setVisibility(View.VISIBLE); 49 | getPresenter().loadMeizhi(); 50 | mSubscrition = RxBus.getInstance().tObservable(ClickEvent.class).subscribe( 51 | new Action1() { 52 | @Override public void call(ClickEvent clickEvent) { 53 | if (clickEvent.eventType == ClickEvent.CLICK_TYPE_MEIZHI) { 54 | Intent intent = new Intent(mContext, PhotoActivity.class); 55 | intent.putExtra(PhotoActivity.KEY_ACTIVITY_JUMPED, 56 | PhotoActivity.ACTIVITY_JUMPER_FROM_MEIZHI); 57 | intent.putExtra(PhotoActivity.KEY_PHOTO_URL, 58 | mList.get(clickEvent.position)); 59 | startActivity(intent); 60 | } 61 | } 62 | }); 63 | } 64 | 65 | @Override 66 | public MeiZhiPresenter createPresenter() { 67 | return new MeiZhiPresenter(); 68 | } 69 | 70 | @Override public void showMeizhi(List list) { 71 | mProgressBar.setVisibility(View.GONE); 72 | mEmptyTip.setVisibility(View.GONE); 73 | mList = list; 74 | mAdapter.setList(mList); 75 | mAdapter.notifyDataSetChanged(); 76 | } 77 | 78 | @Override public void showEmptyView() { 79 | mProgressBar.setVisibility(View.GONE); 80 | mEmptyTip.setVisibility(View.VISIBLE); 81 | } 82 | 83 | @Override public void showErrorView() { 84 | mProgressBar.setVisibility(View.GONE); 85 | mEmptyTip.setText("出问题了"); 86 | mEmptyTip.setVisibility(View.VISIBLE); 87 | } 88 | 89 | @Override public void onHiddenChanged(boolean hidden) { 90 | super.onHiddenChanged(hidden); 91 | if (!hidden) { 92 | sClickCount++; 93 | if (sClickCount % 2 == 0) { 94 | getPresenter().loadMeizhi(); 95 | } 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/ui/fragment/MoreFragment.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.ui.fragment; 2 | 3 | import android.app.Activity; 4 | import android.content.ActivityNotFoundException; 5 | import android.content.Intent; 6 | import android.net.Uri; 7 | import android.os.Build.VERSION; 8 | import android.support.v7.widget.SwitchCompat; 9 | import android.support.v7.widget.Toolbar; 10 | import android.view.View; 11 | import android.view.View.OnClickListener; 12 | import android.widget.CompoundButton; 13 | import android.widget.CompoundButton.OnCheckedChangeListener; 14 | import android.widget.TextView; 15 | import android.widget.Toast; 16 | import me.wavever.ganklock.MyApplication; 17 | import me.wavever.ganklock.R; 18 | import me.wavever.ganklock.config.Config; 19 | import me.wavever.ganklock.presenter.MorePresenter; 20 | import me.wavever.ganklock.service.LockService; 21 | import me.wavever.ganklock.ui.activity.AboutActivity; 22 | import me.wavever.ganklock.ui.activity.LicenseActivity; 23 | import me.wavever.ganklock.ui.activity.SettingActivity; 24 | import me.wavever.ganklock.utils.PreferenceUtil; 25 | import me.wavever.ganklock.utils.ToastUtil; 26 | import me.wavever.ganklock.view.IMoreView; 27 | 28 | /** 29 | * Created by wavever on 2016/9/18. 30 | */ 31 | 32 | public class MoreFragment extends BaseFragment implements OnClickListener { 33 | 34 | private TextView mTitle; 35 | private SwitchCompat mSwitch; 36 | private TextView mItemLockSetting, mItemStyleSetting, mItemFeedBack, mItemOpenSource, 37 | mItemEvaluate, mItemAbout; 38 | private Toolbar mToolbar; 39 | 40 | @Override protected int loadView() { 41 | return R.layout.fragment_more; 42 | } 43 | 44 | 45 | @Override protected void initView() { 46 | mToolbar = (Toolbar) mContext.findViewById(R.id.toolbar_more_fragment); 47 | mTitle = (TextView) mContext.findViewById(R.id.more_fragment_title); 48 | mItemLockSetting = (TextView) mContext.findViewById(R.id.more_fragment_item_lock_setting); 49 | mItemLockSetting.setOnClickListener(this); 50 | mItemStyleSetting = (TextView) mContext.findViewById(R.id.more_fragment_item_style_setting); 51 | mItemStyleSetting.setOnClickListener(this); 52 | mItemFeedBack = (TextView) mContext.findViewById(R.id.more_fragment_item_feedback); 53 | mItemFeedBack.setOnClickListener(this); 54 | mItemOpenSource = (TextView) mContext.findViewById(R.id.more_fragment_item_open_source); 55 | mItemOpenSource.setOnClickListener(this); 56 | mItemEvaluate = (TextView) mContext.findViewById(R.id.more_fragment_item_evaluate); 57 | mItemEvaluate.setOnClickListener(this); 58 | mItemAbout = (TextView) mContext.findViewById(R.id.more_fragment_item_about); 59 | mItemAbout.setOnClickListener(this); 60 | mSwitch = (SwitchCompat) mContext.findViewById(R.id.more_fragment_switch_button); 61 | mSwitch.setChecked(PreferenceUtil.getBoolean(Config.GANK_LOCK_IS_OPEN));//根据存储的布尔值来判断是否是开启状态 62 | mSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() { 63 | @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 64 | if (isChecked) { 65 | ToastUtil.showToastShort(mContext, "open锁屏"); 66 | PreferenceUtil.putBoolean(Config.GANK_LOCK_IS_OPEN, true); 67 | //LockManager.startLock(true);//立即显示锁屏 68 | MyApplication.getContext().startService(new Intent(MyApplication.getContext(), LockService.class)); 69 | } else { 70 | ToastUtil.showToastShort(mContext, "close锁屏"); 71 | PreferenceUtil.putBoolean(Config.GANK_LOCK_IS_OPEN, false); 72 | MyApplication.getContext().stopService(new Intent(MyApplication.getContext(), LockService.class)); 73 | //LockManager.cancleLock(); 74 | } 75 | } 76 | }); 77 | } 78 | 79 | 80 | @Override public MorePresenter createPresenter() { 81 | return new MorePresenter(); 82 | } 83 | 84 | 85 | @Override public void onClick(View v) { 86 | switch (v.getId()) { 87 | case R.id.more_fragment_item_lock_setting: 88 | startActivity(new Intent(mContext, SettingActivity.class)); 89 | break; 90 | case R.id.more_fragment_item_feedback: 91 | break; 92 | case R.id.more_fragment_item_open_source: 93 | startActivity(new Intent(mContext, LicenseActivity.class)); 94 | break; 95 | case R.id.more_fragment_item_evaluate: 96 | Uri uri = Uri.parse("market://details?id=" + mContext.getPackageName()); 97 | Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri); 98 | try { 99 | startActivity(goToMarket); 100 | } catch (ActivityNotFoundException e) { 101 | Toast.makeText(mContext, "Couldn't launch the market !", Toast.LENGTH_SHORT).show(); 102 | } 103 | break; 104 | case R.id.more_fragment_item_about: 105 | startActivity(new Intent(mContext, AboutActivity.class)); 106 | break; 107 | } 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/ui/fragment/SettingFragment.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.ui.fragment; 2 | 3 | import android.os.Bundle; 4 | import android.preference.Preference; 5 | import android.preference.PreferenceFragment; 6 | import com.activeandroid.query.Delete; 7 | import com.activeandroid.query.Select; 8 | import me.wavever.ganklock.R; 9 | import me.wavever.ganklock.model.bean.GankDaily; 10 | import me.wavever.ganklock.utils.ToastUtil; 11 | import rx.Observable; 12 | import rx.Subscriber; 13 | import rx.Subscription; 14 | import rx.functions.Action1; 15 | 16 | /** 17 | * Created by wavever on 2016/2/23. 18 | */ 19 | public class SettingFragment extends PreferenceFragment 20 | implements Preference.OnPreferenceChangeListener, 21 | Preference.OnPreferenceClickListener { 22 | 23 | private Subscription subscription; 24 | 25 | @Override 26 | public void onCreate(Bundle savedInstanceState) { 27 | super.onCreate(savedInstanceState); 28 | addPreferencesFromResource(R.xml.preferences); 29 | findPreference(getString(R.string.key_lock_style)).setOnPreferenceClickListener(this); 30 | findPreference(getString(R.string.key_shake_feed_back)).setOnPreferenceChangeListener(this); 31 | findPreference("key_clear_cache").setOnPreferenceClickListener(this); 32 | } 33 | 34 | 35 | @Override 36 | public boolean onPreferenceChange(Preference preference, Object newValue) { 37 | String key = preference.getKey(); 38 | if (key.equals(getString(R.string.key_shake_feed_back))) { 39 | if ((Boolean) newValue) { 40 | } else { 41 | } 42 | } 43 | return true; 44 | } 45 | 46 | @Override 47 | public boolean onPreferenceClick(Preference preference) { 48 | String key = preference.getKey(); 49 | if (key.equals(getString(R.string.key_clear_cache))) { 50 | Observable.create(new Observable.OnSubscribe() { 51 | @Override public void call(Subscriber subscriber) { 52 | new Delete().from(GankDaily.class).execute(); 53 | subscriber.onNext(new Select().from(GankDaily.class).count()); 54 | } 55 | }).subscribe(new Action1() { 56 | @Override public void call(Integer count) { 57 | if (count == 0) { 58 | ToastUtil.showToastShort(getActivity(), "清除缓存成功~"); 59 | } else { 60 | ToastUtil.showToastShort(getActivity(), "清除缓存失败~"); 61 | } 62 | } 63 | }); 64 | } else if (key.equals(getString(R.string.key_lock_style))) { 65 | ToastUtil.showToastShort(getActivity(), "正在开发中哦"); 66 | } 67 | return false; 68 | } 69 | 70 | 71 | @Override public void onDestroy() { 72 | super.onDestroy(); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/ui/widget/RatioImageView.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 XiNGRZ 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.wavever.ganklock.ui.widget; 18 | 19 | import android.content.Context; 20 | import android.util.AttributeSet; 21 | import android.widget.ImageView; 22 | 23 | /** 24 | * 一个能保持比例的 ImageView 25 | * TODO: 暂时只支持维持宽度适应高度 26 | * 27 | * @author XiNGRZ 28 | */ 29 | public class RatioImageView extends ImageView { 30 | 31 | private int originalWidth; 32 | private int originalHeight; 33 | 34 | public RatioImageView(Context context) { 35 | super(context); 36 | } 37 | 38 | public RatioImageView(Context context, AttributeSet attrs) { 39 | super(context, attrs); 40 | } 41 | 42 | public RatioImageView(Context context, AttributeSet attrs, int defStyleAttr) { 43 | super(context, attrs, defStyleAttr); 44 | } 45 | 46 | public void setOriginalSize(int originalWidth, int originalHeight) { 47 | this.originalWidth = originalWidth; 48 | this.originalHeight = originalHeight; 49 | } 50 | 51 | @Override 52 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 53 | if (originalWidth > 0 && originalHeight > 0) { 54 | float ratio = (float) originalWidth / (float) originalHeight; 55 | 56 | int width = MeasureSpec.getSize(widthMeasureSpec); 57 | int height = MeasureSpec.getSize(heightMeasureSpec); 58 | 59 | // TODO: 现在只支持固定宽度 60 | if (width > 0) { 61 | height = (int) ((float) width / ratio); 62 | } 63 | 64 | setMeasuredDimension(width, height); 65 | } else { 66 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 67 | } 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/ui/widget/SwipeUnLockLayout.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.ui.widget; 2 | 3 | import android.animation.Animator; 4 | import android.animation.AnimatorListenerAdapter; 5 | import android.animation.AnimatorSet; 6 | import android.animation.ObjectAnimator; 7 | import android.content.Context; 8 | import android.util.AttributeSet; 9 | import android.view.MotionEvent; 10 | import android.view.View; 11 | import android.widget.FrameLayout; 12 | import me.wavever.ganklock.R; 13 | 14 | /** 15 | * Created by wavever on 2016/10/11. 16 | */ 17 | 18 | public class SwipeUnLockLayout extends FrameLayout { 19 | 20 | private static final int MIN_FLING_VELOCITY = 200; 21 | 22 | //TODO 只能够移动他的直接子View 23 | private View mTimeLayout; 24 | private View mArrow; 25 | 26 | private int mLastInterceptX; 27 | 28 | private float mStartX; 29 | private int mLayoutX; 30 | private int mArrowX; 31 | private float minVel; 32 | 33 | private OnSwipeListener mOnSwipeListener; 34 | 35 | public SwipeUnLockLayout(Context context) { 36 | this(context, null); 37 | } 38 | 39 | 40 | public SwipeUnLockLayout(Context context, AttributeSet attrs) { 41 | this(context, attrs, 0); 42 | } 43 | 44 | 45 | public SwipeUnLockLayout(Context context, AttributeSet attrs, int defStyleAttr) { 46 | super(context, attrs, defStyleAttr); 47 | init(context); 48 | } 49 | 50 | 51 | private void init(Context context) { 52 | final float density = getResources().getDisplayMetrics().density; 53 | minVel = MIN_FLING_VELOCITY * density; 54 | } 55 | 56 | 57 | public void setOnSwipeListener(OnSwipeListener onSwipeListener) { 58 | this.mOnSwipeListener = onSwipeListener; 59 | } 60 | 61 | @Override public boolean onInterceptTouchEvent(MotionEvent ev) { 62 | boolean intercepted = false; 63 | int x = (int) ev.getX(); 64 | switch (ev.getAction()){ 65 | case MotionEvent.ACTION_DOWN: 66 | mLastInterceptX = x; 67 | intercepted = false; 68 | break; 69 | case MotionEvent.ACTION_MOVE: 70 | if(x==mLastInterceptX){ 71 | intercepted = false; 72 | }else { 73 | intercepted = true; 74 | } 75 | break; 76 | case MotionEvent.ACTION_UP: 77 | intercepted = false; 78 | break; 79 | default: 80 | break; 81 | } 82 | 83 | return intercepted; 84 | } 85 | 86 | 87 | @Override public boolean onTouchEvent(MotionEvent event) { 88 | 89 | float x = event.getX(); 90 | 91 | switch (event.getAction()){ 92 | case MotionEvent.ACTION_DOWN: 93 | mStartX = x; 94 | break; 95 | case MotionEvent.ACTION_MOVE: 96 | float moveX= x - mStartX; 97 | if (moveX < 0) 98 | moveX = 0; 99 | mTimeLayout.setTranslationX(-moveX); 100 | mArrow.setTranslationX(moveX); 101 | break; 102 | case MotionEvent.ACTION_UP: 103 | float moveX1= x - mStartX; 104 | ObjectAnimator animator1; 105 | ObjectAnimator animator2; 106 | AnimatorSet set = new AnimatorSet(); 107 | if(moveX1 > minVel){ 108 | animator1 = ObjectAnimator.ofFloat(mTimeLayout,"translationX",-200); 109 | animator2 = ObjectAnimator.ofFloat(mArrow,"translationX",-200); 110 | set.setDuration(250).playTogether(animator1,animator2); 111 | set.addListener(new AnimatorListenerAdapter() { 112 | @Override public void onAnimationEnd(Animator animation) { 113 | mOnSwipeListener.onSwipeFinish(); 114 | } 115 | }); 116 | }else{ 117 | animator1 = ObjectAnimator.ofFloat(mTimeLayout,"translationX",mLayoutX); 118 | animator2 = ObjectAnimator.ofFloat(mArrow,"translationX",-mArrowX); 119 | set.setDuration(250).playTogether(animator1,animator2); 120 | } 121 | set.start(); 122 | break; 123 | case MotionEvent.ACTION_CANCEL: 124 | break; 125 | } 126 | return true; 127 | } 128 | 129 | 130 | @Override protected void onFinishInflate() { 131 | super.onFinishInflate(); 132 | mTimeLayout = findViewById(R.id.lock_view_time_layout); 133 | mArrow = findViewById(R.id.lock_view_arrow); 134 | } 135 | 136 | 137 | @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 138 | super.onLayout(changed, left, top, right, bottom); 139 | //记录初始的位置 140 | mLayoutX = mTimeLayout.getLeft(); 141 | mArrowX = mArrow.getLeft(); 142 | } 143 | 144 | public interface OnSwipeListener{ 145 | void onSwipeFinish(); 146 | } 147 | 148 | 149 | } 150 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/ui/widget/UnlockArrow.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.ui.widget; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.graphics.Color; 6 | import android.graphics.Paint; 7 | import android.graphics.Path; 8 | import android.util.AttributeSet; 9 | import android.view.View; 10 | 11 | import me.wavever.ganklock.R; 12 | 13 | /** 14 | * Created by wavevr on 2016/2/20. 15 | */ 16 | public class UnlockArrow extends View { 17 | 18 | private int width; 19 | private int height; 20 | private int strokeWidth; 21 | private Paint paint; 22 | private Path path; 23 | 24 | public UnlockArrow(Context context) { 25 | this(context, null); 26 | } 27 | 28 | public UnlockArrow(Context context, AttributeSet attrs) { 29 | this(context, attrs, 0); 30 | } 31 | 32 | 33 | public UnlockArrow(Context context, AttributeSet attrs, int defStyleAttr) { 34 | super(context, attrs, defStyleAttr); 35 | init(context); 36 | } 37 | 38 | 39 | private void init(Context context) { 40 | paint = new Paint(); 41 | path = new Path(); 42 | strokeWidth = context.getResources().getDimensionPixelSize(R.dimen.unlock_arrow_stroke_width); 43 | width = context.getResources().getDimensionPixelSize(R.dimen.unlock_arrow_width); 44 | height = context.getResources().getDimensionPixelSize(R.dimen.unlock_arrow_height); 45 | paint.setStrokeJoin(Paint.Join.ROUND); 46 | paint.setStrokeCap(Paint.Cap.ROUND); 47 | paint.setStrokeWidth((float) this.strokeWidth); 48 | paint.setStyle(Paint.Style.STROKE); 49 | paint.setAntiAlias(true); 50 | paint.setColor(Color.WHITE); 51 | } 52 | 53 | @Override 54 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 55 | 56 | setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec)); 57 | 58 | } 59 | 60 | private int measureWidth(int widthMeasureSpec) { 61 | int result = 0; 62 | int width = MeasureSpec.getSize(widthMeasureSpec); 63 | int mode = MeasureSpec.getMode(widthMeasureSpec); 64 | if(mode == MeasureSpec.EXACTLY){ 65 | result = width; 66 | }else{ 67 | if(mode == MeasureSpec.AT_MOST){ 68 | result = this.width+strokeWidth; 69 | } 70 | } 71 | return result; 72 | } 73 | 74 | private int measureHeight(int heightMeasureSpec) { 75 | int result = 0; 76 | int height = MeasureSpec.getSize(heightMeasureSpec); 77 | int mode = MeasureSpec.getMode(heightMeasureSpec); 78 | if(mode == MeasureSpec.EXACTLY){ 79 | result = height; 80 | }else{ 81 | if(mode == MeasureSpec.AT_MOST){ 82 | result = this.height+strokeWidth; 83 | } 84 | } 85 | return result; 86 | } 87 | 88 | @Override 89 | protected void onDraw(Canvas canvas) { 90 | super.onDraw(canvas); 91 | path.reset(); 92 | path.moveTo(0, 0); 93 | path.lineTo(width, height / 2); 94 | path.lineTo(0, height); 95 | canvas.drawPath(path, paint); 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/ui/widget/UnlockArrowHolder.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.ui.widget; 2 | 3 | import android.animation.AnimatorSet; 4 | import android.animation.FloatEvaluator; 5 | import android.animation.ObjectAnimator; 6 | import android.animation.ValueAnimator; 7 | import android.content.Context; 8 | import android.util.AttributeSet; 9 | import android.view.animation.LinearInterpolator; 10 | import android.widget.RelativeLayout; 11 | 12 | import me.wavever.ganklock.R; 13 | 14 | /** 15 | * Created by wavever on 2016/5/25. 16 | */ 17 | public class UnlockArrowHolder extends RelativeLayout { 18 | 19 | private ValueAnimator valueAnimator = null; 20 | private AnimatorSet animationSet = null; 21 | private UnlockArrow[] arrows = null; 22 | private int animationDistance = 0;//滑动箭头做动画的距离 23 | private int arrowGap = 0;//箭头之间的距离 24 | 25 | public UnlockArrowHolder(Context context) { 26 | super(context); 27 | init(context); 28 | } 29 | 30 | public UnlockArrowHolder(Context context, AttributeSet attrs) { 31 | super(context, attrs); 32 | init(context); 33 | } 34 | 35 | public UnlockArrowHolder(Context context, AttributeSet attrs, int defStyleAttr) { 36 | super(context, attrs, defStyleAttr); 37 | init(context); 38 | } 39 | 40 | private void init(Context context) { 41 | animationDistance = (int) context.getResources().getDimension(R.dimen.unlock_arrow_animation_distance); 42 | arrowGap = context.getResources().getDimensionPixelSize(R.dimen.unlock_arrow_gap); 43 | arrows = new UnlockArrow[3]; 44 | for (int i = 0; i < 3; i++) { 45 | arrows[i] = new UnlockArrow(getContext()); 46 | addView(arrows[i]); 47 | arrows[i].setAlpha(0.0f); 48 | } 49 | animationSet = new AnimatorSet(); 50 | animationSet.setInterpolator(new LinearInterpolator()); 51 | float f = animationDistance * 2 + arrowGap * 2; //总共的距离 52 | valueAnimator = ObjectAnimator.ofObject(new ArrowEvaluator(this), new Object[]{Integer.valueOf(0), Float.valueOf(f)}).setDuration(1680); 53 | valueAnimator.setRepeatCount(ValueAnimator.INFINITE); 54 | animationSet.play(valueAnimator); 55 | } 56 | 57 | public class ArrowEvaluator extends FloatEvaluator { 58 | 59 | private final UnlockArrowHolder unlockArrowHolder; 60 | 61 | public ArrowEvaluator(UnlockArrowHolder unlockArrowHolder) { 62 | this.unlockArrowHolder = unlockArrowHolder; 63 | } 64 | 65 | @Override 66 | public Float evaluate(float fraction, Number startValue, Number endValue) { 67 | 68 | float startFloat = startValue.floatValue(); 69 | float float2 = startFloat + ((endValue.floatValue() - startFloat) * fraction);//当前动画的完成度 70 | for (int i = 0; i < 3; i++) { 71 | float s = float2 - arrowGap * i; 72 | if (s > animationDistance * 2) { 73 | s = animationDistance * 2; 74 | } 75 | arrows[i].setTranslationX(s); 76 | arrows[i].setAlpha(s > animationDistance ? 77 | ((animationDistance * 2 - s) / (animationDistance * 1.0f)) : animationDistance * 1.0f); 78 | } 79 | return Float.valueOf((endValue.floatValue() - startFloat) * fraction + startFloat); 80 | } 81 | } 82 | 83 | @Override 84 | protected void onAttachedToWindow() { 85 | startAnim(); 86 | super.onAttachedToWindow(); 87 | } 88 | 89 | public void startAnim() { 90 | setVisibility(VISIBLE); 91 | for (int i = 0; i < 3; i++) { 92 | arrows[i].setLayerType(LAYER_TYPE_HARDWARE, null); 93 | } 94 | animationSet.start(); 95 | } 96 | 97 | public void stopAnim() { 98 | setVisibility(GONE); 99 | for (int i = 0; i < 3; i++) { 100 | arrows[i].setLayerType(LAYER_TYPE_NONE, null); 101 | } 102 | animationSet.cancel();//set会遍历子Animator调用cancel方法 103 | } 104 | 105 | @Override 106 | protected void onDetachedFromWindow() { 107 | stopAnim(); 108 | super.onDetachedFromWindow(); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/utils/DialogUtil.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.utils; 2 | 3 | import android.app.ProgressDialog; 4 | import android.content.Context; 5 | import android.support.v7.app.AlertDialog; 6 | 7 | import me.wavever.ganklock.R; 8 | 9 | /** 10 | * Created by wavever on 2016/2/22. 11 | */ 12 | public class DialogUtil { 13 | 14 | private static ProgressDialog progressDialog; 15 | 16 | public static void showSingleBUttonDialog(Context context, String msg) { 17 | new AlertDialog.Builder(context) 18 | .setCancelable(true) 19 | .setMessage(msg) 20 | .setTitle(R.string.dialog_tip) 21 | .setPositiveButton(R.string.dialog_confirm,null) 22 | .show(); 23 | } 24 | 25 | public static void showSingleDialog(Context context, int msgId) { 26 | showSingleBUttonDialog(context,context.getResources().getString(msgId)); 27 | } 28 | 29 | public static void showLoadingDialog(Context context){ 30 | progressDialog = new ProgressDialog(context); 31 | progressDialog.setMessage("主人别急,正在加载"); 32 | progressDialog.show(); 33 | } 34 | 35 | public static void dismissLoadingDialog(){ 36 | if (progressDialog != null){ 37 | progressDialog.dismiss(); 38 | } 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/utils/LogUtil.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.utils; 2 | 3 | import android.util.Log; 4 | 5 | /** 6 | * Created by WAVE on 2016/2/23. 7 | */ 8 | public class LogUtil { 9 | 10 | private static final String TAG = "TAG"; 11 | 12 | public static final int VERBOSE = 1; 13 | 14 | public static final int DEBUG = 2; 15 | 16 | public static final int INFO = 3; 17 | 18 | public static final int WRAN = 4; 19 | 20 | public static final int ERROR = 5; 21 | 22 | public static final int NOTHING = 6; 23 | 24 | public static final int LEVEL = VERBOSE; 25 | 26 | //只需要修改LEVEL的值,就可以自由的控制日志的打印, 27 | // 当LEVEL为NOTHING时,就可以屏蔽掉所有的日志 28 | 29 | public static void v(String message) { 30 | if (LEVEL <= VERBOSE) { 31 | Log.v(TAG, message); 32 | } 33 | } 34 | 35 | public static void d(String message) { 36 | if (LEVEL <= DEBUG) { 37 | Log.d(TAG,message); 38 | } 39 | } 40 | 41 | public static void i(String message) { 42 | if (LEVEL <= INFO) { 43 | Log.i(TAG,message); 44 | } 45 | } 46 | 47 | public static void w(String message) { 48 | if (LEVEL <= WRAN) { 49 | Log.w(TAG,message); 50 | } 51 | } 52 | 53 | public static void e(String message) { 54 | if (LEVEL <= ERROR) { 55 | Log.e(TAG,message); 56 | } 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/utils/PreferenceUtil.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.utils; 2 | 3 | import android.content.SharedPreferences; 4 | import android.content.SharedPreferences.Editor; 5 | import android.preference.PreferenceManager; 6 | import me.wavever.ganklock.MyApplication; 7 | 8 | public class PreferenceUtil { 9 | private static SharedPreferences prefs; 10 | private static Editor editor; 11 | 12 | 13 | static { 14 | prefs = PreferenceManager.getDefaultSharedPreferences(MyApplication.getContext()); 15 | editor = prefs.edit(); 16 | } 17 | 18 | 19 | public static void putString(String key, String value) { 20 | editor.putString(key, value).apply(); 21 | } 22 | 23 | 24 | public static String getString(String key) { 25 | return prefs.getString(key, ""); 26 | } 27 | 28 | 29 | public static void putInt(String key, int value) { 30 | editor.putInt(key, value).apply(); 31 | } 32 | 33 | 34 | public static int getInt(String key,int value) { 35 | return prefs.getInt(key, value); 36 | } 37 | 38 | 39 | public static void putBoolean(String key, boolean value) { 40 | editor.putBoolean(key, value).apply();//apply没有返回值,commit返回值为布尔值 41 | } 42 | 43 | public static boolean getBoolean(String key) { 44 | return prefs.getBoolean(key, false); 45 | } 46 | 47 | 48 | public static boolean clear() { 49 | editor.clear(); 50 | return editor.commit(); 51 | } 52 | 53 | 54 | public static void close() { 55 | prefs = null; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/utils/StringUtil.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 me.wavever.ganklock.utils; 21 | 22 | import android.content.Context; 23 | import android.content.pm.ApplicationInfo; 24 | import android.content.pm.PackageManager; 25 | import android.content.res.AssetManager; 26 | import android.graphics.Typeface; 27 | import me.wavever.ganklock.MyApplication; 28 | 29 | public class StringUtil { 30 | 31 | public static AssetManager assetManager = MyApplication.getContext().getAssets(); 32 | 33 | public static Typeface getTypeFace(String fontName) { 34 | return Typeface.createFromAsset(MyApplication.getContext().getAssets(), 35 | "fonts/" + fontName); 36 | } 37 | 38 | public static String getChannelValue(){ 39 | Context context = MyApplication.getContext(); 40 | String value = ""; 41 | try { 42 | ApplicationInfo info = context.getPackageManager().getApplicationInfo(context.getPackageName(), 43 | PackageManager.GET_META_DATA); 44 | value = info.metaData.getString("UMENG_CHANNEL"); 45 | } catch (PackageManager.NameNotFoundException e) { 46 | e.printStackTrace(); 47 | } 48 | return value; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/utils/SystemUtil.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.utils; 2 | 3 | import android.content.Context; 4 | import android.net.ConnectivityManager; 5 | import android.net.NetworkInfo; 6 | import me.wavever.ganklock.MyApplication; 7 | 8 | /** 9 | * Created by wavever on 2016/9/20. 10 | */ 11 | 12 | public class SystemUtil { 13 | 14 | /** 15 | * 网络是否可用 16 | */ 17 | public static boolean isNetworkAvailable() { 18 | ConnectivityManager manager = (ConnectivityManager) MyApplication.getContext() 19 | .getSystemService(Context.CONNECTIVITY_SERVICE); 20 | NetworkInfo info = manager.getActiveNetworkInfo(); 21 | if (info != null) { 22 | return info.isAvailable(); 23 | } 24 | return false; 25 | } 26 | 27 | 28 | /** 29 | * 获取当前网络状态:WiFi OR Mobile 30 | * @return if wifi return 1 or mobile return 1 31 | */ 32 | public static int getNetType() { 33 | ConnectivityManager manager = (ConnectivityManager) MyApplication.getContext() 34 | .getSystemService(Context.CONNECTIVITY_SERVICE); 35 | if (manager != null) { 36 | NetworkInfo info = manager.getActiveNetworkInfo(); 37 | if (info != null && info.isConnected()) { 38 | if (info.getState() == NetworkInfo.State.CONNECTED) { 39 | if (info.getType() == ConnectivityManager.TYPE_WIFI) { 40 | return 1;//wifi 41 | } else if (info.getType() == ConnectivityManager.TYPE_MOBILE) { 42 | return 0;//mobile 43 | } 44 | } 45 | } 46 | } 47 | return -1; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/utils/ToastUtil.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.utils; 2 | 3 | import android.content.Context; 4 | import android.widget.Toast; 5 | 6 | /** 7 | * Created by wavever on 2016/8/14. 8 | */ 9 | public class ToastUtil { 10 | 11 | private static Toast sToast; 12 | 13 | public static void showToastShort(Context context, String content) { 14 | if (sToast == null) { 15 | sToast = Toast.makeText(context, content, Toast.LENGTH_SHORT); 16 | } else { 17 | sToast.setText(content); 18 | } 19 | sToast.show(); 20 | } 21 | 22 | public static void showToastLong(Context context, String content) { 23 | if (sToast == null) { 24 | sToast = Toast.makeText(context, content, Toast.LENGTH_LONG); 25 | } else { 26 | sToast.setText(content); 27 | } 28 | sToast.show(); 29 | } 30 | 31 | public static void showToastShort(Context context, int resId) { 32 | showToastShort(context, context.getResources().getString(resId)); 33 | } 34 | 35 | public static void showToastLong(Context context, int resId) { 36 | showToastLong(context, context.getResources().getString(resId)); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/utils/UIUtil.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.utils; 2 | 3 | import android.content.Context; 4 | import android.util.DisplayMetrics; 5 | import android.util.TypedValue; 6 | import android.view.KeyCharacterMap; 7 | import android.view.KeyEvent; 8 | import android.view.ViewConfiguration; 9 | import android.view.WindowManager; 10 | 11 | import me.wavever.ganklock.MyApplication; 12 | 13 | /** 14 | * Created by wavever on 2016/3/10. 15 | */ 16 | public class UIUtil { 17 | 18 | public static int[] getScreenSize() { 19 | DisplayMetrics metrics = new DisplayMetrics(); 20 | WindowManager windowManager 21 | = (WindowManager) MyApplication.getContext() 22 | .getSystemService( 23 | Context.WINDOW_SERVICE); 24 | windowManager.getDefaultDisplay().getMetrics(metrics); 25 | return new int[]{metrics.widthPixels, metrics.heightPixels}; 26 | } 27 | 28 | 29 | public static int dp2px(int dp, Context context) { 30 | return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 31 | dp, context.getResources().getDisplayMetrics()); 32 | } 33 | 34 | public static int sp2px(int sp,Context context) { 35 | return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 36 | sp, context.getResources().getDisplayMetrics()); 37 | } 38 | 39 | /** 40 | * 获取状态栏高度 41 | * 42 | * @param context 43 | * @return 44 | */ 45 | public static int getStatusHeight(Context context) { 46 | int statusHeight = -1; 47 | try { 48 | Class clazz = Class.forName("com.android.internal.R$dimen");//com.android.internal.R.dimen 49 | Object object = clazz.newInstance(); 50 | int height = Integer.parseInt(clazz.getField("status_bar_height").get(object).toString()); 51 | statusHeight = context.getResources().getDimensionPixelSize(height); 52 | } catch (Exception e) { 53 | e.printStackTrace(); 54 | } 55 | return statusHeight; 56 | } 57 | 58 | 59 | 60 | /** 61 | * 通过是否有物理按键来确定是否有虚拟按键 62 | * 63 | * @return 64 | */ 65 | public static boolean isHasNavigationBar(Context context) { 66 | boolean hasMenuKey = ViewConfiguration.get(context).hasPermanentMenuKey(); 67 | boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK); 68 | return !(hasBackKey && hasMenuKey); 69 | } 70 | 71 | 72 | } 73 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/view/IBaseView.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.view; 2 | 3 | 4 | /** 5 | * Created by WAVE on 2016/3/4. 6 | */ 7 | public interface IBaseView{ 8 | 9 | } 10 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/view/IDailyGankView.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.view; 2 | 3 | 4 | import java.util.List; 5 | import me.wavever.ganklock.model.bean.GankDaily; 6 | 7 | /** 8 | * Created by wavever on 2016/8/14. 9 | */ 10 | public interface IDailyGankView extends IBaseView{ 11 | void showLoading(); 12 | void loadDailyData(int page); 13 | void loadFailure(); 14 | void loadTodayDailyData(); 15 | void showDailyData(List ganks); 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/view/IGankContentView.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.view; 2 | 3 | import java.util.List; 4 | import me.wavever.ganklock.model.bean.Gank; 5 | 6 | /** 7 | * Created by wavever on 2016/2/22. 8 | */ 9 | public interface IGankContentView extends IBaseView { 10 | 11 | void loadData(String date); 12 | void showData(List list); 13 | void showError(); 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/view/ILikeView.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.view; 2 | 3 | import java.util.List; 4 | import me.wavever.ganklock.model.bean.Gank; 5 | 6 | /** 7 | * Created by wavever on 2016/9/2. 8 | */ 9 | public interface ILikeView extends IBaseView{ 10 | void showEmptyTip(); 11 | void showLikeData(List list); 12 | void refreshLikeData(List list); 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/view/ILockView.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.view; 2 | 3 | public interface ILockView extends IBaseView { 4 | } 5 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/view/IMeiZhiView.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.view; 2 | 3 | import java.io.File; 4 | import java.util.List; 5 | 6 | /** 7 | * Created by wavever on 2016/9/2. 8 | */ 9 | public interface IMeiZhiView extends IBaseView{ 10 | 11 | void showMeizhi(List list); 12 | void showEmptyView(); 13 | void showErrorView(); 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/view/IMoreView.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.view; 2 | 3 | /** 4 | * Created by wavever on 2016/9/18. 5 | */ 6 | 7 | public interface IMoreView{ 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/me/wavever/ganklock/view/IWebView.java: -------------------------------------------------------------------------------- 1 | package me.wavever.ganklock.view; 2 | 3 | /** 4 | * Created by wavever on 2016/10/18. 5 | */ 6 | 7 | public interface IWebView extends IBaseView{ 8 | 9 | } 10 | -------------------------------------------------------------------------------- /app/src/main/res/color/selector_primary_click.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_settings_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wavever/GankLock/cf8f53cea137c302d069346efb5744ca29633ba3/app/src/main/res/drawable-hdpi/ic_settings_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_card_48dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wavever/GankLock/cf8f53cea137c302d069346efb5744ca29633ba3/app/src/main/res/drawable-xhdpi/ic_card_48dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_check_white_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wavever/GankLock/cf8f53cea137c302d069346efb5744ca29633ba3/app/src/main/res/drawable-xhdpi/ic_check_white_18dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_favorite_grey_500_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wavever/GankLock/cf8f53cea137c302d069346efb5744ca29633ba3/app/src/main/res/drawable-xhdpi/ic_favorite_grey_500_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_favorite_red_500_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wavever/GankLock/cf8f53cea137c302d069346efb5744ca29633ba3/app/src/main/res/drawable-xhdpi/ic_favorite_red_500_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_share_grey_500_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wavever/GankLock/cf8f53cea137c302d069346efb5744ca29633ba3/app/src/main/res/drawable-xhdpi/ic_share_grey_500_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/empty_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wavever/GankLock/cf8f53cea137c302d069346efb5744ca29633ba3/app/src/main/res/drawable-xxhdpi/empty_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/l_new_tip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wavever/GankLock/cf8f53cea137c302d069346efb5744ca29633ba3/app/src/main/res/drawable-xxhdpi/l_new_tip.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/test_image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wavever/GankLock/cf8f53cea137c302d069346efb5744ca29633ba3/app/src/main/res/drawable-xxhdpi/test_image.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_cloud_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wavever/GankLock/cf8f53cea137c302d069346efb5744ca29633ba3/app/src/main/res/drawable-xxxhdpi/ic_cloud_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_format_list_numbered_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wavever/GankLock/cf8f53cea137c302d069346efb5744ca29633ba3/app/src/main/res/drawable-xxxhdpi/ic_format_list_numbered_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_portrait_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wavever/GankLock/cf8f53cea137c302d069346efb5744ca29633ba3/app/src/main/res/drawable-xxxhdpi/ic_portrait_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_star_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wavever/GankLock/cf8f53cea137c302d069346efb5744ca29633ba3/app/src/main/res/drawable-xxxhdpi/ic_star_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_card_nopic.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_more_fragment_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/daily_mask.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/lock_date_mask.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/more_item_line_divider.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_pick_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/toolbar_shadow_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_gank_content.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 14 | 15 | 20 | 21 | 28 | 29 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_lock.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 15 | 16 | 23 | 24 | 31 | 32 | 38 | 39 | 47 | 48 | 55 | 56 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 12 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_photo.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 14 | 15 | 23 | 24 | 31 | 32 | 39 | 40 | 41 | 42 | 53 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_setting.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_web_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 14 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_daily.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 14 | 15 | 22 | 23 | 24 | 25 | 28 | 29 | 36 | 37 | 44 | 45 | 52 | 53 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_license.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_like.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 15 | 16 | 24 | 25 | 26 | 29 | 30 | 34 | 35 | 42 | 43 | 50 | 51 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_meizhi.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 14 | 15 | 23 | 24 | 25 | 28 | 29 | 34 | 35 | 42 | 43 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_daily_recycler_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 24 | 25 | 31 | 32 | 36 | 37 | 42 | 49 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_gank_rv_content.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 17 | 18 | 30 | 31 | 34 | 45 | 46 | 54 | 55 | 62 | 63 | 64 | 72 | 73 | 81 | 82 | 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_like_rv.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 23 | 24 | 29 | 30 | 37 | 38 | 49 | 50 | 61 | 62 | 68 | 69 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_meizhi_recycler_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_lock_time.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 16 | 24 |