├── .gitignore ├── .idea ├── codeStyles │ └── Project.xml ├── gradle.xml ├── inspectionProfiles │ └── Project_Default.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── assets │ └── fonts │ │ ├── FZLanTingHeiS-DB1-GB-Regular.TTF │ │ ├── FZLanTingHeiS-L-GB-Regular.TTF │ │ └── Lobster-1.4.otf │ ├── java │ └── com │ │ └── stx │ │ └── xhb │ │ └── enjoylife │ │ ├── MyApplication.java │ │ ├── config │ │ ├── Config.java │ │ ├── Constants.java │ │ └── MyAppGlideModule.java │ │ ├── listener │ │ ├── OnTransitionListener.java │ │ └── SampleVideoPlayListener.java │ │ ├── model │ │ ├── entity │ │ │ ├── TuChongWallPaperResponse.java │ │ │ ├── TuchongImagResponse.java │ │ │ ├── VideoResponse.java │ │ │ ├── ZhiHuNewsContentResponse.java │ │ │ └── ZhiHuNewsResponse.java │ │ └── http │ │ │ └── ApiManager.java │ │ ├── presenter │ │ ├── tuchong │ │ │ ├── getFeedAppContact.java │ │ │ ├── getFeedAppIPresenterImpl.java │ │ │ ├── getWallPaperContract.java │ │ │ └── getWallPaperIPresenterImpl.java │ │ ├── video │ │ │ ├── getVideoContract.java │ │ │ └── getVideoIPresenterImpl.java │ │ └── zhihu │ │ │ ├── getNewsContentContract.java │ │ │ ├── getNewsContentIPresenterImpl.java │ │ │ ├── getZhiHuNewsContract.java │ │ │ └── getZhiHuNewsIPresenterImpl.java │ │ ├── ui │ │ ├── activity │ │ │ ├── AboutActivity.java │ │ │ ├── MainActivity.java │ │ │ ├── NewsDetailsActivity.java │ │ │ ├── PhotoViewActivity.java │ │ │ ├── SetttingActivity.java │ │ │ ├── SplashActivity.java │ │ │ ├── VideoDetailActivity.java │ │ │ └── VideoPlayActivity.java │ │ ├── adapter │ │ │ ├── NewsAdapter.java │ │ │ ├── PhotoViewPagerAdapter.java │ │ │ ├── TuChongListAdapter.java │ │ │ ├── TuChongWallPaperAdapter.java │ │ │ ├── VideoRecyclerAdapter.java │ │ │ └── provider │ │ │ │ ├── BannerItemProvider.java │ │ │ │ ├── TextItemProvider.java │ │ │ │ └── VideoItemProvider.java │ │ ├── fragment │ │ │ ├── TuChongFeedFragment.java │ │ │ ├── TuChongWallPaperFragment.java │ │ │ ├── VideoFragment.java │ │ │ └── ZhihuFragment.java │ │ ├── video │ │ │ └── CustomVideoView.java │ │ └── widget │ │ │ ├── CustomTextView.java │ │ │ ├── RatioImageView.java │ │ │ ├── RecyclerViewNoBugLinearLayoutManager.java │ │ │ └── RecyclerViewNoBugStaggeredGridLayoutManger.java │ │ └── utils │ │ ├── LogUtil.java │ │ ├── NetConnectedUtils.java │ │ ├── SPUtils.java │ │ ├── ShareUtils.java │ │ ├── SnackbarUtil.java │ │ ├── ToastUtil.java │ │ └── WebHtmlUtil.java │ └── res │ ├── anim │ ├── splash_fade_in.xml │ └── splash_fade_out.xml │ ├── drawable-hdpi │ ├── ic_logo.png │ └── iconfont_downgrey.png │ ├── drawable-xhdpi-v4 │ ├── action_pause.png │ ├── action_reload.png │ ├── ic_action_play.png │ ├── ic_player_close_white.png │ ├── ic_player_next.png │ ├── ic_player_pause.png │ ├── ic_player_play.png │ ├── ic_player_progress_handle.png │ ├── ic_player_reload.png │ ├── ic_player_volume_down.png │ ├── ic_player_volume_up.png │ ├── landing_background.jpg │ ├── landing_countdown_background.png │ ├── video_player_bg_color.png │ └── videobg.9.png │ ├── drawable-xhdpi │ ├── bg.png │ └── shape_rec_90000000_corner_4dp.xml │ ├── drawable-xxhdpi-v4 │ ├── light_100.png │ ├── light_20.png │ ├── light_30.png │ ├── light_40.png │ ├── light_50.png │ ├── light_60.png │ ├── light_70.png │ ├── light_80.png │ ├── light_90.png │ ├── video_volumn_bg.png │ ├── volmn_100.png │ ├── volmn_30.png │ ├── volmn_60.png │ └── volmn_no.png │ ├── drawable-xxhdpi │ ├── ic_card_overflow.png │ ├── splash_bg.jpg │ └── web_progress_bg.xml │ ├── drawable │ ├── bg_card.9.png │ ├── bg_card_nopic.xml │ ├── boman_selector.xml │ ├── gradient.xml │ ├── ic_arrow_upward_white_24px.xml │ ├── ic_more_vert_black_24px.xml │ ├── ic_photo_black_24dp.xml │ ├── ic_settings_black_24px.xml │ ├── ic_share_white_24px.xml │ ├── ic_sort_black_24px.xml │ ├── ic_video_black_24px.xml │ ├── icon_picture_black_24px.xml │ ├── icon_tv_black_24px.xml │ ├── icon_zhihu_black_24px.xml │ ├── paly_selector.xml │ ├── selector_select_on_sale_time_text_color.xml │ ├── selector_trade_white_orange_btn_10dp.xml │ ├── shape_rec_blue_corner_pressed_10dp.xml │ ├── shape_rec_gray_corner_disable_10dp.xml │ ├── shape_rec_white_corner_normal_10dp.xml │ ├── video_new_progress.xml │ ├── video_new_seekbar_progress.xml │ ├── video_new_seekbar_thumb.xml │ ├── video_new_volume_progress_bg.xml │ ├── video_seek_new_thumb_normal.xml │ └── video_seek_new_thumb_press.xml │ ├── layout │ ├── activity_about.xml │ ├── activity_main.xml │ ├── activity_photo_view.xml │ ├── activity_play.xml │ ├── activity_settting.xml │ ├── activity_splash.xml │ ├── activity_video_detail.xml │ ├── activity_web_details.xml │ ├── app_bar_main.xml │ ├── content_main.xml │ ├── custom_video.xml │ ├── custom_video_normal.xml │ ├── customle_video_land.xml │ ├── fragment_common.xml │ ├── include_layout_line_panding.xml │ ├── item_photoview.xml │ ├── list_home_item_banner.xml │ ├── list_home_text_item.xml │ ├── list_home_video_item.xml │ ├── list_item_news.xml │ ├── list_item_selet_tv_primary.xml │ ├── list_item_selet_tv_sub.xml │ ├── list_item_tuchong.xml │ ├── list_item_wall_paper.xml │ ├── nav_header_main.xml │ ├── toolbar_layout.xml │ └── view_toast.xml │ ├── menu │ ├── activity_main_drawer.xml │ ├── menu_about.xml │ └── menu_more.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ ├── enjoylife.png │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ └── values │ ├── android_material_design_colours.xml │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── core ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── xhb │ │ └── core │ │ ├── BaseApplication.java │ │ ├── adapter │ │ ├── RecyclerAdapter.java │ │ └── RecyclerViewHolder.java │ │ ├── api │ │ ├── HttpCacheInterceptor.java │ │ └── RestApi.java │ │ ├── base │ │ ├── BaseActivity.java │ │ ├── BaseFragment.java │ │ ├── BaseIPresenter.java │ │ ├── BaseSwipeBackActivity.java │ │ ├── IBaseView.java │ │ ├── IModel.java │ │ └── IPresenter.java │ │ ├── manage │ │ ├── crash │ │ │ ├── AndroidCrash.java │ │ │ └── LogWriter.java │ │ └── interfacee │ │ │ ├── HttpReportCallback.java │ │ │ └── ImageLoadInterface.java │ │ ├── model │ │ ├── LogicProxy.java │ │ └── annotation │ │ │ └── Implement.java │ │ ├── ui │ │ ├── DividerDecoration.java │ │ ├── SwipeBackLayout.java │ │ └── TabStripView.java │ │ └── util │ │ ├── GsonUtil.java │ │ ├── LoggerHelper.java │ │ ├── NetworkUtil.java │ │ ├── RxImage.java │ │ └── ScreenUtil.java │ └── res │ ├── drawable-xhdpi │ └── abc_icon_down_arrow.png │ ├── drawable │ └── abc_oval_white.xml │ ├── layout │ └── abc_navi_tab_view.xml │ └── values │ ├── attrs.xml │ ├── colors.xml │ ├── strings.xml │ └── styles.xml ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── screenshot ├── apk_code.png ├── device-1.png ├── device-2.png ├── device-3.png ├── device-4.png ├── device-5.png └── device-6.png └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15 | 16 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 36 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EnjoyLife 2 | :wink:【乐享】每天一张精选妹纸图、一个精选短视频,知乎美文的精美应用 3 | 4 | **【Kotlin版本】**: 5 | 6 | ### 效果图 7 | 8 | ![](https://github.com/xiaohaibin/EnjoyLife/blob/master/screenshot/device-1.png) 9 | ![](https://github.com/xiaohaibin/EnjoyLife/blob/master/screenshot/device-2.png) 10 | ![](https://github.com/xiaohaibin/EnjoyLife/blob/master/screenshot/device-3.png) 11 | ![](https://github.com/xiaohaibin/EnjoyLife/blob/master/screenshot/device-4.png) 12 | 13 | ### Apk下载 14 | 15 | ![](https://github.com/xiaohaibin/EnjoyLife/blob/master/screenshot/apk_code.png) 16 | 17 | ### 关于我 18 | 19 | * **Email**: 20 | * **Home**: 21 | * **掘金**: 22 | * **简书**: 23 | 24 | ### Thanks 25 | 26 | * **Meizhi**: 27 | * **-Api**: 28 | 29 | ### 欢迎关注个人微信公众号,将会定期推送优质技术文章,求关注 30 | 31 | ![欢迎关注“大话微信”公众号](http://upload-images.jianshu.io/upload_images/1956769-2f49dcb0dc5195b6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 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 |

3 | 6 | 7 | 8 | 9 | 10 | 11 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_about.xml: -------------------------------------------------------------------------------- 1 | 5 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_more.xml: -------------------------------------------------------------------------------- 1 | 5 | 10 | 15 | 20 | 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 | 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 | --------------------------------------------------------------------------------