28 |
29 | ### 欢迎关注个人微信公众号,将会定期推送优质技术文章,求关注
30 |
31 | 
32 |
33 | ### 声明
34 |
35 | 【乐享】仅作学习交流之用,数据来源于`开眼视频`、`图虫摄影`、`知乎日报`,数据接口均属于非正常渠道获取,请勿用于商业用途,原作公司拥有所有权利,如若涉及侵权,请联系删除。
36 |
37 | License
38 | --
39 | Copyright (C) 2016 xhb_199409@163.com
40 |
41 | Licensed under the Apache License, Version 2.0 (the "License");
42 | you may not use this file except in compliance with the License.
43 | You may obtain a copy of the License at
44 |
45 | http://www.apache.org/licenses/LICENSE-2.0
46 |
47 | Unless required by applicable law or agreed to in writing, software
48 | distributed under the License is distributed on an "AS IS" BASIS,
49 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
50 | See the License for the specific language governing permissions and
51 | limitations under the License.
52 |
53 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 27
5 | defaultConfig {
6 | applicationId "com.stx.xhb.enjoylife"
7 | minSdkVersion 16
8 | targetSdkVersion 27
9 | versionCode 4
10 | versionName "1.4"
11 | ndk {
12 | //设置支持的SO库架构
13 | abiFilters 'armeabi', 'armeabi-v7a','x86'
14 | }
15 | }
16 |
17 | buildTypes {
18 | release {
19 | minifyEnabled false
20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
21 | }
22 | debug {
23 | minifyEnabled false
24 | }
25 | }
26 | }
27 |
28 | repositories {
29 | maven { url "https://jitpack.io" }
30 | }
31 |
32 | dependencies {
33 | implementation fileTree(include: ['*.jar'], dir: 'libs')
34 | implementation project(':core')
35 | implementation 'com.shuyu:GSYVideoPlayer:2.0.2'
36 | //集成腾讯bugly
37 | implementation 'com.tencent.bugly:crashreport_upgrade:latest.release'
38 | //其中latest.release指代最新版本号
39 | implementation 'com.tencent.bugly:nativecrashreport:latest.release'
40 | implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.40'
41 | implementation 'com.jakewharton:butterknife:8.8.1'
42 | annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
43 | api 'com.github.bumptech.glide:glide:4.8.0'
44 | annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'
45 | implementation 'cn.bingoogolapple:bga-swipebacklayout:1.2.0@aar'
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/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 /SDKTools/android-sdk-macosx/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 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
25 |
26 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
41 |
42 |
43 |
47 |
48 |
49 |
53 |
54 |
55 |
58 |
59 |
60 |
64 |
65 |
66 |
70 |
71 |
72 |
75 |
76 |
77 |
80 |
81 |
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/FZLanTingHeiS-DB1-GB-Regular.TTF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/assets/fonts/FZLanTingHeiS-DB1-GB-Regular.TTF
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/FZLanTingHeiS-L-GB-Regular.TTF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/assets/fonts/FZLanTingHeiS-L-GB-Regular.TTF
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/Lobster-1.4.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/assets/fonts/Lobster-1.4.otf
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/MyApplication.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 | import android.text.TextUtils;
6 | import android.util.Config;
7 | import android.util.Log;
8 | import android.view.Gravity;
9 | import android.view.LayoutInflater;
10 | import android.widget.TextView;
11 | import android.widget.Toast;
12 |
13 | import com.stx.xhb.enjoylife.R;
14 | import com.umeng.analytics.MobclickAgent;
15 | import com.umeng.commonsdk.UMConfigure;
16 | import com.xhb.core.BuildConfig;
17 | import com.xhb.core.BaseApplication;
18 | import com.xhb.core.api.RestApi;
19 | import com.xhb.core.manage.crash.AndroidCrash;
20 | import com.tencent.bugly.Bugly;
21 | import com.xhb.core.util.LoggerHelper;
22 |
23 | /**
24 | *
25 | * @link https://xiaohaibin.github.io/
26 | * @email: xhb_199409@163.com
27 | * @github: https://github.com/xiaohaibin
28 | * @description: 程序入口
29 | */
30 | public class MyApplication extends BaseApplication {
31 |
32 | @Override
33 | public void onCreate() {
34 | super.onCreate();
35 | //初始化日志工具类
36 | LoggerHelper.initLogger(true);
37 | RestApi.getInstance();
38 | Bugly.init(getApplicationContext(), "784b642b7a", true);
39 | //初始化Toast
40 | ToastManager.instance.init(this);
41 | initUM();
42 | }
43 |
44 | private void initUM() {
45 | UMConfigure.init(this,UMConfigure.DEVICE_TYPE_PHONE,"");
46 | MobclickAgent.setSessionContinueMillis(2 * 60 * 1000);
47 | MobclickAgent.openActivityDurationTrack(false);
48 | MobclickAgent.setDebugMode(true);
49 | }
50 |
51 |
52 | public enum ToastManager {
53 | instance;
54 | private TextView contentTextView;
55 | private Toast toast;
56 |
57 | public void init(Context context) {
58 | contentTextView = (TextView) LayoutInflater.from(context).inflate(R.layout.view_toast, null);
59 | toast = new Toast(context);
60 | toast.setView(contentTextView);
61 | toast.setGravity(Gravity.CENTER, 0, 0);
62 | }
63 |
64 | public void show(CharSequence charSequence, int duration) {
65 | if (!TextUtils.isEmpty(charSequence)) {
66 | contentTextView.setText(charSequence);
67 | toast.setDuration(duration);
68 | toast.show();
69 | }
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/config/Config.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.config;
2 |
3 | import com.stx.xhb.enjoylife.R;
4 |
5 | /**
6 | * Created by Mr.xiao on 16/7/11.
7 | */
8 | public class Config {
9 |
10 | public static final String FEED = "IMAGE";
11 | public static final String WALLPAPER = "WALLPAPER";
12 | public static final String ZHIHU = "ZHIHU";
13 | public static final String VIDEO = "VIDEO";
14 |
15 | public enum Channel {
16 | IMAGE(R.string.fragment_image_title, R.drawable.ic_photo_black_24dp),
17 | WALLPAPER(R.string.fragment_wallpaper_title, R.drawable.icon_picture_black_24px),
18 | VIDEO(R.string.fragment_video_title, R.drawable.ic_video_black_24px),
19 | ZHIHU(R.string.fragment_zhihu_title, R.drawable.icon_zhihu_black_24px);
20 |
21 | private int title;
22 | private int icon;
23 |
24 | Channel(int title, int icon) {
25 | this.title = title;
26 | this.icon = icon;
27 | }
28 |
29 | public int getTitle() {
30 | return title;
31 | }
32 |
33 | public void setTitle(int title) {
34 | this.title = title;
35 | }
36 |
37 | public int getIcon() {
38 | return icon;
39 | }
40 |
41 | public void setIcon(int icon) {
42 | this.icon = icon;
43 | }
44 |
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/config/Constants.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.config;
2 |
3 | /**
4 | * Created by Mr.xiao on 16/7/7.
5 | * 接口统一管理工具类
6 | */
7 | public class Constants {
8 |
9 | /**
10 | * 开眼视频推荐接口
11 | */
12 | public static String VIDEO_API = "http://baobab.kaiyanapp.com/api/";
13 |
14 | /**
15 | * 图虫推荐API
16 | * page:翻页值。从 1 开始。需要搭配 json 中的 pose_id 字段使用。可为空
17 | * post_id:如果是第一页则不需要添加该字段。否则,需要加上该字段,该字段的值为上一页最后一个 json 中的 post_id 值
18 | * type:如果是第一页则是 refresh,如果是加载更多,则是 loadmore。可为空
19 | *
20 | * 图片地址:https://photo.tuchong.com/ + user_id +/f/ + img_id 即图片地址 例如:https://photo.tuchong.com/1673709/f/25389444.jpg
21 | */
22 | public static String TUCHONG_API = "https://api.tuchong.com/";
23 |
24 | /**
25 | * 知乎日报API
26 | */
27 | public static String ZHIHU_API="https://news-at.zhihu.com/api/4/news/";
28 |
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/config/MyAppGlideModule.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.config;
2 |
3 | import android.content.Context;
4 |
5 | import com.bumptech.glide.Glide;
6 | import com.bumptech.glide.Registry;
7 | import com.bumptech.glide.annotation.GlideModule;
8 | import com.bumptech.glide.module.AppGlideModule;
9 |
10 | /**
11 | * @author: xiaohaibin.
12 | * @time: 2018/7/3
13 | * @mail:xhb_199409@163.com
14 | * @github:https://github.com/xiaohaibin
15 | * @describe:
16 | */
17 | @GlideModule
18 | public final class MyAppGlideModule extends AppGlideModule {
19 |
20 | @Override
21 | public void registerComponents(Context context, Glide glide, Registry registry) {
22 | //Glide 底层默认使用 HttpConnection 进行网络请求,这里替换为 Okhttp 后才能使用本框架,进行 Glide 的加载进度监听
23 | // registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(ProgressManager.getInstance().with(new OkHttpClient.Builder())
24 | // .build()));
25 | }
26 |
27 | @Override
28 | public boolean isManifestParsingEnabled() {
29 | return false;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/listener/OnTransitionListener.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.listener;
2 |
3 | import android.annotation.TargetApi;
4 | import android.os.Build;
5 | import android.transition.Transition;
6 |
7 | /**
8 | * 重载了过渡动画的方法
9 | * Created by shuyu on 2016/8/15.
10 | */
11 |
12 | @TargetApi(Build.VERSION_CODES.KITKAT)
13 | public class OnTransitionListener implements Transition.TransitionListener {
14 |
15 |
16 | @Override
17 | public void onTransitionStart(Transition transition) {
18 |
19 | }
20 |
21 | @Override
22 | public void onTransitionEnd(Transition transition) {
23 |
24 | }
25 |
26 | @Override
27 | public void onTransitionCancel(Transition transition) {
28 |
29 | }
30 |
31 | @Override
32 | public void onTransitionPause(Transition transition) {
33 |
34 | }
35 |
36 | @Override
37 | public void onTransitionResume(Transition transition) {
38 |
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/listener/SampleVideoPlayListener.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.listener;
2 |
3 | import com.shuyu.gsyvideoplayer.listener.StandardVideoAllCallBack;
4 |
5 | /**
6 | * Author:xiaohaibin
7 | * Time:2017/7/18
8 | * Emil:xhb_199409@163.com
9 | * Github:https://github.com/xiaohaibin/
10 | * Describe:
11 | */
12 | public class SampleVideoPlayListener implements StandardVideoAllCallBack {
13 | @Override
14 | public void onClickStartThumb(String url, Object... objects) {
15 |
16 | }
17 |
18 | @Override
19 | public void onClickBlank(String url, Object... objects) {
20 |
21 | }
22 |
23 | @Override
24 | public void onClickBlankFullscreen(String url, Object... objects) {
25 |
26 | }
27 |
28 | @Override
29 | public void onPrepared(String url, Object... objects) {
30 |
31 | }
32 |
33 | @Override
34 | public void onClickStartIcon(String url, Object... objects) {
35 |
36 | }
37 |
38 | @Override
39 | public void onClickStartError(String url, Object... objects) {
40 |
41 | }
42 |
43 | @Override
44 | public void onClickStop(String url, Object... objects) {
45 |
46 | }
47 |
48 | @Override
49 | public void onClickStopFullscreen(String url, Object... objects) {
50 |
51 | }
52 |
53 | @Override
54 | public void onClickResume(String url, Object... objects) {
55 |
56 | }
57 |
58 | @Override
59 | public void onClickResumeFullscreen(String url, Object... objects) {
60 |
61 | }
62 |
63 | @Override
64 | public void onClickSeekbar(String url, Object... objects) {
65 |
66 | }
67 |
68 | @Override
69 | public void onClickSeekbarFullscreen(String url, Object... objects) {
70 |
71 | }
72 |
73 | @Override
74 | public void onAutoComplete(String url, Object... objects) {
75 |
76 | }
77 |
78 | @Override
79 | public void onEnterFullscreen(String url, Object... objects) {
80 |
81 | }
82 |
83 | @Override
84 | public void onQuitFullscreen(String url, Object... objects) {
85 |
86 | }
87 |
88 | @Override
89 | public void onQuitSmallWidget(String url, Object... objects) {
90 |
91 | }
92 |
93 | @Override
94 | public void onEnterSmallWidget(String url, Object... objects) {
95 |
96 | }
97 |
98 | @Override
99 | public void onTouchScreenSeekVolume(String url, Object... objects) {
100 |
101 | }
102 |
103 | @Override
104 | public void onTouchScreenSeekPosition(String url, Object... objects) {
105 |
106 | }
107 |
108 | @Override
109 | public void onTouchScreenSeekLight(String url, Object... objects) {
110 |
111 | }
112 |
113 | @Override
114 | public void onPlayError(String url, Object... objects) {
115 |
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/model/entity/ZhiHuNewsContentResponse.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.model.entity;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * @author: xiaohaibin.
7 | * @time: 2018/5/9
8 | * @mail:xhb_199409@163.com
9 | * @github:https://github.com/xiaohaibin
10 | * @describe: 知乎日报新闻详情
11 | */
12 | public class ZhiHuNewsContentResponse {
13 |
14 | private String body="";
15 | private String image_source;
16 | private String title;
17 | private String image;
18 | private String share_url;
19 | private String ga_prefix;
20 | private int type;
21 | private int id;
22 | private List> js;
23 | private List images;
24 | private List css;
25 |
26 | public String getBody() {
27 | return body;
28 | }
29 |
30 | public String getImage_source() {
31 | return image_source;
32 | }
33 |
34 | public String getTitle() {
35 | return title;
36 | }
37 |
38 | public String getImage() {
39 | return image;
40 | }
41 |
42 | public String getShare_url() {
43 | return share_url;
44 | }
45 |
46 | public String getGa_prefix() {
47 | return ga_prefix;
48 | }
49 |
50 | public int getType() {
51 | return type;
52 | }
53 |
54 | public int getId() {
55 | return id;
56 | }
57 |
58 | public List> getJs() {
59 | return js;
60 | }
61 |
62 | public List getImages() {
63 | return images;
64 | }
65 |
66 | public List getCss() {
67 | return css;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/model/entity/ZhiHuNewsResponse.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.model.entity;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * @author: xiaohaibin.
7 | * @time: 2018/5/9
8 | * @mail:xhb_199409@163.com
9 | * @github:https://github.com/xiaohaibin
10 | * @describe: 知乎日报新闻实体类
11 | */
12 | public class ZhiHuNewsResponse {
13 |
14 | /**
15 | * date : 20180509
16 | * stories : [{"images":["https://pic1.zhimg.com/v2-2eab141000845dedd3e5215cec396ca0.jpg"],"type":0,"id":9681671,"ga_prefix":"050910","title":"听见「2000 块护肤品不如一次医美」,作为皮肤科医生,我得说几句"},{"images":["https://pic4.zhimg.com/v2-85c9f286013d987008a35033d661fef7.jpg"],"type":0,"id":9680802,"ga_prefix":"050909","title":"为什么很多经历原生家庭伤害的人,父母往往是老师?"},{"images":["https://pic4.zhimg.com/v2-cb1218d5947e60be39df4ce9f2a8c4b7.jpg"],"type":0,"id":9681981,"ga_prefix":"050908","title":"「你都 20 好几的男人了还天天打游戏,真没出息」"},{"images":["https://pic3.zhimg.com/v2-0a82314c26a546ab0e2591d65494ba96.jpg"],"type":0,"id":9681931,"ga_prefix":"050907","title":"港股迎来 20 年来最大变革,A 股恐怕又要因此再失去一波公司"},{"images":["https://pic2.zhimg.com/v2-cd3128cc82ee7330c4b19d1fc20301c1.jpg"],"type":0,"id":9681999,"ga_prefix":"050907","title":"马化腾张一鸣朋友圈「互怼」,看来头条和腾讯一战是在所难免了"},{"images":["https://pic2.zhimg.com/v2-6a5e13826658386270a9d2c559811e95.jpg"],"type":0,"id":9682062,"ga_prefix":"050906","title":"瞎扯 · 如何正确地吐槽"}]
17 | * top_stories : [{"image":"https://pic1.zhimg.com/v2-e8a7f6e103bf5da69f785279223e71b4.jpg","type":0,"id":9681671,"ga_prefix":"050910","title":"听见「2000 块护肤品不如一次医美」,作为皮肤科医生,我得说几句"},{"image":"https://pic4.zhimg.com/v2-bf2189b8bad4ca7b78abf349c2497183.jpg","type":0,"id":9681999,"ga_prefix":"050907","title":"马化腾张一鸣朋友圈「互怼」,看来头条和腾讯一战是在所难免了"},{"image":"https://pic1.zhimg.com/v2-c00667590f4fd4b739e6904379a23768.jpg","type":0,"id":9681981,"ga_prefix":"050908","title":"「你都 20 好几的男人了还天天打游戏,真没出息」"},{"image":"https://pic2.zhimg.com/v2-f25b047abda14637c43dae6aee8c4969.jpg","type":0,"id":9681931,"ga_prefix":"050907","title":"港股迎来 20 年来最大变革,A 股恐怕又要因此再失去一波公司"},{"image":"https://pic3.zhimg.com/v2-3285705600681b9f8cd49c503b5d69e2.jpg","type":0,"id":9680802,"ga_prefix":"050909","title":"为什么很多经历原生家庭伤害的人,父母往往是老师?"}]
18 | */
19 |
20 | private String date;
21 | private List stories;
22 | private List top_stories;
23 |
24 | public String getDate() {
25 | return date;
26 | }
27 |
28 | public List getStories() {
29 | return stories;
30 | }
31 |
32 | public List getTop_stories() {
33 | return top_stories;
34 | }
35 |
36 | public static class StoriesBean {
37 | /**
38 | * images : ["https://pic1.zhimg.com/v2-2eab141000845dedd3e5215cec396ca0.jpg"]
39 | * type : 0
40 | * id : 9681671
41 | * ga_prefix : 050910
42 | * title : 听见「2000 块护肤品不如一次医美」,作为皮肤科医生,我得说几句
43 | */
44 |
45 | private int type;
46 | private int id;
47 | private String ga_prefix;
48 | private String title;
49 | private List images;
50 |
51 | public int getType() {
52 | return type;
53 | }
54 |
55 | public int getId() {
56 | return id;
57 | }
58 |
59 | public String getGa_prefix() {
60 | return ga_prefix;
61 | }
62 |
63 | public String getTitle() {
64 | return title;
65 | }
66 |
67 | public List getImages() {
68 | return images;
69 | }
70 | }
71 |
72 | public static class TopStoriesBean {
73 | /**
74 | * image : https://pic1.zhimg.com/v2-e8a7f6e103bf5da69f785279223e71b4.jpg
75 | * type : 0
76 | * id : 9681671
77 | * ga_prefix : 050910
78 | * title : 听见「2000 块护肤品不如一次医美」,作为皮肤科医生,我得说几句
79 | */
80 |
81 | private String image;
82 | private int type;
83 | private int id;
84 | private String ga_prefix;
85 | private String title;
86 |
87 | public String getImage() {
88 | return image;
89 | }
90 |
91 | public int getType() {
92 | return type;
93 | }
94 |
95 | public int getId() {
96 | return id;
97 | }
98 |
99 | public String getGa_prefix() {
100 | return ga_prefix;
101 | }
102 |
103 | public String getTitle() {
104 | return title;
105 | }
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/model/http/ApiManager.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.model.http;
2 |
3 | import com.stx.xhb.enjoylife.model.entity.TuChongWallPaperResponse;
4 | import com.stx.xhb.enjoylife.model.entity.ZhiHuNewsContentResponse;
5 | import com.stx.xhb.enjoylife.model.entity.ZhiHuNewsResponse;
6 | import com.xhb.core.api.RestApi;
7 | import com.stx.xhb.enjoylife.config.Constants;
8 | import com.stx.xhb.enjoylife.model.entity.TuchongImagResponse;
9 | import com.stx.xhb.enjoylife.model.entity.VideoResponse;
10 |
11 | import java.util.Map;
12 |
13 | import retrofit2.Call;
14 | import retrofit2.http.GET;
15 | import retrofit2.http.Path;
16 | import retrofit2.http.Query;
17 | import retrofit2.http.QueryMap;
18 |
19 | /**
20 | * API管理
21 | */
22 | public interface ApiManager {
23 |
24 | /**
25 | * 开眼推荐视频
26 | *
27 | * @param param
28 | * @return
29 | */
30 | @GET("v2/feed")
31 | Call getVideoList(@QueryMap Map param);
32 |
33 | /**
34 | * 图虫推荐
35 | *
36 | * @param param
37 | * @return
38 | */
39 | @GET("feed-app")
40 | Call getFeedApp(@QueryMap Map param);
41 |
42 | /**
43 | * 图虫壁纸
44 | *
45 | * @param page
46 | * @return
47 | */
48 | @GET("2/wall-paper/app")
49 | Call getWallPaper(@Query("page") int page);
50 |
51 | /**
52 | * 获取知乎日报
53 | *
54 | * @param url https://news-at.zhihu.com/api/4/news/latest 最新消息
55 | * https://news-at.zhihu.com/api/4/news/before/20131119 过往消息
56 | * @return
57 | */
58 | @GET("{url}")
59 | Call getZhiHuNews(@Path("url") String url);
60 |
61 | /**
62 | * 获取知乎日报
63 | *
64 | * @param time https://news-at.zhihu.com/api/4/news/latest 最新消息
65 | * https://news-at.zhihu.com/api/4/news/before/20131119 过往消息
66 | * @return
67 | */
68 | @GET("before/{time}")
69 | Call getZhiHuNewsBefore(@Path("time") String time);
70 |
71 | /**
72 | * 获取知乎日报新闻详情
73 | * @param time
74 | * @return
75 | */
76 | @GET("{time}")
77 | Call getZhiHuNewsContent(@Path("time") String time);
78 |
79 | class ApiFactory {
80 |
81 | public static ApiManager createVideoApi() {
82 | return RestApi.getInstance().create(Constants.VIDEO_API, ApiManager.class);
83 | }
84 |
85 | public static ApiManager createTuChongApi() {
86 | return RestApi.getInstance().create(Constants.TUCHONG_API, ApiManager.class);
87 | }
88 |
89 | public static ApiManager creatZhiHuApi() {
90 | return RestApi.getInstance().create(Constants.ZHIHU_API, ApiManager.class);
91 | }
92 |
93 | }
94 |
95 | }
96 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/presenter/tuchong/getFeedAppContact.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.presenter.tuchong;
2 |
3 | import com.xhb.core.base.IBaseView;
4 | import com.xhb.core.base.IModel;
5 | import com.xhb.core.model.annotation.Implement;
6 | import com.stx.xhb.enjoylife.model.entity.TuchongImagResponse;
7 |
8 | import java.util.List;
9 |
10 | /**
11 | * @author: xiaohaibin.
12 | * @time: 2018/4/24
13 | * @mail:xhb_199409@163.com
14 | * @github:https://github.com/xiaohaibin
15 | * @describe:
16 | */
17 | @Implement(getFeedAppIPresenterImpl.class)
18 | public interface getFeedAppContact {
19 |
20 | interface Model extends IModel {
21 | void getFeedAppImage(int page, String type, String posId);
22 | }
23 |
24 | interface View extends IBaseView {
25 |
26 | void onResponse(List feedList, boolean isMore);
27 |
28 | void onFailure(String msg);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/presenter/tuchong/getFeedAppIPresenterImpl.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.presenter.tuchong;
2 |
3 | import android.text.TextUtils;
4 |
5 | import com.xhb.core.base.BaseIPresenter;
6 | import com.stx.xhb.enjoylife.model.entity.TuchongImagResponse;
7 | import com.stx.xhb.enjoylife.model.http.ApiManager;
8 |
9 | import java.util.HashMap;
10 |
11 | /**
12 | * @author: xiaohaibin.
13 | * @time: 2018/4/24
14 | * @mail:xhb_199409@163.com
15 | * @github:https://github.com/xiaohaibin
16 | * @describe:
17 | */
18 | public class getFeedAppIPresenterImpl extends BaseIPresenter implements getFeedAppContact.Model {
19 |
20 | @Override
21 | public void getFeedAppImage(int page, String type, String posId) {
22 | HashMap map = new HashMap<>();
23 | map.put("page", String.valueOf(page));
24 | map.put("type", type);
25 | if (!TextUtils.isEmpty(posId)) {
26 | map.put("post_id", posId);
27 | }
28 | request(ApiManager.ApiFactory.createTuChongApi().getFeedApp(map), new LoadTaskCallback() {
29 | @Override
30 | public void onTaskLoaded(TuchongImagResponse data) {
31 | if (getView() != null && data.getFeedList() != null && !data.getFeedList().isEmpty()) {
32 | getView().onResponse(data.getFeedList(), data.isMore());
33 | }
34 | }
35 |
36 | @Override
37 | public void onDataNotAvailable(String msg) {
38 | if (getView() != null) {
39 | getView().onFailure(msg);
40 | }
41 | }
42 | });
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/presenter/tuchong/getWallPaperContract.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.presenter.tuchong;
2 |
3 | import com.stx.xhb.enjoylife.model.entity.TuChongWallPaperResponse;
4 | import com.xhb.core.base.IBaseView;
5 | import com.xhb.core.base.IModel;
6 | import com.xhb.core.model.annotation.Implement;
7 |
8 | import java.util.List;
9 |
10 | /**
11 | * @author: xiaohaibin.
12 | * @time: 2018/4/28
13 | * @mail:xhb_199409@163.com
14 | * @github:https://github.com/xiaohaibin
15 | * @describe:
16 | */
17 | @Implement(getWallPaperIPresenterImpl.class)
18 | public interface getWallPaperContract {
19 |
20 | interface Model extends IModel {
21 | void getWallPaper(int page);
22 | }
23 |
24 | interface View extends IBaseView {
25 |
26 | void onResponse(List feedList, boolean isMore);
27 |
28 | void onFailure(String msg);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/presenter/tuchong/getWallPaperIPresenterImpl.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.presenter.tuchong;
2 |
3 | import com.stx.xhb.enjoylife.model.entity.TuChongWallPaperResponse;
4 | import com.stx.xhb.enjoylife.model.http.ApiManager;
5 | import com.xhb.core.base.BaseIPresenter;
6 |
7 | /**
8 | * @author: xiaohaibin.
9 | * @time: 2018/4/28
10 | * @mail:xhb_199409@163.com
11 | * @github:https://github.com/xiaohaibin
12 | * @describe:
13 | */
14 | public class getWallPaperIPresenterImpl extends BaseIPresenter implements getWallPaperContract.Model {
15 |
16 | @Override
17 | public void getWallPaper(int page) {
18 | request(ApiManager.ApiFactory.createTuChongApi().getWallPaper(page), new LoadTaskCallback() {
19 | @Override
20 | public void onTaskLoaded(TuChongWallPaperResponse data) {
21 | if (getView() != null && data.getFeedList() != null && !data.getFeedList().isEmpty()) {
22 | getView().onResponse(data.getFeedList(), data.isMore());
23 | }
24 | }
25 |
26 | @Override
27 | public void onDataNotAvailable(String msg) {
28 | if (getView() != null) {
29 | getView().onFailure(msg);
30 | }
31 | }
32 | });
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/presenter/video/getVideoContract.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.presenter.video;
2 |
3 | import com.xhb.core.base.IBaseView;
4 | import com.xhb.core.base.IModel;
5 | import com.xhb.core.model.annotation.Implement;
6 | import com.stx.xhb.enjoylife.model.entity.VideoResponse;
7 |
8 | /**
9 | * Author:xiaohaibin
10 | * Time:2017/7/26
11 | * Emil:xhb_199409@163.com
12 | * Github:https://github.com/xiaohaibin/
13 | * Describe:
14 | */
15 | @Implement(getVideoIPresenterImpl.class)
16 | public interface getVideoContract {
17 |
18 | interface Model extends IModel {
19 | void getVideoInfo(String date, int num);
20 | }
21 |
22 | interface getVideoView extends IBaseView {
23 |
24 | void onResponse(VideoResponse response);
25 |
26 | void onFailure(String msg);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/presenter/video/getVideoIPresenterImpl.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.presenter.video;
2 |
3 | import android.text.TextUtils;
4 |
5 | import com.xhb.core.base.BaseIPresenter;
6 | import com.stx.xhb.enjoylife.model.entity.VideoResponse;
7 | import com.stx.xhb.enjoylife.model.http.ApiManager;
8 |
9 | import java.util.HashMap;
10 |
11 | /**
12 | * Created by Mr.xiao on 16/7/14.
13 | */
14 | public class getVideoIPresenterImpl extends BaseIPresenter implements getVideoContract.Model {
15 |
16 | @Override
17 | public void getVideoInfo(String date, int num) {
18 | HashMap map = new HashMap<>();
19 | map.put("num", "2");
20 | if (!TextUtils.isEmpty(date)) {
21 | map.put("date", String.valueOf(date));
22 | }
23 | request(ApiManager.ApiFactory.createVideoApi().getVideoList(map), new LoadTaskCallback() {
24 | @Override
25 | public void onTaskLoaded(VideoResponse data) {
26 | if (getView() != null) {
27 | getView().onResponse(data);
28 | }
29 | }
30 |
31 | @Override
32 | public void onDataNotAvailable(String msg) {
33 | if (getView() != null) {
34 | getView().onFailure(msg);
35 | }
36 | }
37 | });
38 |
39 |
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/presenter/zhihu/getNewsContentContract.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.presenter.zhihu;
2 |
3 | import com.stx.xhb.enjoylife.model.entity.ZhiHuNewsContentResponse;
4 | import com.xhb.core.base.IBaseView;
5 | import com.xhb.core.base.IModel;
6 | import com.xhb.core.model.annotation.Implement;
7 |
8 | /**
9 | * @author: xiaohaibin.
10 | * @time: 2018/5/9
11 | * @mail:xhb_199409@163.com
12 | * @github:https://github.com/xiaohaibin
13 | * @describe:
14 | */
15 | @Implement(getNewsContentIPresenterImpl.class)
16 | public interface getNewsContentContract {
17 |
18 | interface Model extends IModel {
19 | void getNewsContent(String id);
20 | }
21 |
22 | interface View extends IBaseView {
23 |
24 | void onResponse(ZhiHuNewsContentResponse response);
25 |
26 | void onFailed(String msg);
27 |
28 | void showLoading();
29 |
30 | void hideLoading();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/presenter/zhihu/getNewsContentIPresenterImpl.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.presenter.zhihu;
2 |
3 | import com.stx.xhb.enjoylife.model.entity.ZhiHuNewsContentResponse;
4 | import com.stx.xhb.enjoylife.model.http.ApiManager;
5 | import com.xhb.core.base.BaseIPresenter;
6 |
7 | /**
8 | * @author: xiaohaibin.
9 | * @time: 2018/5/9
10 | * @mail:xhb_199409@163.com
11 | * @github:https://github.com/xiaohaibin
12 | * @describe:
13 | */
14 | public class getNewsContentIPresenterImpl extends BaseIPresenter implements getNewsContentContract.Model {
15 |
16 | @Override
17 | public void getNewsContent(String id) {
18 | if (getView() == null) {
19 | return;
20 | }
21 | getView().showLoading();
22 | request(ApiManager.ApiFactory.creatZhiHuApi().getZhiHuNewsContent(id), new LoadTaskCallback() {
23 | @Override
24 | public void onTaskLoaded(ZhiHuNewsContentResponse data) {
25 | getView().hideLoading();
26 | getView().onResponse(data);
27 | }
28 |
29 | @Override
30 | public void onDataNotAvailable(String msg) {
31 | getView().hideLoading();
32 | getView().onFailed(msg);
33 | }
34 | });
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/presenter/zhihu/getZhiHuNewsContract.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.presenter.zhihu;
2 |
3 | import com.stx.xhb.enjoylife.model.entity.ZhiHuNewsResponse;
4 | import com.xhb.core.base.IBaseView;
5 | import com.xhb.core.base.IModel;
6 | import com.xhb.core.model.annotation.Implement;
7 |
8 | /**
9 | * @author: xiaohaibin.
10 | * @time: 2018/5/9
11 | * @mail:xhb_199409@163.com
12 | * @github:https://github.com/xiaohaibin
13 | * @describe:
14 | */
15 | @Implement(getZhiHuNewsIPresenterImpl.class)
16 | public interface getZhiHuNewsContract {
17 |
18 | interface Model extends IModel {
19 | void getNews(String url);
20 |
21 | void getNewsBefore(String time);
22 | }
23 |
24 |
25 | interface View extends IBaseView {
26 |
27 | void onResponse(ZhiHuNewsResponse zhiHuNewsResponse);
28 |
29 | void onFailure(String msg);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/presenter/zhihu/getZhiHuNewsIPresenterImpl.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.presenter.zhihu;
2 |
3 | import com.stx.xhb.enjoylife.model.entity.ZhiHuNewsResponse;
4 | import com.stx.xhb.enjoylife.model.http.ApiManager;
5 | import com.xhb.core.base.BaseIPresenter;
6 |
7 | /**
8 | * @author: xiaohaibin.
9 | * @time: 2018/5/9
10 | * @mail:xhb_199409@163.com
11 | * @github:https://github.com/xiaohaibin
12 | * @describe:
13 | */
14 | public class getZhiHuNewsIPresenterImpl extends BaseIPresenter implements getZhiHuNewsContract.Model {
15 |
16 | @Override
17 | public void getNews(String url) {
18 | request(ApiManager.ApiFactory.creatZhiHuApi().getZhiHuNews(url), new LoadTaskCallback() {
19 | @Override
20 | public void onTaskLoaded(ZhiHuNewsResponse data) {
21 | if (getView() != null) {
22 | getView().onResponse(data);
23 | }
24 | }
25 |
26 | @Override
27 | public void onDataNotAvailable(String msg) {
28 | if (getView() != null) {
29 | getView().onFailure(msg);
30 | }
31 | }
32 | });
33 | }
34 |
35 | @Override
36 | public void getNewsBefore(String time) {
37 | request(ApiManager.ApiFactory.creatZhiHuApi().getZhiHuNewsBefore(time), new LoadTaskCallback() {
38 | @Override
39 | public void onTaskLoaded(ZhiHuNewsResponse data) {
40 | if (getView() != null) {
41 | getView().onResponse(data);
42 | }
43 | }
44 |
45 | @Override
46 | public void onDataNotAvailable(String msg) {
47 | if (getView() != null) {
48 | getView().onFailure(msg);
49 | }
50 | }
51 | });
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/ui/activity/AboutActivity.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.ui.activity;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.support.design.widget.CollapsingToolbarLayout;
7 | import android.support.v7.widget.Toolbar;
8 | import android.view.Menu;
9 | import android.view.MenuItem;
10 | import android.view.View;
11 | import android.widget.TextView;
12 |
13 | import com.stx.xhb.enjoylife.BuildConfig;
14 | import com.stx.xhb.enjoylife.R;
15 | import com.stx.xhb.enjoylife.utils.ShareUtils;
16 | import com.xhb.core.base.BaseSwipeBackActivity;
17 | import com.xhb.core.ui.SwipeBackLayout;
18 |
19 | import butterknife.BindView;
20 | import butterknife.ButterKnife;
21 |
22 | /**
23 | * 关于界面
24 | */
25 | public class AboutActivity extends BaseSwipeBackActivity {
26 |
27 | @BindView(R.id.tv_version)
28 | TextView tvVersion;
29 | @BindView(R.id.toolbar)
30 | Toolbar toolbar;
31 | @BindView(R.id.collapsing_toolbar)
32 | CollapsingToolbarLayout collapsingToolbar;
33 |
34 | public static void start(Context context) {
35 | Intent intent = new Intent(context, AboutActivity.class);
36 | context.startActivity(intent);
37 | }
38 |
39 | @Override
40 | protected void onCreate(Bundle savedInstanceState) {
41 | super.onCreate(savedInstanceState);
42 | setContentView(R.layout.activity_about);
43 | ButterKnife.bind(this);
44 | setDragEdge(SwipeBackLayout.DragEdge.LEFT);
45 | initView();
46 | }
47 |
48 | //初始化视图控件
49 | private void initView() {
50 | tvVersion.setText("Version " + BuildConfig.VERSION_NAME);
51 | collapsingToolbar.setTitle(getString(R.string.app_name));
52 | setSupportActionBar(toolbar);
53 | getSupportActionBar().setDisplayHomeAsUpEnabled(true);
54 | toolbar.setNavigationOnClickListener(new View.OnClickListener() {
55 | @Override
56 | public void onClick(View v) {
57 | AboutActivity.this.onBackPressed();
58 | }
59 | });
60 | }
61 |
62 |
63 | @Override
64 | public boolean onCreateOptionsMenu(Menu menu) {
65 | getMenuInflater().inflate(R.menu.menu_about, menu);
66 | return true;
67 | }
68 |
69 | @Override
70 | public boolean onOptionsItemSelected(MenuItem item) {
71 | switch (item.getItemId()) {
72 | case android.R.id.home:
73 | finish();
74 | return true;
75 | case R.id.menu_share:
76 | ShareUtils.share(this, R.string.share_text);
77 | return true;
78 | default:
79 | break;
80 | }
81 | return super.onOptionsItemSelected(item);
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/ui/activity/SetttingActivity.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.ui.activity;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.support.v7.widget.Toolbar;
7 | import android.view.View;
8 |
9 | import com.xhb.core.base.BaseSwipeBackActivity;
10 | import com.xhb.core.ui.SwipeBackLayout;
11 | import com.stx.xhb.enjoylife.R;
12 |
13 | import butterknife.BindView;
14 | import butterknife.ButterKnife;
15 |
16 | /**
17 | * 设置界面
18 | */
19 | public class SetttingActivity extends BaseSwipeBackActivity {
20 |
21 |
22 | @BindView(R.id.toolbar)
23 | Toolbar toolbar;
24 |
25 | public static void start(Context context) {
26 | Intent intent = new Intent(context, SetttingActivity.class);
27 | context.startActivity(intent);
28 | }
29 |
30 | @Override
31 | protected void onCreate(Bundle savedInstanceState) {
32 | super.onCreate(savedInstanceState);
33 | setContentView(R.layout.activity_settting);
34 | ButterKnife.bind(this);
35 | setDragEdge(SwipeBackLayout.DragEdge.LEFT);
36 | initView();
37 | }
38 |
39 | private void initView() {
40 | setSupportActionBar(toolbar);
41 | if (getSupportActionBar() != null) {
42 | getSupportActionBar().setDisplayHomeAsUpEnabled(true);
43 | }
44 | toolbar.setNavigationOnClickListener(new View.OnClickListener() {
45 | @Override
46 | public void onClick(View v) {
47 | onBackPressed();
48 | }
49 | });
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/ui/activity/SplashActivity.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.ui.activity;
2 |
3 | import android.animation.Animator;
4 | import android.animation.AnimatorListenerAdapter;
5 | import android.animation.ObjectAnimator;
6 | import android.content.Intent;
7 | import android.os.Bundle;
8 | import android.view.WindowManager;
9 | import android.widget.FrameLayout;
10 | import android.widget.ImageView;
11 |
12 | import com.jaeger.library.StatusBarUtil;
13 | import com.stx.xhb.enjoylife.R;
14 | import com.xhb.core.base.BaseActivity;
15 |
16 | import butterknife.BindView;
17 |
18 | /**
19 | * 启动页面
20 | */
21 | public class SplashActivity extends BaseActivity {
22 | @BindView(R.id.iv_splash)
23 | ImageView ivSplash;
24 | @BindView(R.id.splash_view)
25 | FrameLayout splashView;
26 | /**动画时间 1000ms*/
27 | private static final int ANIMATOR_DURATION = 2000;
28 | private ObjectAnimator alphaAnimIn;
29 | @Override
30 | protected int getLayoutResource() {
31 | return R.layout.activity_splash;
32 | }
33 |
34 | @Override
35 | protected void onInitialization(Bundle bundle) {
36 | getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
37 | //设置状态栏透明
38 | StatusBarUtil.setTranslucent(this,0);
39 | // GlideApp.with(this).load("https://pic1.zhimg.com/v2-9639852750175df1b80ed995729e64e8.jpg").dontAnimate().into(ivSplash);
40 | //设置动画
41 | alphaAnimIn = ObjectAnimator.ofFloat(splashView, "alpha", 0f, 1f);
42 |
43 | alphaAnimIn.setDuration(ANIMATOR_DURATION);
44 |
45 | alphaAnimIn.start();
46 | alphaAnimIn.addListener(new AnimatorListenerAdapter() {
47 | @Override
48 | public void onAnimationEnd(Animator animation) {
49 | super.onAnimationEnd(animation);
50 | jumpToMain();
51 | }
52 | });
53 | }
54 |
55 | private void jumpToMain() {
56 | startActivity(new Intent(SplashActivity.this, MainActivity.class));
57 | finish();
58 | overridePendingTransition(R.anim.splash_fade_in, R.anim.splash_fade_out);
59 | }
60 |
61 | @Override
62 | protected void onStop() {
63 | super.onStop();
64 | if (alphaAnimIn != null) {
65 | alphaAnimIn.cancel();
66 | }
67 | }
68 |
69 | @Override
70 | protected void onDestroy() {
71 | super.onDestroy();
72 | if (alphaAnimIn != null) {
73 | alphaAnimIn.cancel();
74 | alphaAnimIn.removeAllListeners();
75 | alphaAnimIn = null;
76 | }
77 | }
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/ui/adapter/NewsAdapter.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.ui.adapter;
2 |
3 | import android.content.Context;
4 | import android.view.View;
5 | import android.widget.ImageView;
6 |
7 | import com.bumptech.glide.Glide;
8 | import com.chad.library.adapter.base.BaseQuickAdapter;
9 | import com.chad.library.adapter.base.BaseViewHolder;
10 | import com.stx.xhb.enjoylife.R;
11 | import com.stx.xhb.enjoylife.model.entity.ZhiHuNewsResponse;
12 | import com.stx.xhb.enjoylife.ui.activity.NewsDetailsActivity;
13 |
14 |
15 | /**
16 | * @author: xiaohaibin.
17 | * @time: 2018/5/9
18 | * @mail:xhb_199409@163.com
19 | * @github:https://github.com/xiaohaibin
20 | * @describe:
21 | */
22 | public class NewsAdapter extends BaseQuickAdapter {
23 |
24 | private Context mContext;
25 |
26 | public NewsAdapter(int layoutResId, Context context) {
27 | super(layoutResId);
28 | mContext = context;
29 | }
30 |
31 | @Override
32 | protected void convert(BaseViewHolder holder, final ZhiHuNewsResponse.StoriesBean news) {
33 | if (news.getImages()!=null&&!news.getImages().isEmpty()) {
34 | ImageView imageView = holder.getView(R.id.thumbnail_image);
35 | Glide.with(imageView.getContext()).load(news.getImages().get(0)).into(imageView);
36 | }
37 | holder.setText(R.id.daily_title,news.getTitle());
38 | holder.itemView.setOnClickListener(new View.OnClickListener() {
39 | @Override
40 | public void onClick(View v) {
41 | NewsDetailsActivity.start(mContext,String.valueOf(news.getId()),news.getTitle());
42 | }
43 | });
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/ui/adapter/PhotoViewPagerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.ui.adapter;
2 |
3 | import android.content.Context;
4 | import android.graphics.drawable.Drawable;
5 | import android.support.annotation.NonNull;
6 | import android.support.annotation.Nullable;
7 | import android.support.v4.view.PagerAdapter;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.ProgressBar;
11 |
12 | import com.bumptech.glide.load.DataSource;
13 | import com.bumptech.glide.load.engine.DiskCacheStrategy;
14 | import com.bumptech.glide.load.engine.GlideException;
15 | import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;
16 | import com.bumptech.glide.request.RequestListener;
17 | import com.bumptech.glide.request.target.Target;
18 | import com.github.chrisbanes.photoview.OnViewTapListener;
19 | import com.github.chrisbanes.photoview.PhotoView;
20 | import com.stx.xhb.enjoylife.R;
21 | import com.stx.xhb.enjoylife.config.GlideApp;
22 | import com.stx.xhb.enjoylife.utils.ToastUtil;
23 |
24 | import java.util.ArrayList;
25 |
26 |
27 | /**
28 | * Created by Mr.xiao on 16/8/26.
29 | * 图片预览Viewpager适配器
30 | */
31 | public class PhotoViewPagerAdapter extends PagerAdapter {
32 |
33 | private Context context;
34 | private ArrayList imageList;
35 | private onImageLayoutListener mImageLayoutListener;
36 |
37 | public PhotoViewPagerAdapter(Context context, ArrayList imageList) {
38 | this.context = context;
39 | this.imageList = imageList;
40 | }
41 |
42 | @Override
43 | public int getCount() {
44 | return imageList.size();
45 | }
46 |
47 | @Override
48 | public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
49 | return view == object;
50 | }
51 |
52 | @NonNull
53 | @Override
54 | public Object instantiateItem(@NonNull ViewGroup container, int position) {
55 | View convertView = View.inflate(context, R.layout.item_photoview, null);
56 | final PhotoView photoView = convertView.findViewById(R.id.photo_view);
57 | final ProgressBar progressBar = convertView.findViewById(R.id.progress_view);
58 | final String imgUrl = imageList.get(position);
59 |
60 | photoView.setOnViewTapListener(new OnViewTapListener() {
61 | @Override
62 | public void onViewTap(View view, float v, float v1) {
63 | if (mImageLayoutListener != null) {
64 | mImageLayoutListener.setOnImageOnClik();
65 | }
66 | }
67 | });
68 | GlideApp.with(context)
69 | .load(imgUrl)
70 | .transition(DrawableTransitionOptions.withCrossFade())
71 | .listener(new RequestListener() {
72 | @Override
73 | public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
74 | ToastUtil.show("图片加载失败");
75 | progressBar.setVisibility(View.GONE);
76 | return false;
77 | }
78 |
79 | @Override
80 | public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) {
81 | progressBar.setVisibility(View.GONE);
82 | return false;
83 | }
84 | })
85 | .diskCacheStrategy(DiskCacheStrategy.NONE)
86 | .into(photoView);
87 |
88 | photoView.setOnLongClickListener(new View.OnLongClickListener() {
89 | @Override
90 | public boolean onLongClick(View v) {
91 | if (mImageLayoutListener != null) {
92 | mImageLayoutListener.setLongClick(imgUrl);
93 | }
94 | return true;
95 | }
96 | });
97 | container.addView(convertView);
98 | return convertView;
99 | }
100 |
101 | @Override
102 | public void destroyItem(ViewGroup container, int position, Object object) {
103 | container.removeView((View) object);
104 | }
105 |
106 | public void setOnClickListener(onImageLayoutListener onClickListener) {
107 | mImageLayoutListener = onClickListener;
108 | }
109 |
110 | public interface onImageLayoutListener {
111 |
112 | void setOnImageOnClik();
113 |
114 | void setLongClick(String url);
115 |
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/ui/adapter/TuChongListAdapter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Drakeet
3 | *
4 | * This file is part of Meizhi
5 | *
6 | * Meizhi is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Meizhi is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Meizhi. If not, see .
18 | */
19 |
20 | package com.stx.xhb.enjoylife.ui.adapter;
21 |
22 | import android.support.v4.view.ViewCompat;
23 | import android.view.View;
24 | import android.widget.TextView;
25 |
26 | import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;
27 | import com.bumptech.glide.request.target.SizeReadyCallback;
28 | import com.chad.library.adapter.base.BaseQuickAdapter;
29 | import com.chad.library.adapter.base.BaseViewHolder;
30 | import com.stx.xhb.enjoylife.R;
31 | import com.stx.xhb.enjoylife.config.GlideApp;
32 | import com.stx.xhb.enjoylife.model.entity.TuchongImagResponse;
33 | import com.stx.xhb.enjoylife.ui.widget.RatioImageView;
34 |
35 | import java.util.ArrayList;
36 | import java.util.List;
37 |
38 | public class TuChongListAdapter extends BaseQuickAdapter {
39 |
40 | public static final String TAG = "TuChongListAdapter";
41 |
42 | private OnImageItemClickListener mOnImageItemClickListener;
43 |
44 | public TuChongListAdapter(int layoutResId) {
45 | super(layoutResId);
46 | }
47 |
48 | @Override
49 | protected void convert(final BaseViewHolder holder, TuchongImagResponse.FeedListBean feedListBean) {
50 | final RatioImageView imageView = holder.getView(R.id.iv_img);
51 | imageView.setOriginalSize(50, 50);
52 | int limit = 48;
53 | String text = feedListBean.getTitle().length() > limit ? feedListBean.getTitle().substring(0, limit) +
54 | "..." : feedListBean.getTitle();
55 | ((TextView) holder.getView(R.id.tv_title)).setText(text);
56 |
57 | List images = feedListBean.getImages();
58 | if (images == null || images.isEmpty()) {
59 | return;
60 | }
61 | TuchongImagResponse.FeedListBean.ImagesBean imagesBean = images.get(0);
62 | if (imagesBean != null) {
63 | String url = "https://photo.tuchong.com/" + imagesBean.getUser_id() + "/f/" + imagesBean.getImg_id() + ".jpg";
64 | GlideApp.with(imageView.getContext())
65 | .load(url)
66 | .centerCrop()
67 | .transition(DrawableTransitionOptions.withCrossFade(500))
68 | .into(imageView)
69 | .getSize(new SizeReadyCallback() {
70 | @Override
71 | public void onSizeReady(int width, int height) {
72 | if (!holder.itemView.isShown()) {
73 | holder.itemView.setVisibility(View.VISIBLE);
74 | }
75 | }
76 | });
77 | holder.itemView.setTag(url);
78 | ViewCompat.setTransitionName(imageView, url);
79 | }
80 |
81 | final ArrayList imageList = new ArrayList<>();
82 | for (int i = 0; i < images.size(); i++) {
83 | TuchongImagResponse.FeedListBean.ImagesBean imageData = images.get(i);
84 | String url = "https://photo.tuchong.com/" + imageData.getUser_id() + "/f/" + imageData.getImg_id() + ".jpg";
85 | imageList.add(url);
86 | }
87 | holder.itemView.setOnClickListener(new View.OnClickListener() {
88 | @Override
89 | public void onClick(View v) {
90 | if (mOnImageItemClickListener != null) {
91 | mOnImageItemClickListener.setOnImageClick(imageView, imageList);
92 | }
93 | }
94 | });
95 | }
96 |
97 | public void setOnImageItemClickListener(OnImageItemClickListener onImageItemClickListener) {
98 | mOnImageItemClickListener = onImageItemClickListener;
99 | }
100 |
101 | public interface OnImageItemClickListener {
102 | void setOnImageClick(View view, ArrayList imageList);
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/ui/adapter/VideoRecyclerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.ui.adapter;
2 |
3 | import android.text.TextUtils;
4 | import android.view.View;
5 |
6 | import com.chad.library.adapter.base.BaseViewHolder;
7 | import com.chad.library.adapter.base.MultipleItemRvAdapter;
8 | import com.stx.xhb.enjoylife.model.entity.VideoResponse;
9 | import com.stx.xhb.enjoylife.ui.adapter.provider.BannerItemProvider;
10 | import com.stx.xhb.enjoylife.ui.adapter.provider.TextItemProvider;
11 | import com.stx.xhb.enjoylife.ui.adapter.provider.VideoItemProvider;
12 |
13 | import java.util.List;
14 |
15 | /**
16 | * @author: xiaohaibin.
17 | * @time: 2018/5/28
18 | * @mail:xhb_199409@163.com
19 | * @github:https://github.com/xiaohaibin
20 | * @describe: 开眼视频推荐适配器
21 | */
22 | public class VideoRecyclerAdapter extends MultipleItemRvAdapter {
23 |
24 | public static final int VIDEO = 1;
25 | public static final int TEXT = 2;
26 | public static final int BANNER=3;
27 |
28 | private VideoItemProvider.setOnItemClickListener mItemClickListener;
29 |
30 | public VideoRecyclerAdapter(List data) {
31 | super(data);
32 | finishInitialize();
33 | }
34 |
35 | @Override
36 | protected int getViewType(VideoResponse.IssueListEntity.ItemListEntity itemListEntity) {
37 | if ("video".equals(itemListEntity.getType())) {
38 | return VIDEO;
39 | } else if (itemListEntity.getType().startsWith("banner") && TextUtils.isEmpty(itemListEntity.getData().getActionUrl())) {
40 | return BANNER;
41 | } else {
42 | return TEXT;
43 | }
44 | }
45 |
46 | @Override
47 | public void registerItemProvider() {
48 | mProviderDelegate.registerProvider(new TextItemProvider());
49 | VideoItemProvider videoItemProvider = new VideoItemProvider();
50 | mProviderDelegate.registerProvider(videoItemProvider);
51 | mProviderDelegate.registerProvider(new BannerItemProvider());
52 | videoItemProvider.setItemClickListener(new VideoItemProvider.setOnItemClickListener() {
53 | @Override
54 | public void onItemClick(View view, VideoResponse.IssueListEntity.ItemListEntity data) {
55 | if (mItemClickListener != null) {
56 | mItemClickListener.onItemClick(view, data);
57 | }
58 | }
59 | });
60 | }
61 |
62 | public void setItemClickListener(VideoItemProvider.setOnItemClickListener itemClickListener) {
63 | mItemClickListener = itemClickListener;
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/ui/adapter/provider/BannerItemProvider.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.ui.adapter.provider;
2 |
3 | import android.util.Log;
4 | import android.widget.ImageView;
5 |
6 | import com.bumptech.glide.Glide;
7 | import com.bumptech.glide.load.engine.DiskCacheStrategy;
8 | import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;
9 | import com.chad.library.adapter.base.BaseViewHolder;
10 | import com.chad.library.adapter.base.provider.BaseItemProvider;
11 | import com.stx.xhb.enjoylife.R;
12 | import com.stx.xhb.enjoylife.config.GlideApp;
13 | import com.stx.xhb.enjoylife.model.entity.VideoResponse;
14 | import com.stx.xhb.enjoylife.ui.adapter.VideoRecyclerAdapter;
15 |
16 | /**
17 | * @author: xiaohaibin.
18 | * @time: 2018/5/29
19 | * @mail:xhb_199409@163.com
20 | * @github:https://github.com/xiaohaibin
21 | * @describe:
22 | */
23 | public class BannerItemProvider extends BaseItemProvider {
24 | @Override
25 | public int viewType() {
26 | return VideoRecyclerAdapter.BANNER;
27 | }
28 |
29 | @Override
30 | public int layout() {
31 | return R.layout.list_home_item_banner;
32 | }
33 |
34 | @Override
35 | public void convert(BaseViewHolder holder, VideoResponse.IssueListEntity.ItemListEntity itemListEntity, int i) {
36 | ImageView imageView = holder.getView(R.id.iv_banner);
37 | GlideApp.with(imageView.getContext())
38 | .load(itemListEntity.getData().getImage())
39 | .transition(DrawableTransitionOptions.withCrossFade())
40 | .diskCacheStrategy(DiskCacheStrategy.ALL)
41 | .into(imageView);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/ui/adapter/provider/TextItemProvider.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.ui.adapter.provider;
2 |
3 | import com.chad.library.adapter.base.BaseViewHolder;
4 | import com.chad.library.adapter.base.provider.BaseItemProvider;
5 | import com.stx.xhb.enjoylife.R;
6 | import com.stx.xhb.enjoylife.model.entity.VideoResponse;
7 | import com.stx.xhb.enjoylife.ui.adapter.VideoRecyclerAdapter;
8 |
9 | /**
10 | * @author: xiaohaibin.
11 | * @time: 2018/5/28
12 | * @mail:xhb_199409@163.com
13 | * @github:https://github.com/xiaohaibin
14 | * @describe:
15 | */
16 | public class TextItemProvider extends BaseItemProvider {
17 | @Override
18 | public int viewType() {
19 | return VideoRecyclerAdapter.TEXT;
20 | }
21 |
22 | @Override
23 | public int layout() {
24 | return R.layout.list_home_text_item;
25 | }
26 |
27 | @Override
28 | public void convert(BaseViewHolder holder, VideoResponse.IssueListEntity.ItemListEntity itemListEntity, int i) {
29 | if (itemListEntity.getType().startsWith("text")) {
30 | holder.setGone(R.id.tv_home_text, true);
31 | } else {
32 | holder.setGone(R.id.tv_home_text, false);
33 | }
34 | holder.setText(R.id.tv_home_text, itemListEntity.getData().getText());
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/ui/adapter/provider/VideoItemProvider.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.ui.adapter.provider;
2 |
3 | import android.view.View;
4 | import android.widget.ImageView;
5 |
6 | import com.bumptech.glide.Glide;
7 | import com.bumptech.glide.load.engine.DiskCacheStrategy;
8 | import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;
9 | import com.chad.library.adapter.base.BaseViewHolder;
10 | import com.chad.library.adapter.base.provider.BaseItemProvider;
11 | import com.stx.xhb.enjoylife.R;
12 | import com.stx.xhb.enjoylife.config.GlideApp;
13 | import com.stx.xhb.enjoylife.model.entity.VideoResponse;
14 | import com.stx.xhb.enjoylife.ui.adapter.VideoRecyclerAdapter;
15 |
16 | /**
17 | * @author: xiaohaibin.
18 | * @time: 2018/5/28
19 | * @mail:xhb_199409@163.com
20 | * @github:https://github.com/xiaohaibin
21 | * @describe:
22 | */
23 | public class VideoItemProvider extends BaseItemProvider {
24 | @Override
25 | public int viewType() {
26 | return VideoRecyclerAdapter.VIDEO;
27 | }
28 |
29 | @Override
30 | public int layout() {
31 | return R.layout.list_home_video_item;
32 | }
33 |
34 | @Override
35 | public void convert(BaseViewHolder holder, VideoResponse.IssueListEntity.ItemListEntity itemListEntity, int i) {
36 | //得到不同类型所需要的数据
37 | String feed = itemListEntity.getData().getCover().getFeed();
38 | String title = itemListEntity.getData().getTitle();
39 | String category = itemListEntity.getData().getCategory();
40 | category = "#" + category + " / ";
41 | int duration = itemListEntity.getData().getDuration();
42 |
43 | int last = duration % 60;
44 | String stringLast;
45 | if (last <= 9) {
46 | stringLast = "0" + last;
47 | } else {
48 | stringLast = last + "";
49 | }
50 |
51 | String durationString;
52 | int minit = duration / 60;
53 | if (minit < 10) {
54 | durationString = "0" + minit;
55 | } else {
56 | durationString = "" + minit;
57 | }
58 | String stringTime = durationString + "' " + stringLast + '"';
59 |
60 | final ImageView view = holder.getView(R.id.iv);
61 | GlideApp.with(view.getContext()).load(feed).diskCacheStrategy(DiskCacheStrategy.ALL).transition(DrawableTransitionOptions.withCrossFade()).into(view);
62 | holder.setText(R.id.tv_title, title);
63 | holder.setText(R.id.tv_time, String.valueOf(category + stringTime));
64 | }
65 |
66 | @Override
67 | public void onClick(BaseViewHolder holder, VideoResponse.IssueListEntity.ItemListEntity data, int position) {
68 | if (mItemClickListener != null) {
69 | mItemClickListener.onItemClick(holder.getView(R.id.iv), data);
70 | }
71 | }
72 |
73 | private setOnItemClickListener mItemClickListener;
74 |
75 | public void setItemClickListener(setOnItemClickListener itemClickListener) {
76 | mItemClickListener = itemClickListener;
77 | }
78 |
79 | public interface setOnItemClickListener {
80 | void onItemClick(View view, VideoResponse.IssueListEntity.ItemListEntity data);
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/ui/fragment/ZhihuFragment.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.ui.fragment;
2 |
3 |
4 | import android.os.Bundle;
5 | import android.support.v4.widget.SwipeRefreshLayout;
6 | import android.support.v7.widget.LinearLayoutManager;
7 | import android.support.v7.widget.RecyclerView;
8 | import android.text.TextUtils;
9 |
10 | import com.chad.library.adapter.base.BaseQuickAdapter;
11 | import com.stx.xhb.enjoylife.R;
12 | import com.stx.xhb.enjoylife.model.entity.ZhiHuNewsResponse;
13 | import com.stx.xhb.enjoylife.presenter.zhihu.getZhiHuNewsContract;
14 | import com.stx.xhb.enjoylife.presenter.zhihu.getZhiHuNewsIPresenterImpl;
15 | import com.stx.xhb.enjoylife.ui.adapter.NewsAdapter;
16 | import com.stx.xhb.enjoylife.utils.ToastUtil;
17 | import com.xhb.core.base.BaseFragment;
18 |
19 | import butterknife.BindView;
20 |
21 | /**
22 | * 知乎Fragment
23 | */
24 | public class ZhihuFragment extends BaseFragment implements getZhiHuNewsContract.View, SwipeRefreshLayout.OnRefreshListener {
25 |
26 |
27 | @BindView(R.id.recly_view)
28 | RecyclerView mReclyView;
29 | @BindView(R.id.refresh_layout)
30 | SwipeRefreshLayout mSwipeRefreshLayout;
31 | private String date = "";
32 | /**
33 | * 是否是第一次加载数据
34 | */
35 | private boolean isFirstLoad = false;
36 | private NewsAdapter mNewsAdapter;
37 |
38 | public static ZhihuFragment newInstance() {
39 | return new ZhihuFragment();
40 | }
41 |
42 | @Override
43 | protected int getLayoutResource() {
44 | return R.layout.fragment_common;
45 | }
46 |
47 | @Override
48 | protected Class getLogicClazz() {
49 | return getZhiHuNewsContract.class;
50 | }
51 |
52 | @Override
53 | protected void onInitView(Bundle savedInstanceState) {
54 | mReclyView.setLayoutManager(new LinearLayoutManager(getActivity()));
55 | mSwipeRefreshLayout.setColorSchemeResources(R.color.colorPrimary, R.color.colorPrimary);
56 | mNewsAdapter = new NewsAdapter(R.layout.list_item_news,getActivity());
57 | mSwipeRefreshLayout.setOnRefreshListener(this);
58 |
59 | mReclyView.setAdapter(mNewsAdapter);
60 | mNewsAdapter.openLoadAnimation();
61 | mNewsAdapter.setOnLoadMoreListener(new BaseQuickAdapter.RequestLoadMoreListener() {
62 | @Override
63 | public void onLoadMoreRequested() {
64 | onLoadMore();
65 | }
66 | }, mReclyView);
67 | }
68 |
69 | @Override
70 | protected void onVisible() {
71 | super.onVisible();
72 | mSwipeRefreshLayout.setRefreshing(true);
73 | onRefresh();
74 | }
75 |
76 | @Override
77 | public void onResponse(ZhiHuNewsResponse zhiHuNewsResponse) {
78 | onLoadComplete();
79 | mNewsAdapter.addData(zhiHuNewsResponse.getStories());
80 | date = zhiHuNewsResponse.getDate();
81 | if (isFirstLoad) {
82 | onLoadMore();
83 | }
84 | }
85 |
86 | @Override
87 | public void onFailure(String msg) {
88 | ToastUtil.show(msg);
89 | }
90 |
91 | @Override
92 | public void onRefresh() {
93 | date = "latest";
94 | isFirstLoad = true;
95 | ((getZhiHuNewsIPresenterImpl) mPresenter).getNews(date);
96 | }
97 |
98 | public void onLoadMore() {
99 | if (!TextUtils.isEmpty(date)) {
100 | isFirstLoad = false;
101 | ((getZhiHuNewsIPresenterImpl) mPresenter).getNewsBefore(date);
102 | }
103 | }
104 |
105 | private void onLoadComplete() {
106 | if ("latest".equals(date)) {
107 | mNewsAdapter.setNewData(null);
108 | mSwipeRefreshLayout.setRefreshing(false);
109 | } else {
110 | mNewsAdapter.loadMoreComplete();
111 | }
112 | }
113 |
114 | @Override
115 | public void onDestroyView() {
116 | super.onDestroyView();
117 | if (mSwipeRefreshLayout!=null) {
118 | mSwipeRefreshLayout.setRefreshing(false);
119 | }
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/ui/widget/CustomTextView.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.ui.widget;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.Context;
5 | import android.content.res.AssetManager;
6 | import android.graphics.Typeface;
7 | import android.util.AttributeSet;
8 | import android.widget.TextView;
9 |
10 | /**
11 | * Created by xhb on 2016/2/29.
12 | * 自定义特殊字体TextView
13 | */
14 | @SuppressLint("AppCompatCustomView")
15 | public class CustomTextView extends TextView {
16 | public CustomTextView(Context context) {
17 | super(context);
18 | init(context);
19 | }
20 |
21 | public CustomTextView(Context context, AttributeSet attrs) {
22 | super(context, attrs);
23 | init(context);
24 | }
25 |
26 | public CustomTextView(Context context, AttributeSet attrs, int defStyleAttr) {
27 | super(context, attrs, defStyleAttr);
28 | init(context);
29 | }
30 |
31 | /**
32 | * 设置字体
33 | * @param context
34 | */
35 | private void init(Context context){
36 | AssetManager assets = context.getAssets();
37 | Typeface font = Typeface.createFromAsset(assets, "fonts/Lobster-1.4.otf");
38 | setTypeface(font);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/ui/widget/RatioImageView.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Drakeet
3 | *
4 | * This file is part of Meizhi
5 | *
6 | * Meizhi is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Meizhi is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Meizhi. If not, see .
18 | */
19 |
20 | package com.stx.xhb.enjoylife.ui.widget;
21 |
22 | import android.annotation.SuppressLint;
23 | import android.content.Context;
24 | import android.util.AttributeSet;
25 | import android.widget.ImageView;
26 |
27 | @SuppressLint("AppCompatCustomView")
28 | public class RatioImageView extends ImageView {
29 |
30 | private int originalWidth;
31 | private int originalHeight;
32 |
33 | public RatioImageView(Context context) {
34 | super(context);
35 | }
36 |
37 | public RatioImageView(Context context, AttributeSet attrs) {
38 | super(context, attrs);
39 | }
40 |
41 | public RatioImageView(Context context, AttributeSet attrs, int defStyleAttr) {
42 | super(context, attrs, defStyleAttr);
43 | }
44 |
45 | public void setOriginalSize(int originalWidth, int originalHeight) {
46 | this.originalWidth = originalWidth;
47 | this.originalHeight = originalHeight;
48 | }
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 | if (width > 0) {
59 | height = (int) ((float) width / ratio);
60 | }
61 |
62 | setMeasuredDimension(width, height);
63 | } else {
64 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/ui/widget/RecyclerViewNoBugLinearLayoutManager.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.ui.widget;
2 |
3 | import android.content.Context;
4 | import android.support.v7.widget.LinearLayoutManager;
5 | import android.support.v7.widget.RecyclerView;
6 | import android.util.AttributeSet;
7 |
8 | /**
9 | * @author: xiaohaibin.
10 | * @time: 2018/3/28
11 | * @mail:xhb_199409@163.com
12 | * @github:https://github.com/xiaohaibin
13 | * @describe: fixed RecyclerView notifyDataChanged bug
14 | */
15 |
16 | public class RecyclerViewNoBugLinearLayoutManager extends LinearLayoutManager {
17 |
18 | public RecyclerViewNoBugLinearLayoutManager(Context context) {
19 | super( context );
20 | }
21 |
22 | public RecyclerViewNoBugLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
23 | super( context, orientation, reverseLayout );
24 | }
25 |
26 | public RecyclerViewNoBugLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
27 | super( context, attrs, defStyleAttr, defStyleRes );
28 | }
29 |
30 | @Override
31 | public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
32 | try {
33 | super.onLayoutChildren( recycler, state );
34 | } catch (IndexOutOfBoundsException e) {
35 | e.printStackTrace();
36 | }
37 |
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/ui/widget/RecyclerViewNoBugStaggeredGridLayoutManger.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.ui.widget;
2 |
3 | import android.content.Context;
4 | import android.support.v7.widget.RecyclerView;
5 | import android.support.v7.widget.StaggeredGridLayoutManager;
6 | import android.util.AttributeSet;
7 |
8 | /**
9 | * @author: xiaohaibin.
10 | * @time: 2018/3/28
11 | * @mail:xhb_199409@163.com
12 | * @github:https://github.com/xiaohaibin
13 | * @describe: fixed RecyclerView notifyDataChanged bug
14 | */
15 |
16 | public class RecyclerViewNoBugStaggeredGridLayoutManger extends StaggeredGridLayoutManager {
17 |
18 | public RecyclerViewNoBugStaggeredGridLayoutManger(int spanCount, int orientation) {
19 | super(spanCount, orientation);
20 | }
21 |
22 | public RecyclerViewNoBugStaggeredGridLayoutManger(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
23 | super(context, attrs, defStyleAttr, defStyleRes);
24 | }
25 |
26 | @Override
27 | public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
28 | super.onLayoutChildren(recycler, state);
29 | try {
30 | super.onLayoutChildren( recycler, state );
31 | } catch (IndexOutOfBoundsException e) {
32 | e.printStackTrace();
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/utils/NetConnectedUtils.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.utils;
2 |
3 | import android.content.Context;
4 | import android.net.ConnectivityManager;
5 | import android.net.NetworkInfo;
6 |
7 | /**
8 | * Created by xhb on 2016/1/20.
9 | * 网络状态工具类
10 | */
11 | public class NetConnectedUtils {
12 | /**
13 | * 1.判断网络是否连接
14 | *
15 | * @param context 上下文,通过它获取到ConnectivityManager
16 | * @return true 网络连接成功 false 网络连接失败
17 | */
18 | public static boolean isNetConnected(Context context) {
19 | boolean ret = false;
20 | //1.获取到ConnectivityManager
21 | ConnectivityManager connectivityManager
22 | = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
23 | //获取到当前活动的网络(即正在传输数据的网络),若存在,那么可以确定网络连接存在;
24 | //connectivityManager.getActiveNetwork(); 版本23新添加的,不建议这么早使用
25 |
26 | //返回当前正在传输数据的网络连接的信息,ApiManager 1 就存在了
27 | NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
28 |
29 | if (networkInfo == null) {//无网络连接
30 | return ret;
31 | }
32 |
33 | //网络是否可用
34 | // networkInfo.isAvailable();
35 | //网络是否连接
36 | // networkInfo.isConnected();
37 | //只有两个都满足才能确保网络是连接上的
38 | ret = networkInfo.isAvailable() & networkInfo.isConnected();
39 | return ret;
40 | }
41 |
42 | /**
43 | * 2.判断手机网络是否存在
44 | *
45 | * @param context 上下文
46 | * @return 返回 false 无手机网络 true 有手机网络
47 | */
48 | public static boolean isPhoneNetConnected(Context context) {
49 | int typeMobile = ConnectivityManager.TYPE_MOBILE;//手机网络类型
50 | return isNetworkConnected(context, typeMobile);
51 | }
52 |
53 |
54 | /**
55 | * 2.判断WIFI网络是否存在
56 | *
57 | * @param context 上下文
58 | * @return 返回 false 无wifi网络 true 有wifi网络
59 | */
60 | public static boolean isWifiNetConnected(Context context) {
61 | int typeMobile = ConnectivityManager.TYPE_WIFI;//WIFI网络类型
62 | return isNetworkConnected(context, typeMobile);
63 | }
64 |
65 | /**
66 | * 返回网络是否连接
67 | *
68 | * @param context 上下文
69 | * @param typeMobile 网络类型
70 | * @return true 有网络连接 false 无网络连接
71 | */
72 | private static boolean isNetworkConnected(Context context, int typeMobile) {
73 | boolean ret = false;
74 | //判断是否有网络
75 | if (!isNetConnected(context)) {
76 | //如果没有网络连接,直接返回
77 | return ret;
78 | }
79 | //获取到网络连接管理器
80 | ConnectivityManager connectManger = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
81 | //当获取到网络连接信息的时候,可以获取到某一个类型的网络连接
82 | //获取到手机网络的信息
83 | NetworkInfo networkInfo = connectManger.getNetworkInfo(typeMobile);
84 | //如果不存在,那么就没有连接了
85 | if (networkInfo == null) {
86 | return ret;
87 | }
88 | //判断手机网络是否可用
89 | ret = networkInfo.isAvailable() & networkInfo.isConnected();
90 | return ret;
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/utils/ShareUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Drakeet
3 | *
4 | * This file is part of Meizhi
5 | *
6 | * Meizhi is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Meizhi is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Meizhi. If not, see .
18 | */
19 |
20 | package com.stx.xhb.enjoylife.utils;
21 |
22 | import android.content.Context;
23 | import android.content.Intent;
24 | import android.net.Uri;
25 |
26 | import com.stx.xhb.enjoylife.R;
27 |
28 | /**
29 | * Created by xiaohaibin on 7/12/16.
30 | * 分享工具类
31 | */
32 | public class ShareUtils {
33 |
34 | public static void share(Context context, int stringRes) {
35 | share(context, context.getString(stringRes));
36 | }
37 |
38 | /**
39 | * 分享图片
40 | * @param context
41 | * @param uri
42 | * @param title
43 | */
44 | public static void shareImage(Context context, Uri uri, String title) {
45 | Intent shareIntent = new Intent();
46 | shareIntent.setAction(Intent.ACTION_SEND);
47 | shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
48 | shareIntent.setType("image/jpeg");
49 | context.startActivity(Intent.createChooser(shareIntent, title));
50 | }
51 |
52 | /**
53 | * 分享文本内容
54 | * @param context
55 | * @param extraText
56 | */
57 | public static void share(Context context, String extraText) {
58 | Intent intent = new Intent(Intent.ACTION_SEND);
59 | intent.setType("text/plain");
60 | intent.putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.action_share));
61 | intent.putExtra(Intent.EXTRA_TEXT, extraText);
62 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
63 | context.startActivity(
64 | Intent.createChooser(intent, context.getString(R.string.action_share)));
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/app/src/main/java/com/stx/xhb/enjoylife/utils/ToastUtil.java:
--------------------------------------------------------------------------------
1 | package com.stx.xhb.enjoylife.utils;
2 | import android.widget.Toast;
3 | import com.stx.xhb.enjoylife.MyApplication;
4 |
5 | /**
6 | * Description:Toast工具
7 | */
8 | public class ToastUtil {
9 |
10 | /**
11 | * @param charSequence 显示文字
12 | */
13 | public static void show(CharSequence charSequence) {
14 | show(charSequence, Toast.LENGTH_SHORT);
15 | }
16 |
17 | /**
18 | * @param charSequence 显示文字
19 | * @param duration 显示时长 Toast.LENGTH_LONG/LENGTH_SHORT
20 | */
21 | public static void show(CharSequence charSequence, int duration) {
22 | MyApplication.ToastManager.instance.show(charSequence, duration);
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/splash_fade_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/splash_fade_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-hdpi/ic_logo.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/iconfont_downgrey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-hdpi/iconfont_downgrey.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi-v4/action_pause.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xhdpi-v4/action_pause.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi-v4/action_reload.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xhdpi-v4/action_reload.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi-v4/ic_action_play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xhdpi-v4/ic_action_play.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi-v4/ic_player_close_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xhdpi-v4/ic_player_close_white.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi-v4/ic_player_next.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xhdpi-v4/ic_player_next.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi-v4/ic_player_pause.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xhdpi-v4/ic_player_pause.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi-v4/ic_player_play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xhdpi-v4/ic_player_play.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi-v4/ic_player_progress_handle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xhdpi-v4/ic_player_progress_handle.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi-v4/ic_player_reload.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xhdpi-v4/ic_player_reload.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi-v4/ic_player_volume_down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xhdpi-v4/ic_player_volume_down.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi-v4/ic_player_volume_up.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xhdpi-v4/ic_player_volume_up.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi-v4/landing_background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xhdpi-v4/landing_background.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi-v4/landing_countdown_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xhdpi-v4/landing_countdown_background.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi-v4/video_player_bg_color.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xhdpi-v4/video_player_bg_color.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi-v4/videobg.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xhdpi-v4/videobg.9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xhdpi/bg.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/shape_rec_90000000_corner_4dp.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi-v4/light_100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xxhdpi-v4/light_100.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi-v4/light_20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xxhdpi-v4/light_20.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi-v4/light_30.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xxhdpi-v4/light_30.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi-v4/light_40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xxhdpi-v4/light_40.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi-v4/light_50.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xxhdpi-v4/light_50.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi-v4/light_60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xxhdpi-v4/light_60.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi-v4/light_70.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xxhdpi-v4/light_70.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi-v4/light_80.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xxhdpi-v4/light_80.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi-v4/light_90.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xxhdpi-v4/light_90.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi-v4/video_volumn_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xxhdpi-v4/video_volumn_bg.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi-v4/volmn_100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xxhdpi-v4/volmn_100.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi-v4/volmn_30.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xxhdpi-v4/volmn_30.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi-v4/volmn_60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xxhdpi-v4/volmn_60.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi-v4/volmn_no.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xxhdpi-v4/volmn_no.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_card_overflow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xxhdpi/ic_card_overflow.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/splash_bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable-xxhdpi/splash_bg.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/web_progress_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
11 |
12 |
13 | -
14 |
15 |
16 |
17 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_card.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/drawable/bg_card.9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_card_nopic.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 |
10 | -
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/boman_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/gradient.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_arrow_upward_white_24px.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_more_vert_black_24px.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_photo_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_settings_black_24px.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_share_white_24px.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_sort_black_24px.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_video_black_24px.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/icon_picture_black_24px.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/icon_tv_black_24px.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/icon_zhihu_black_24px.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/paly_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/selector_select_on_sale_time_text_color.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/selector_trade_white_orange_btn_10dp.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_rec_blue_corner_pressed_10dp.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_rec_gray_corner_disable_10dp.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_rec_white_corner_normal_10dp.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/video_new_progress.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 |
10 | -
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | -
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/video_new_seekbar_progress.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 |
10 | -
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | -
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/video_new_seekbar_thumb.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/video_new_volume_progress_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 | -
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/video_seek_new_thumb_normal.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/video_seek_new_thumb_press.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
15 |
16 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_photo_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
12 |
15 |
16 |
20 |
21 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_play.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_settting.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
13 |
14 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_splash.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_video_detail.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
15 |
16 |
24 |
25 |
26 |
27 |
31 |
32 |
37 |
38 |
43 |
44 |
49 |
50 |
51 |
52 |
56 |
57 |
62 |
63 |
66 |
67 |
73 |
74 |
82 |
83 |
90 |
91 |
99 |
100 |
101 |
102 |
103 |
104 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_web_details.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
22 |
23 |
24 |
25 |
29 |
30 |
33 |
34 |
39 |
40 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/app_bar_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
15 |
16 |
20 |
21 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_common.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/include_layout_line_panding.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_photoview.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
11 |
12 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_home_item_banner.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_home_text_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_home_video_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
16 |
17 |
23 |
24 |
29 |
30 |
38 |
39 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item_news.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
16 |
17 |
21 |
22 |
25 |
26 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item_selet_tv_primary.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
19 |
20 |
21 |
22 |
23 |
24 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item_selet_tv_sub.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item_tuchong.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
20 |
21 |
30 |
31 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item_wall_paper.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/nav_header_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
15 |
16 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/toolbar_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/view_toast.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/activity_main_drawer.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_about.xml:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_more.xml:
--------------------------------------------------------------------------------
1 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/enjoylife.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/mipmap-xxhdpi/enjoylife.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #03a9f4
4 | #03a9f4
5 | #03a9f4
6 | #FFFFFF
7 | #000000
8 | #03a9f4
9 | #888888
10 | #bbbbbb
11 | #008cf0
12 | #ededed
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 | 16dp
6 | 220dp
7 | 16dp
8 | 0dp
9 | 3dp
10 | 16sp
11 | 230dp
12 | 8dp
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | 乐享
3 | Open navigation drawer
4 | Close navigation drawer
5 | 生活的美好,需要你用心去发现,用眼去摄录
6 | 知乎日报
7 | 视频推荐
8 | 图虫摄影
9 | 图虫壁纸
10 | 设置
11 | 关于
12 | 应用简介
13 | 用到的开源库
14 | \ncom.android.support:appcompat-v7:25.4.0\ncom.android.support:recyclerview-v7:25.4.0\ncom.android.support:design:25.4.0\ncom.github.bumptech.glide:glide:3.7.0\ncom.shuyu:GSYVideoPlayer:2.0.2\ncom.github.chrisbanes:PhotoView:2.1.3\ncom.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.40\ncom.jaeger.statusbaruitl:library:1.3.6\n...
15 | 作者简介
16 | 一个热衷于移动开发、喜欢摄影、旅游和美食的程序猿...
17 | 分享给朋友
18 | 保存
19 | 设为壁纸
20 | 分享
21 | 图片已保存至 %s 文件夹
22 | 图片保存失败,请重试
23 | 保存到手机?
24 | 发现了一款非常棒的App「乐享」,每天一张精选妹纸图、一个精选短视频,知乎美文,完全开源不收费,太赞了! 下载地址:https://www.coolapk.com/apk/185913
25 | 每天一张精选妹纸图、一个精选小视频,一篇知乎美文。\n\n图片数据内容来源于图虫摄影网 \n\n视频数据来源于开眼视频 \n\n我的 GitHub: https://github.com/xiaohaibin\n\n完全开源,如果你觉得不错,可以帮忙分享给你更多的朋友,这是我最大的动力和支持,非常感谢!\n\n
26 | 图片预览
27 | 分享至…
28 | 分享这个新闻
29 | 分享图片至...
30 | 穿越茫茫人海\n寻找属于我们的那一份宁静
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
27 |
28 |
32 |
33 |
36 |
37 |
41 |
42 |
46 |
47 |
51 |
52 |
55 |
56 |
62 |
63 |
72 |
73 |
80 |
81 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 |
6 | jcenter()
7 | maven {
8 | url 'https://maven.google.com/'
9 | name 'Google'
10 | }
11 | }
12 | dependencies {
13 | classpath 'com.android.tools.build:gradle:3.1.3'
14 | // NOTE: Do not place your application dependencies here; they belong
15 | // in the individual module build.gradle files
16 | }
17 | }
18 |
19 | allprojects {
20 | repositories {
21 | jcenter()
22 | maven { url 'https://jitpack.io' }
23 | maven {
24 | url 'https://maven.google.com/'
25 | name 'Google'
26 | }
27 | }
28 | }
29 |
30 | task clean(type: Delete) {
31 | delete rootProject.buildDir
32 | }
33 |
--------------------------------------------------------------------------------
/core/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/core/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 27
5 | defaultConfig {
6 | minSdkVersion 15
7 | targetSdkVersion 27
8 | }
9 | buildTypes {
10 | release {
11 | minifyEnabled false
12 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
13 | }
14 | }
15 | }
16 |
17 | dependencies {
18 | api fileTree(dir: 'libs', include: ['*.jar'])
19 | api 'com.android.support:appcompat-v7:27.1.1'
20 | api 'com.android.support:recyclerview-v7:27.1.1'
21 | api 'com.android.support:design:27.1.1'
22 | api 'com.android.support:cardview-v7:27.1.1'
23 | //squareup
24 | api 'com.squareup.retrofit2:retrofit:2.3.0'
25 | api 'com.squareup.retrofit2:converter-gson:2.4.0'
26 | api 'com.squareup.retrofit2:adapter-rxjava:2.2.0'
27 | api 'com.squareup.okhttp3:logging-interceptor:3.8.1'
28 |
29 | api 'com.jakewharton:butterknife:8.8.1'
30 | annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
31 |
32 | api 'com.squareup.picasso:picasso:2.5.2'
33 | api 'io.reactivex:rxjava:1.2.1'
34 | api 'io.reactivex:rxandroid:1.2.1'
35 | //友盟统计
36 | api 'com.umeng.sdk:common:latest.integration'
37 | api 'com.umeng.analytics:analytics:latest.integration'
38 | //状态栏工具类
39 | api 'com.jaeger.statusbaruitl:library:1.3.6'
40 | api 'com.orhanobut:logger:2.2.0'
41 | api 'com.github.chrisbanes:PhotoView:2.1.3'
42 | }
43 |
44 |
--------------------------------------------------------------------------------
/core/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 /home/zjl/Android/AndroidSdk/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 |
--------------------------------------------------------------------------------
/core/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/core/src/main/java/com/xhb/core/BaseApplication.java:
--------------------------------------------------------------------------------
1 | package com.xhb.core;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 | import com.xhb.core.util.LoggerHelper;
6 |
7 | public class BaseApplication extends Application {
8 |
9 | private static Context mContext;
10 | public static Context getContext() {
11 | return mContext;
12 | }
13 |
14 | @Override
15 | public void onCreate() {
16 | super.onCreate();
17 | mContext = getApplicationContext();
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/core/src/main/java/com/xhb/core/adapter/RecyclerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.xhb.core.adapter;
2 |
3 | import android.content.Context;
4 | import android.support.v7.widget.RecyclerView;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 |
9 | import java.util.List;
10 |
11 | public abstract class RecyclerAdapter extends RecyclerView.Adapter {
12 | protected Context mContext;
13 | protected int mLayoutId;
14 | protected List mDatas;
15 | protected LayoutInflater mInflater;
16 |
17 | private OnItemClickListener mOnItemClickListener;
18 |
19 | public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
20 | this.mOnItemClickListener = onItemClickListener;
21 | }
22 |
23 | public RecyclerAdapter(Context context, int layoutId, List datas) {
24 | mContext = context;
25 | mInflater = LayoutInflater.from(context);
26 | mLayoutId = layoutId;
27 | mDatas = datas;
28 | }
29 |
30 | @Override
31 | public RecyclerViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
32 | RecyclerViewHolder viewHolder = RecyclerViewHolder.get(mContext, null, parent, mLayoutId, -1);
33 | setListener(parent, viewHolder, viewType);
34 | return viewHolder;
35 | }
36 |
37 | protected int getPosition(RecyclerViewHolder viewHolder) {
38 | return viewHolder.getAdapterPosition();
39 | }
40 |
41 | protected boolean isEnabled(int viewType) {
42 | return true;
43 | }
44 |
45 | protected void setListener(final ViewGroup parent, final RecyclerViewHolder viewHolder, int viewType) {
46 | if (!isEnabled(viewType)) return;
47 | viewHolder.getConvertView().setOnClickListener(new View.OnClickListener() {
48 | @Override
49 | public void onClick(View v) {
50 | if (mOnItemClickListener != null) {
51 | int position = getPosition(viewHolder);
52 | mOnItemClickListener.onItemClick(parent, v, mDatas.get(position), position);
53 | }
54 | }
55 | });
56 |
57 | viewHolder.getConvertView().setOnLongClickListener(new View.OnLongClickListener() {
58 | @Override
59 | public boolean onLongClick(View v) {
60 | if (mOnItemClickListener != null) {
61 | int position = getPosition(viewHolder);
62 | return mOnItemClickListener.onItemLongClick(parent, v, mDatas.get(position), position);
63 | }
64 | return false;
65 | }
66 | });
67 | }
68 |
69 | @Override
70 | public void onBindViewHolder(RecyclerViewHolder hepler, int position) {
71 | hepler.updatePosition(position);
72 | convert(hepler, mDatas.get(position));
73 | }
74 |
75 | public abstract void convert(RecyclerViewHolder holder, T t);
76 |
77 | @Override
78 | public int getItemCount() {
79 | return mDatas!= null ? mDatas.size() : 0;
80 | }
81 |
82 |
83 | public interface OnItemClickListener {
84 | void onItemClick(ViewGroup parent, View view, T t, int position);
85 |
86 | boolean onItemLongClick(ViewGroup parent, View view, T t, int position);
87 | }
88 |
89 | }
--------------------------------------------------------------------------------
/core/src/main/java/com/xhb/core/api/HttpCacheInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.xhb.core.api;
2 |
3 | import com.xhb.core.BaseApplication;
4 | import com.xhb.core.util.NetworkUtil;
5 |
6 | import java.io.IOException;
7 |
8 | import okhttp3.CacheControl;
9 | import okhttp3.Interceptor;
10 | import okhttp3.Request;
11 | import okhttp3.Response;
12 |
13 | public class HttpCacheInterceptor implements Interceptor {
14 |
15 | @Override
16 | public Response intercept(Chain chain) throws IOException {
17 | Request request = chain.request();
18 | if (!NetworkUtil.isInternetConnection(BaseApplication.getContext())) {
19 | request = request.newBuilder()
20 | .cacheControl(CacheControl.FORCE_CACHE)
21 | .build();
22 | }
23 |
24 | Response response = chain.proceed(request);
25 |
26 | if (NetworkUtil.isInternetConnection(BaseApplication.getContext())) {
27 | int maxAge = 60 * 60; // read from cache for 1 minute
28 | response.newBuilder()
29 | .removeHeader("Pragma")
30 | .header("Cache-Control", "public, max-age=" + maxAge)
31 | .build();
32 | } else {
33 | int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale
34 | response.newBuilder()
35 | .removeHeader("Pragma")
36 | .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
37 | .build();
38 | }
39 | return response;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/core/src/main/java/com/xhb/core/api/RestApi.java:
--------------------------------------------------------------------------------
1 | package com.xhb.core.api;
2 |
3 | import android.text.TextUtils;
4 | import android.util.Log;
5 |
6 | import com.xhb.core.util.LoggerHelper;
7 |
8 | import java.lang.reflect.Field;
9 |
10 | import okhttp3.OkHttpClient;
11 | import okhttp3.logging.HttpLoggingInterceptor;
12 | import retrofit2.Retrofit;
13 | import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
14 | import retrofit2.converter.gson.GsonConverterFactory;
15 |
16 | import static android.content.ContentValues.TAG;
17 |
18 | public class RestApi {
19 |
20 | private static final String TAG = "===Enjoy";
21 | private static RestApi mInstance;
22 | public static boolean isDebug = false;
23 |
24 | public static synchronized RestApi getInstance() {
25 | if (mInstance == null) {
26 | mInstance = new RestApi();
27 | }
28 | return mInstance;
29 | }
30 |
31 | public void bug(boolean isDebug) {
32 | RestApi.isDebug = isDebug;
33 | }
34 |
35 | // create retrofit singleton
36 | private Retrofit createApiClient(String baseUrl) {
37 | return new Retrofit.Builder()
38 | .baseUrl(baseUrl)
39 | .addConverterFactory(GsonConverterFactory.create())
40 | .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
41 | .client(createOkHttpClient())
42 | .build();
43 | }
44 |
45 | // create api service singleton
46 | public T create(String baseUrl, Class clz) {
47 | String serviceUrl = "";
48 | try {
49 | Field field1 = clz.getField("BASE_URL");
50 | serviceUrl = (String) field1.get(clz);
51 | } catch (NoSuchFieldException e) {
52 | e.printStackTrace();
53 | } catch (IllegalAccessException e) {
54 | e.getMessage();
55 | e.printStackTrace();
56 | }
57 | return createApiClient(
58 | TextUtils.isEmpty(serviceUrl) ? baseUrl : serviceUrl).create(clz);
59 | }
60 |
61 | // create api service baseUrl singleton
62 | public T create(Class clz) {
63 | String serviceUrl = "";
64 | try {
65 | Field field1 = clz.getField("BASE_URL");
66 | serviceUrl = (String) field1.get(clz);
67 | if (TextUtils.isEmpty(serviceUrl)) {
68 | throw new NullPointerException("base_url is null");
69 | }
70 | } catch (Exception e) {
71 | e.printStackTrace();
72 | }
73 | return createApiClient(serviceUrl).create(clz);
74 | }
75 |
76 | // create okHttpClient singleton
77 | private OkHttpClient createOkHttpClient() {
78 | return new OkHttpClient.Builder()
79 | .addNetworkInterceptor(new HttpCacheInterceptor())
80 | .addInterceptor(
81 | new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
82 | @Override
83 | public void log(String message) {
84 | if (message.startsWith("{") || message.startsWith("[")) {
85 | LoggerHelper.json(TAG,message);
86 | } else {
87 | LoggerHelper.d(TAG,message);
88 | }
89 | }
90 | }).setLevel(HttpLoggingInterceptor.Level.BODY)).build();
91 | }
92 |
93 | }
94 |
--------------------------------------------------------------------------------
/core/src/main/java/com/xhb/core/base/BaseFragment.java:
--------------------------------------------------------------------------------
1 | package com.xhb.core.base;
2 |
3 | import android.app.Fragment;
4 | import android.content.Context;
5 | import android.os.Bundle;
6 | import android.support.annotation.Nullable;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 |
11 | import com.orhanobut.logger.Logger;
12 | import com.xhb.core.model.LogicProxy;
13 |
14 | import butterknife.ButterKnife;
15 | import butterknife.Unbinder;
16 |
17 | public abstract class BaseFragment extends Fragment implements IBaseView {
18 |
19 | protected BaseIPresenter mPresenter;
20 | protected View rootView;
21 | protected Context mContext = null;
22 | //是否可见
23 | protected boolean isViable = false;
24 |
25 | // 标志位,标志Fragment已经初始化完成。
26 | protected boolean isPrepared = false;
27 |
28 | //标记已加载完成,保证懒加载只能加载一次
29 | protected boolean hasLoaded = false;
30 | private Unbinder mBind;
31 |
32 | protected abstract int getLayoutResource();
33 |
34 | protected abstract void onInitView(Bundle savedInstanceState);
35 |
36 | protected Class getLogicClazz() {
37 | return null;
38 | }
39 |
40 | protected void onInitData2Remote() {
41 | if (getLogicClazz() != null) {
42 | mPresenter = getLogicImpl();
43 | }
44 | }
45 |
46 | @Nullable
47 | @Override
48 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
49 | if (getLayoutResource() != 0) {
50 | rootView = inflater.inflate(getLayoutResource(), null);
51 | } else {
52 | rootView = super.onCreateView(inflater, container, savedInstanceState);
53 | }
54 | onInitData2Remote();
55 | mBind = ButterKnife.bind(this, rootView);
56 | onInitView(savedInstanceState);
57 | return rootView;
58 | }
59 |
60 | @Override
61 | public void onCreate(Bundle savedInstanceState) {
62 | super.onCreate(savedInstanceState);
63 | Logger.d("name (%s.java:0)", getClass().getSimpleName());
64 | mContext = getActivity();
65 | }
66 |
67 | @Override
68 | public void onViewCreated(View view, Bundle savedInstanceState) {
69 | super.onViewCreated(view, savedInstanceState);
70 | if (!isPrepared && getUserVisibleHint()) {
71 | onFragmentVisibleChange(true);
72 | isViable = true;
73 | }
74 | }
75 |
76 | //获得该页面的实例
77 | public T getLogicImpl() {
78 | return LogicProxy.getInstance().bind(getLogicClazz(), this);
79 | }
80 |
81 | @Override
82 | public void onStart() {
83 | if (mPresenter != null && mPresenter.isViewBind()) {
84 | LogicProxy.getInstance().bind(getLogicClazz(), this);
85 | }
86 | super.onStart();
87 | }
88 |
89 | @Override
90 | public void onDestroy() {
91 | super.onDestroy();
92 | mBind.unbind();
93 | if (mPresenter != null) {
94 | mPresenter.detachView();
95 | }
96 | }
97 |
98 | /**
99 | * 在这里实现Fragment数据的缓加载.
100 | *
101 | * @param isVisibleToUser
102 | */
103 | @Override
104 | public void setUserVisibleHint(boolean isVisibleToUser) {
105 | super.setUserVisibleHint(isVisibleToUser);
106 | if (rootView == null) {
107 | return;
108 | }
109 | isPrepared = true;
110 | if (isVisibleToUser) {
111 | onFragmentVisibleChange(true);
112 | isViable = true;
113 | return;
114 | }
115 |
116 | if (isViable) {
117 | onFragmentVisibleChange(false);
118 | isViable = false;
119 | }
120 | }
121 |
122 | /**
123 | * 当前fragment可见状态发生变化时会回调该方法
124 | *
125 | * @param isVisible
126 | */
127 | protected void onFragmentVisibleChange(boolean isVisible) {
128 | if (isVisible) {
129 | onVisible();
130 | } else {
131 | onInVisible();
132 | }
133 | }
134 | /**
135 | * 当界面可见时的操作
136 | */
137 | protected void onVisible() {
138 | if (hasLoaded) {
139 | return;
140 | }
141 | lazyLoad();
142 | hasLoaded = true;
143 | }
144 |
145 |
146 | /**
147 | * 数据懒加载
148 | */
149 | protected void lazyLoad() {
150 |
151 | }
152 |
153 | /**
154 | * 当界面不可见时的操作
155 | */
156 | protected void onInVisible() {
157 |
158 | }
159 |
160 | }
161 |
--------------------------------------------------------------------------------
/core/src/main/java/com/xhb/core/base/BaseIPresenter.java:
--------------------------------------------------------------------------------
1 | package com.xhb.core.base;
2 |
3 | import retrofit2.Call;
4 | import retrofit2.Callback;
5 | import retrofit2.Response;
6 |
7 | public class BaseIPresenter implements IPresenter {
8 |
9 | private V mView;
10 | private Call mResponseCall;
11 |
12 | @Override
13 | public void attachView(V mvpView) {
14 | this.mView = mvpView;
15 | }
16 |
17 | @Override
18 | public void detachView() {
19 | this.mView = null;
20 | if (mResponseCall != null) {
21 | mResponseCall.cancel();
22 | }
23 | }
24 |
25 | protected void request(Call call, final LoadTaskCallback callback) {
26 | this.mResponseCall = call;
27 | call.enqueue(new Callback() {
28 | @Override
29 | public void onResponse(Call call, Response response) {
30 | if (response.isSuccessful() && response.body() != null) {
31 | callback.onTaskLoaded(response.body());
32 | } else {
33 | callback.onDataNotAvailable(response.message());
34 | }
35 | }
36 |
37 | @Override
38 | public void onFailure(Call call, Throwable t) {
39 | callback.onDataNotAvailable(t.getMessage());
40 | }
41 | });
42 | }
43 |
44 | public boolean isViewBind() {
45 | return mView == null;
46 | }
47 |
48 | public V getView() {
49 | return mView;
50 | }
51 |
52 | public interface LoadTaskCallback {
53 |
54 | void onTaskLoaded(T data);
55 |
56 | void onDataNotAvailable(String msg);
57 | }
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/core/src/main/java/com/xhb/core/base/BaseSwipeBackActivity.java:
--------------------------------------------------------------------------------
1 | package com.xhb.core.base;
2 |
3 | import android.os.Bundle;
4 | import android.support.v7.app.AppCompatActivity;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.Window;
8 | import android.widget.ImageView;
9 | import android.widget.RelativeLayout;
10 | import android.widget.RelativeLayout.LayoutParams;
11 |
12 | import com.xhb.core.R;
13 | import com.xhb.core.ui.SwipeBackLayout;
14 |
15 | public abstract class BaseSwipeBackActivity extends AppCompatActivity implements SwipeBackLayout.SwipeBackListener {
16 |
17 | private SwipeBackLayout swipeBackLayout;
18 | private ImageView ivShadow;
19 |
20 | @Override
21 | protected void onCreate(Bundle savedInstanceState) {
22 | super.onCreate(savedInstanceState);
23 | requestWindowFeature(Window.FEATURE_NO_TITLE);
24 | }
25 |
26 | @Override
27 | public void setContentView(int layoutResID) {
28 | super.setContentView(getContainer());
29 | View view = LayoutInflater.from(this).inflate(layoutResID, null);
30 | swipeBackLayout.addView(view);
31 | }
32 |
33 | private View getContainer() {
34 | RelativeLayout container = new RelativeLayout(this);
35 | swipeBackLayout = new SwipeBackLayout(this);
36 | swipeBackLayout.setOnSwipeBackListener(this);
37 | ivShadow = new ImageView(this);
38 | ivShadow.setBackgroundColor(getResources().getColor(R.color.abc_theme_black_7f));
39 | LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
40 | container.addView(ivShadow, params);
41 | container.addView(swipeBackLayout);
42 | return container;
43 | }
44 |
45 | public void setDragEdge(SwipeBackLayout.DragEdge dragEdge) {
46 | swipeBackLayout.setDragEdge(dragEdge);
47 | }
48 |
49 | public SwipeBackLayout getSwipeBackLayout() {
50 | return swipeBackLayout;
51 | }
52 |
53 | @Override
54 | public void onViewPositionChanged(float fractionAnchor, float fractionScreen) {
55 | ivShadow.setAlpha(1 - fractionScreen);
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/core/src/main/java/com/xhb/core/base/IBaseView.java:
--------------------------------------------------------------------------------
1 | package com.xhb.core.base;
2 |
3 | public interface IBaseView {
4 | }
5 |
--------------------------------------------------------------------------------
/core/src/main/java/com/xhb/core/base/IModel.java:
--------------------------------------------------------------------------------
1 | package com.xhb.core.base;
2 |
3 | /**
4 | * @author: xiaohaibin.
5 | * @time: 2018/6/27
6 | * @mail:xhb_199409@163.com
7 | * @github:https://github.com/xiaohaibin
8 | * @describe:
9 | */
10 | public interface IModel {
11 | }
12 |
--------------------------------------------------------------------------------
/core/src/main/java/com/xhb/core/base/IPresenter.java:
--------------------------------------------------------------------------------
1 | package com.xhb.core.base;
2 |
3 | public interface IPresenter {
4 | void attachView(V mvpView);
5 | void detachView();
6 | }
7 |
--------------------------------------------------------------------------------
/core/src/main/java/com/xhb/core/manage/crash/AndroidCrash.java:
--------------------------------------------------------------------------------
1 | package com.xhb.core.manage.crash;
2 |
3 | import android.content.Context;
4 | import android.os.Looper;
5 | import android.os.Process;
6 |
7 | import com.xhb.core.manage.interfacee.HttpReportCallback;
8 |
9 | import java.io.File;
10 | import java.text.SimpleDateFormat;
11 | import java.util.Date;
12 |
13 | public class AndroidCrash implements Thread.UncaughtExceptionHandler {
14 |
15 | private static AndroidCrash sInstance = new AndroidCrash();
16 | private Thread.UncaughtExceptionHandler mDefaultCrashHandler;
17 | private Context mContext;
18 | private HttpReportCallback mCallback;
19 |
20 | public AndroidCrash() {
21 | }
22 |
23 | public static AndroidCrash getInstance() {
24 | return sInstance;
25 | }
26 |
27 | //初始化
28 | public void init(Context context) {
29 | mDefaultCrashHandler = Thread.getDefaultUncaughtExceptionHandler();
30 | Thread.setDefaultUncaughtExceptionHandler(this);
31 | mContext = context.getApplicationContext();
32 | }
33 |
34 | //应用异常系统会调用此方法
35 | @Override
36 | public void uncaughtException(final Thread thread, final Throwable ex) {
37 | long current = System.currentTimeMillis();
38 | String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(current));
39 | final File file = new File(LogWriter.PATH + LogWriter.FILE_NAME + time + LogWriter.FILE_NAME_SUFFIX);
40 |
41 | //为了防止上传时文件没有写入完成
42 | LogWriter.writeLog(mContext, ex, file, time, new LogWriter.WriteCallback() {
43 | @Override
44 | public void writeSuccess() {
45 | if (mCallback != null) {
46 | //上传到服务器
47 | uploadException2remote(file);
48 | }
49 | }
50 | });
51 |
52 | ex.printStackTrace();
53 |
54 | //如果系统提供了默认的一场处理,则交给系统去结束异常,否则自己处理
55 | new Thread(new Runnable() {
56 | @Override
57 | public void run() {
58 | Looper.prepare();
59 | try {
60 | //处理错误
61 | if (mDefaultCrashHandler != null) {
62 | mDefaultCrashHandler.uncaughtException(thread, ex);
63 | }else {
64 | Process.killProcess(Process.myPid());
65 | }
66 | } catch (Exception e) {
67 | e.printStackTrace();
68 | }
69 | Looper.loop();
70 | }
71 | }).start();
72 |
73 | }
74 |
75 | //不调用这个方法 callback 是null 所以就会上传服务器的方法
76 | public AndroidCrash setCrashReporter(HttpReportCallback callback) {
77 | this.mCallback = callback;
78 | return this;
79 | }
80 |
81 | private void uploadException2remote(File file) {
82 | //上传服务器
83 | mCallback.uploadException2remote(file);
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/core/src/main/java/com/xhb/core/manage/crash/LogWriter.java:
--------------------------------------------------------------------------------
1 | package com.xhb.core.manage.crash;
2 |
3 | import android.content.Context;
4 | import android.content.pm.PackageInfo;
5 | import android.content.pm.PackageManager;
6 | import android.os.Build;
7 | import android.os.Environment;
8 |
9 | import com.orhanobut.logger.Logger;
10 |
11 | import java.io.BufferedWriter;
12 | import java.io.File;
13 | import java.io.FileWriter;
14 | import java.io.PrintWriter;
15 |
16 | public class LogWriter {
17 |
18 | private static final boolean DEBUG = true;
19 | public static final String PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + "/androidcrash/log/";
20 | public static final String FILE_NAME = "crash";
21 | public static final String FILE_NAME_SUFFIX = ".txt";
22 | private static File file;
23 |
24 | public static synchronized void writeLog(Context context, Throwable ex, File file, String time, WriteCallback writeCallback) {
25 | if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
26 | if (DEBUG) {
27 | Logger.w("sdcard unmounted,skip dump exception");
28 | return;
29 | }
30 | }
31 |
32 | File dir = new File(PATH);
33 | if (!dir.exists()) {
34 | dir.mkdirs();
35 | }
36 |
37 | try {
38 | PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(file)));
39 | pw.println(time);
40 | writeMobileInfo(context, pw);
41 | pw.println();
42 | ex.printStackTrace(pw);
43 | pw.close();
44 | writeCallback.writeSuccess();
45 | } catch (Exception e) {
46 | Logger.e("write crash exception failed");
47 | }
48 | }
49 |
50 |
51 | private static void writeMobileInfo(Context context, PrintWriter pw) throws PackageManager.NameNotFoundException {
52 |
53 | PackageManager pm = context.getPackageManager();
54 | PackageInfo pi = pm.getPackageInfo(context.getPackageName(), PackageManager.GET_ACTIVITIES);
55 | pw.print("App Version:");
56 | pw.print(pi.versionName);
57 | pw.print("_");
58 | pw.println(pi.versionCode);
59 |
60 | //Android版本
61 | pw.print("OS Version:");
62 | pw.print(Build.VERSION.RELEASE);
63 | pw.print("_");
64 | pw.println(Build.VERSION.SDK_INT);
65 |
66 | //手机制造商
67 | pw.print("Vendor:");
68 | pw.println(Build.MANUFACTURER);
69 |
70 | pw.print("Model:");
71 | pw.println(Build.MODEL);
72 | }
73 |
74 | public interface WriteCallback {
75 | void writeSuccess();
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/core/src/main/java/com/xhb/core/manage/interfacee/HttpReportCallback.java:
--------------------------------------------------------------------------------
1 | package com.xhb.core.manage.interfacee;
2 |
3 | import java.io.File;
4 |
5 | public interface HttpReportCallback {
6 | void uploadException2remote(File file);
7 | }
8 |
--------------------------------------------------------------------------------
/core/src/main/java/com/xhb/core/manage/interfacee/ImageLoadInterface.java:
--------------------------------------------------------------------------------
1 | package com.xhb.core.manage.interfacee;
2 |
3 | import android.widget.ImageView;
4 |
5 | public interface ImageLoadInterface {
6 | void loadNet(ImageView target, String url);
7 |
8 | void loadNet(ImageView target, String url, int animal);
9 |
10 | void loadDrawable(ImageView target, int resId);
11 |
12 | void loadDrawable(ImageView target, int resId, int animal);
13 | }
14 |
--------------------------------------------------------------------------------
/core/src/main/java/com/xhb/core/model/LogicProxy.java:
--------------------------------------------------------------------------------
1 | package com.xhb.core.model;
2 |
3 | import com.xhb.core.base.BaseIPresenter;
4 | import com.xhb.core.base.IBaseView;
5 | import com.xhb.core.model.annotation.Implement;
6 |
7 | import java.lang.annotation.Annotation;
8 | import java.util.HashMap;
9 | import java.util.Map;
10 |
11 | public class LogicProxy {
12 | private static final LogicProxy m_instance = new LogicProxy();
13 |
14 | public static LogicProxy getInstance() {
15 | return m_instance;
16 | }
17 |
18 | private LogicProxy() {
19 | m_objects = new HashMap<>();
20 | }
21 |
22 | private Map m_objects;
23 |
24 | public void init(Class... clss) {
25 | // List list = new LinkedList();
26 | for (Class cls : clss) {
27 | if (cls.isAnnotationPresent(Implement.class)) {
28 | // list.add(cls);
29 | for (Annotation ann : cls.getDeclaredAnnotations()) {
30 | if (ann instanceof Implement) {
31 | try {
32 | m_objects.put(cls, ((Implement) ann).value().newInstance());
33 | } catch (InstantiationException e) {
34 | e.printStackTrace();
35 | } catch (IllegalAccessException e) {
36 | e.printStackTrace();
37 | }
38 | }
39 | }
40 | }
41 | }
42 | }
43 |
44 | // 初始化presenter add map
45 | public T bind(Class clzz, IBaseView var1) {
46 | if (!m_objects.containsKey(clzz)) {
47 | init(clzz);
48 | }
49 | BaseIPresenter presenter = ((BaseIPresenter) m_objects.get(clzz));
50 | if (var1 != presenter.getView()) {
51 | if (presenter.getView() != null) {
52 | presenter.detachView();
53 | }
54 | presenter.attachView(var1);
55 | }
56 | return (T) presenter;
57 | }
58 |
59 | // 解除绑定 移除map
60 | public void unbind(Class clzz, IBaseView var1) {
61 | if (m_objects.containsKey(clzz)) {
62 | BaseIPresenter presenter = ((BaseIPresenter) m_objects.get(clzz));
63 | if (var1 != presenter.getView()) {
64 | if (presenter.getView() != null) {
65 | presenter.detachView();
66 | }
67 | m_objects.remove(clzz);
68 | }
69 |
70 | }
71 | }
72 | }
--------------------------------------------------------------------------------
/core/src/main/java/com/xhb/core/model/annotation/Implement.java:
--------------------------------------------------------------------------------
1 | package com.xhb.core.model.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | @Target(ElementType.TYPE)
9 | @Retention(RetentionPolicy.RUNTIME)
10 | public @interface Implement {
11 | Class value();
12 | }
13 |
--------------------------------------------------------------------------------
/core/src/main/java/com/xhb/core/util/GsonUtil.java:
--------------------------------------------------------------------------------
1 | package com.xhb.core.util;
2 |
3 | import com.google.gson.Gson;
4 | import com.google.gson.GsonBuilder;
5 | import com.google.gson.TypeAdapter;
6 | import com.google.gson.TypeAdapterFactory;
7 | import com.google.gson.reflect.TypeToken;
8 | import com.google.gson.stream.JsonReader;
9 | import com.google.gson.stream.JsonToken;
10 | import com.google.gson.stream.JsonWriter;
11 |
12 | import java.io.IOException;
13 |
14 | /**
15 | * Author:Tiger
16 | *
17 | * CrateTime:2016-12-20 15:49
18 | *
19 | * Description:将null转换为空字符串
20 | */
21 | public class GsonUtil {
22 |
23 | public static Gson newGson() {
24 | return new GsonBuilder().registerTypeAdapterFactory(new NullStringToEmptyAdapterFactory()).create();
25 | }
26 |
27 | /**
28 | * http://www.jianshu.com/p/c6dd9a6b10ee
29 | */
30 | public static class NullStringToEmptyAdapterFactory implements TypeAdapterFactory {
31 | @Override
32 | @SuppressWarnings("unchecked")
33 | public TypeAdapter create(Gson gson, TypeToken type) {
34 | Class rawType = (Class) type.getRawType();
35 | if (rawType != String.class) {
36 | return null;
37 | }
38 | return (TypeAdapter) new StringNullAdapter();
39 | }
40 | }
41 |
42 | /**
43 | * http://www.jianshu.com/p/c6dd9a6b10ee
44 | */
45 | public static class StringNullAdapter extends TypeAdapter {
46 | @Override
47 | public String read(JsonReader reader) throws IOException {
48 | if (reader.peek() == JsonToken.NULL) {
49 | reader.nextNull();
50 | return "";
51 | }
52 | return reader.nextString();
53 | }
54 |
55 | @Override
56 | public void write(JsonWriter writer, String value) throws IOException {
57 | if (value == null) {
58 | writer.nullValue();
59 | return;
60 | }
61 | writer.value(value);
62 | }
63 | }
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/core/src/main/java/com/xhb/core/util/LoggerHelper.java:
--------------------------------------------------------------------------------
1 | package com.xhb.core.util;
2 |
3 | import android.util.Log;
4 |
5 | import com.orhanobut.logger.AndroidLogAdapter;
6 | import com.orhanobut.logger.FormatStrategy;
7 | import com.orhanobut.logger.LogcatLogStrategy;
8 | import com.orhanobut.logger.Logger;
9 | import com.orhanobut.logger.PrettyFormatStrategy;
10 | import com.xhb.core.BuildConfig;
11 |
12 | /**
13 | * @author: xiaohaibin.
14 | * @time: 2018/6/26
15 | * @mail:xhb_199409@163.com
16 | * @github:https://github.com/xiaohaibin
17 | * @describe:
18 | */
19 | public class LoggerHelper {
20 |
21 | private static boolean DEBUG = true;
22 |
23 | public static void initLogger(final boolean isDebug) {
24 | DEBUG=isDebug;
25 | FormatStrategy formatStrategy = PrettyFormatStrategy.newBuilder()
26 | .showThreadInfo(true) // (Optional) Whether to show thread info or not. Default true
27 | .methodCount(0) // (Optional) How many method line to show. Default 2
28 | .methodOffset(7) // (Optional) Hides internal method calls up to offset. Default 5
29 | .logStrategy(new LogcatLogStrategy()) // (Optional) Changes the log strategy to print out. Default LogCat
30 | .tag("Enjoy") // (Optional) Global tag for every log. Default PRETTY_LOGGER
31 | .build();
32 | Logger.addLogAdapter(new AndroidLogAdapter(formatStrategy) {
33 | @Override
34 | public boolean isLoggable(int priority, String tag) {
35 | return DEBUG;
36 | }
37 | });
38 | }
39 |
40 |
41 | public static void d(String tag,String message,Object... args) {
42 | if (DEBUG) {
43 | Logger.t(tag).d(message,args);
44 | }
45 | }
46 |
47 | public static void d(String message, Object... args) {
48 | if (DEBUG) {
49 | Logger.d(message, args);
50 | }
51 | }
52 |
53 | public static void d(String tag,Object object) {
54 | if (DEBUG) {
55 | Logger.t(tag).d(object);
56 | }
57 | }
58 |
59 | public static void d(Object object) {
60 | if (DEBUG) {
61 | Logger.d(object);
62 | }
63 | }
64 |
65 | public static void e(String tag,String message, Object... args) {
66 | if (DEBUG) {
67 | Logger.t(tag).e(message,args);
68 | }
69 | }
70 |
71 | public static void e(String message, Object... args) {
72 | if (DEBUG) {
73 | Logger.e(null, message, args);
74 | }
75 | }
76 |
77 |
78 | public static void e(String tag,Throwable throwable, String message, Object... args) {
79 | if (DEBUG) {
80 | Logger.t(tag).e(throwable,message,args);
81 | }
82 | }
83 |
84 | public static void e(Throwable throwable, String message, Object... args) {
85 | if (DEBUG) {
86 | Logger.e(throwable, message, args);
87 | }
88 | }
89 |
90 | public static void i(String tag,String message, Object... args) {
91 | if (DEBUG) {
92 | Logger.t(tag).i(message,args);
93 | }
94 | }
95 |
96 | public static void i(String message, Object... args) {
97 | if (DEBUG) {
98 | Logger.i(message, args);
99 | }
100 | }
101 |
102 | public static void v(String tag,String message, Object... args) {
103 | if (DEBUG) {
104 | Logger.t(tag).v(message,args);
105 | }
106 | }
107 |
108 |
109 | public static void v(String message, Object... args) {
110 | if (DEBUG) {
111 | Logger.v(message, args);
112 | }
113 | }
114 |
115 | public static void w(String tag,String message, Object... args) {
116 | if (DEBUG) {
117 | Logger.t(tag).w(message,args);
118 | }
119 | }
120 |
121 | public static void w(String message, Object... args) {
122 | if (DEBUG) {
123 | Logger.w(message, args);
124 | }
125 | }
126 |
127 |
128 | public static void json(String json) {
129 | if (DEBUG) {
130 | Logger.json(json);
131 | }
132 | }
133 |
134 | public static void json(String tag,String json) {
135 | if (DEBUG) {
136 | Logger.t(tag).json(json);
137 | }
138 | }
139 |
140 | }
141 |
--------------------------------------------------------------------------------
/core/src/main/java/com/xhb/core/util/NetworkUtil.java:
--------------------------------------------------------------------------------
1 | package com.xhb.core.util;
2 |
3 | import android.content.Context;
4 | import android.net.ConnectivityManager;
5 | import android.net.NetworkInfo;
6 |
7 | public class NetworkUtil {
8 |
9 | //监测网络是否连接
10 | public static boolean isInternetConnection(Context context) {
11 | ConnectivityManager connectivityManager =
12 | (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
13 | NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
14 | boolean isConnected = (networkInfo != null && networkInfo.isConnectedOrConnecting());
15 | return isConnected;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/core/src/main/java/com/xhb/core/util/ScreenUtil.java:
--------------------------------------------------------------------------------
1 | package com.xhb.core.util;
2 |
3 | import android.content.Context;
4 | import android.content.res.TypedArray;
5 | import android.util.DisplayMetrics;
6 | import android.view.Display;
7 | import android.view.WindowManager;
8 |
9 | import com.xhb.core.R;
10 |
11 | public class ScreenUtil {
12 |
13 | private static final int[] APPCOMPAT_CHECK_ATTRS = {R.attr.colorPrimary};
14 |
15 | public static void checkAppCompatTheme(Context context) {
16 | TypedArray a = context.obtainStyledAttributes(APPCOMPAT_CHECK_ATTRS);
17 | final boolean failed = !a.hasValue(0);
18 | if (a != null) {
19 | a.recycle();
20 | }
21 | if (failed) {
22 | throw new IllegalArgumentException("You need to use a Theme.AppCompat theme "
23 | + "(or descendant) with the design library.");
24 | }
25 | }
26 |
27 | public static int px2sp(Context context, float pxValue) {
28 | final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
29 | return (int) (pxValue / fontScale + 0.5f);
30 | }
31 |
32 | public static int dp2px(Context context, int dp) {
33 | DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
34 | return (int) ((dp * displayMetrics.density) + 0.5);
35 | }
36 |
37 | public static int dp2px(Context context, double dp) {
38 | DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
39 | return (int) ((dp * displayMetrics.density) + 0.5);
40 | }
41 |
42 | public static int getScreenWidth(Context context) {
43 | DisplayMetrics dm = new DisplayMetrics();
44 | //((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(dm);
45 |
46 | WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
47 | Display display = wm.getDefaultDisplay();
48 | display.getMetrics(dm);
49 |
50 | return dm.widthPixels;
51 | }
52 |
53 | /**
54 | * 获取屏幕的高
55 | */
56 | public static int getScreenHeight(Context context) {
57 | return context.getResources().getDisplayMetrics().heightPixels;
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/core/src/main/res/drawable-xhdpi/abc_icon_down_arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/core/src/main/res/drawable-xhdpi/abc_icon_down_arrow.png
--------------------------------------------------------------------------------
/core/src/main/res/drawable/abc_oval_white.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/core/src/main/res/layout/abc_navi_tab_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
22 |
23 |
--------------------------------------------------------------------------------
/core/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/core/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #7f000000
4 | #212121
5 | #ffffff
6 | #2196F3
7 | #f2f2f2
8 | #00ffffff
9 | #03a9f4
10 |
11 |
--------------------------------------------------------------------------------
/core/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | core
3 |
4 |
--------------------------------------------------------------------------------
/core/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
13 |
14 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jul 06 14:53:15 CST 2018
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/screenshot/apk_code.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/screenshot/apk_code.png
--------------------------------------------------------------------------------
/screenshot/device-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/screenshot/device-1.png
--------------------------------------------------------------------------------
/screenshot/device-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/screenshot/device-2.png
--------------------------------------------------------------------------------
/screenshot/device-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/screenshot/device-3.png
--------------------------------------------------------------------------------
/screenshot/device-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/screenshot/device-4.png
--------------------------------------------------------------------------------
/screenshot/device-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/screenshot/device-5.png
--------------------------------------------------------------------------------
/screenshot/device-6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaohaibin/EnjoyLife/2fc9bee947fc81c6eb4187d8f8b44c8276dcad76/screenshot/device-6.png
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':core'
2 |
--------------------------------------------------------------------------------