├── app ├── .gitignore ├── src │ └── main │ │ ├── ic_launcher-web.png │ │ ├── res │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_round.png │ │ │ └── ic_launcher_foreground.png │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_round.png │ │ │ └── ic_launcher_foreground.png │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_round.png │ │ │ └── ic_launcher_foreground.png │ │ ├── mipmap-xxhdpi │ │ │ ├── btn_zhi_on.png │ │ │ ├── img_icon.png │ │ │ ├── img_info.png │ │ │ ├── img_play.png │ │ │ ├── img_share.png │ │ │ ├── btn_video_on.png │ │ │ ├── ic_launcher.png │ │ │ ├── img_photo_on.png │ │ │ ├── img_back_blue.png │ │ │ ├── img_back_white.png │ │ │ ├── ic_launcher_round.png │ │ │ └── ic_launcher_foreground.png │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_round.png │ │ │ └── ic_launcher_foreground.png │ │ ├── drawable-xxhdpi │ │ │ ├── img_loading.png │ │ │ ├── video_player_bg_color.png │ │ │ ├── video_seek_new_thumb_normal.xml │ │ │ ├── video_seek_new_thumb_press.xml │ │ │ ├── video_new_seekbar_thumb.xml │ │ │ ├── video_new_volume_progress_bg.xml │ │ │ ├── video_new_seekbar_progress.xml │ │ │ └── video_new_progress.xml │ │ ├── xml │ │ │ └── file_paths.xml │ │ ├── values │ │ │ ├── ic_launcher_background.xml │ │ │ ├── colors.xml │ │ │ ├── styles.xml │ │ │ └── strings.xml │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ ├── layout │ │ │ ├── item_photo.xml │ │ │ ├── activity_video_player.xml │ │ │ ├── activity_splash.xml │ │ │ ├── item_zhihu.xml │ │ │ ├── fragment_photo.xml │ │ │ ├── fragment_video.xml │ │ │ ├── fragment_zhihu.xml │ │ │ ├── item_video.xml │ │ │ ├── activity_main.xml │ │ │ ├── activity_zhihu_details.xml │ │ │ ├── activity_gallery.xml │ │ │ ├── activity_video_details.xml │ │ │ ├── custom_video.xml │ │ │ └── activity_about.xml │ │ ├── drawable-v24 │ │ │ └── ic_launcher_foreground.xml │ │ └── drawable │ │ │ └── ic_launcher_background.xml │ │ ├── java │ │ └── com │ │ │ └── kongzue │ │ │ └── enjoylife │ │ │ ├── listener │ │ │ └── ResponseListener.java │ │ │ ├── EnjoyLifeApp.java │ │ │ ├── util │ │ │ ├── Parameter.java │ │ │ ├── SwipBackActivity.java │ │ │ └── SwipeBackHelper.java │ │ │ ├── activity │ │ │ ├── SplashActivity.java │ │ │ ├── VideoDetailsActivity.java │ │ │ ├── VideoPlayerActivity.java │ │ │ ├── AboutActivity.java │ │ │ ├── MainActivity.java │ │ │ ├── ZhihuDetailsActivity.java │ │ │ └── GalleryActivity.java │ │ │ ├── adapter │ │ │ ├── PhotoViewPagerAdapter.java │ │ │ ├── ZhihuListAdapter.java │ │ │ ├── VideoListAdapter.java │ │ │ └── PhotoListAdapter.java │ │ │ ├── view │ │ │ └── CustomVideoView.java │ │ │ ├── fragment │ │ │ ├── ZhihuFragment.java │ │ │ ├── PhotoFragment.java │ │ │ └── VideoFragment.java │ │ │ └── request │ │ │ └── HttpRequest.java │ │ └── AndroidManifest.xml ├── libs │ └── tbs_sdk_thirdapp_v3.2.0.1104_43200_sharewithdownload_withfilereader_withoutGame_obfs_20170609_115346.jar ├── proguard-rules.pro └── build.gradle ├── settings.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .idea ├── caches │ └── build_file_checksums.ser ├── markdown-navigator │ └── profiles_settings.xml ├── encodings.xml ├── runConfigurations.xml ├── gradle.xml ├── codeStyles │ └── Project.xml ├── misc.xml └── markdown-navigator.xml ├── .gitignore ├── gradle.properties ├── README.md ├── gradlew.bat └── gradlew /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | -------------------------------------------------------------------------------- /app/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kongzue/EnjoyLife/HEAD/app/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kongzue/EnjoyLife/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /.idea/caches/build_file_checksums.ser: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kongzue/EnjoyLife/HEAD/.idea/caches/build_file_checksums.ser -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kongzue/EnjoyLife/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kongzue/EnjoyLife/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kongzue/EnjoyLife/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/btn_zhi_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kongzue/EnjoyLife/HEAD/app/src/main/res/mipmap-xxhdpi/btn_zhi_on.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/img_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kongzue/EnjoyLife/HEAD/app/src/main/res/mipmap-xxhdpi/img_icon.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/img_info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kongzue/EnjoyLife/HEAD/app/src/main/res/mipmap-xxhdpi/img_info.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/img_play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kongzue/EnjoyLife/HEAD/app/src/main/res/mipmap-xxhdpi/img_play.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/img_share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kongzue/EnjoyLife/HEAD/app/src/main/res/mipmap-xxhdpi/img_share.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/btn_video_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kongzue/EnjoyLife/HEAD/app/src/main/res/mipmap-xxhdpi/btn_video_on.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kongzue/EnjoyLife/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/img_photo_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kongzue/EnjoyLife/HEAD/app/src/main/res/mipmap-xxhdpi/img_photo_on.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kongzue/EnjoyLife/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/img_loading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kongzue/EnjoyLife/HEAD/app/src/main/res/drawable-xxhdpi/img_loading.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kongzue/EnjoyLife/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kongzue/EnjoyLife/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/img_back_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kongzue/EnjoyLife/HEAD/app/src/main/res/mipmap-xxhdpi/img_back_blue.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/img_back_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kongzue/EnjoyLife/HEAD/app/src/main/res/mipmap-xxhdpi/img_back_white.png -------------------------------------------------------------------------------- /.idea/markdown-navigator/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kongzue/EnjoyLife/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kongzue/EnjoyLife/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kongzue/EnjoyLife/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kongzue/EnjoyLife/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kongzue/EnjoyLife/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/xml/file_paths.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kongzue/EnjoyLife/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kongzue/EnjoyLife/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/video_player_bg_color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kongzue/EnjoyLife/HEAD/app/src/main/res/drawable-xxhdpi/video_player_bg_color.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kongzue/EnjoyLife/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFFFFF 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/libraries 5 | /.idea/modules.xml 6 | /.idea/workspace.xml 7 | .DS_Store 8 | /build 9 | /captures 10 | .externalNativeBuild 11 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/libs/tbs_sdk_thirdapp_v3.2.0.1104_43200_sharewithdownload_withfilereader_withoutGame_obfs_20170609_115346.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kongzue/EnjoyLife/HEAD/app/libs/tbs_sdk_thirdapp_v3.2.0.1104_43200_sharewithdownload_withfilereader_withoutGame_obfs_20170609_115346.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri May 11 15:06:24 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 | -------------------------------------------------------------------------------- /app/src/main/java/com/kongzue/enjoylife/listener/ResponseListener.java: -------------------------------------------------------------------------------- 1 | package com.kongzue.enjoylife.listener; 2 | 3 | import org.json.JSONObject; 4 | 5 | /** 6 | * Created by myzcx on 2017/12/27. 7 | */ 8 | 9 | public interface ResponseListener { 10 | void onResponse(JSONObject main, Exception error); 11 | } -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/video_seek_new_thumb_normal.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/video_seek_new_thumb_press.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/video_new_seekbar_thumb.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #000000 6 | #fff 7 | #cdcdd1 8 | #313131 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/kongzue/enjoylife/EnjoyLifeApp.java: -------------------------------------------------------------------------------- 1 | package com.kongzue.enjoylife; 2 | 3 | import android.app.Application; 4 | 5 | import com.facebook.drawee.backends.pipeline.Fresco; 6 | import com.kongzue.dialog.v2.DialogSettings; 7 | 8 | import static com.kongzue.dialog.v2.DialogSettings.TYPE_IOS; 9 | 10 | public class EnjoyLifeApp extends Application { 11 | 12 | @Override 13 | public void onCreate() { 14 | super.onCreate(); 15 | DialogSettings.type = TYPE_IOS; 16 | Fresco.initialize(this); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_photo.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/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/layout/activity_video_player.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 16 | 17 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx1536m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 一日读 3 | 每天一张精选妹纸图、一个精选小视频,一篇知乎美文。\n\n图片数据内容来源于图虫摄影网 \n\n视频数据来源于开眼视频 \n\n 4 | 关于作者 5 | \@Kongzue\n软件攻城狮,UI设计狮,宅一只,没钱没车没老婆,倒有梦想一堆,在思想的碰撞中永生,于绝妙创意中不朽。我,一个粉刷着理想墙的工匠\n\n\@Xiaohaibin\n用汗水灌溉梦想,用梦想创造奇迹。\n\n本项目Github地址: 6 | 本项目由\@Kongzue完成开发,灵感来源于\@Xiaohaibin的原作开源项目“乐享”: 7 | 本项目完全开源,如果你觉得不错,可以帮忙分享给你更多的朋友,这是我最大的动力和支持,非常感谢!\n\n 8 | https://github.com/kongzue/EnjoyLife 9 | https://github.com/xiaohaibin/EnjoyLife 10 | 开源框架 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/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-xxhdpi/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/layout/activity_splash.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/java/com/kongzue/enjoylife/util/Parameter.java: -------------------------------------------------------------------------------- 1 | package com.kongzue.enjoylife.util; 2 | 3 | import java.util.TreeMap; 4 | 5 | import okhttp3.FormBody; 6 | import okhttp3.RequestBody; 7 | 8 | public class Parameter extends TreeMap { 9 | 10 | public Parameter add(String key, String value){ 11 | put(key,value); 12 | return this; 13 | } 14 | 15 | public String toParameterString(){ 16 | String result=""; 17 | if (!entrySet().isEmpty()) { 18 | for (Entry entry : entrySet()) { 19 | result = result + entry.getKey() + "=" + entry.getValue() + "&"; 20 | } 21 | if (result.endsWith("&")) { 22 | result = result.substring(0, result.length() - 1); 23 | } 24 | } 25 | return result; 26 | } 27 | 28 | public RequestBody toOkHttpParameter(){ 29 | RequestBody requestBody; 30 | 31 | FormBody.Builder builder = new FormBody.Builder(); 32 | for (Entry entry : entrySet()) { 33 | builder.add(entry.getKey()+"",entry.getValue()+""); 34 | } 35 | 36 | requestBody = builder.build(); 37 | return requestBody; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/com/kongzue/enjoylife/util/SwipBackActivity.java: -------------------------------------------------------------------------------- 1 | package com.kongzue.enjoylife.util; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | 6 | import com.kongzue.baseframework.BaseActivity; 7 | 8 | import me.majiajie.swipeback.SwipeBackLayout; 9 | 10 | public abstract class SwipBackActivity extends BaseActivity { 11 | 12 | private SwipeBackHelper mSwipeBackHelper; 13 | 14 | @Override 15 | protected void onCreate(Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | 18 | mSwipeBackHelper = new SwipeBackHelper(this); 19 | mSwipeBackHelper.onCreate(); 20 | } 21 | 22 | //侧滑返回 23 | @Override 24 | protected void onPostCreate(@Nullable Bundle savedInstanceState) { 25 | super.onPostCreate(savedInstanceState); 26 | mSwipeBackHelper.onPostCreate(); 27 | } 28 | 29 | public SwipeBackLayout getSwipeBackLayout() { 30 | return mSwipeBackHelper.getSwipeBackLayout(); 31 | } 32 | 33 | /** 34 | * 设置是否可以边缘滑动返回 35 | * 36 | * @param enable true可以边缘滑动返回 37 | */ 38 | public void setSwipeBackEnable(boolean enable) { 39 | getSwipeBackLayout().setSwipeBackEnable(enable); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/com/kongzue/enjoylife/util/SwipeBackHelper.java: -------------------------------------------------------------------------------- 1 | package com.kongzue.enjoylife.util; 2 | 3 | import android.app.Activity; 4 | import android.graphics.Color; 5 | import android.graphics.drawable.ColorDrawable; 6 | import android.view.View; 7 | 8 | import me.majiajie.swipeback.SwipeBackLayout; 9 | 10 | public class SwipeBackHelper { 11 | 12 | private Activity mActivity; 13 | 14 | private SwipeBackLayout mSwipeBackLayout; 15 | 16 | public SwipeBackHelper(Activity activity) 17 | { 18 | mActivity = activity; 19 | } 20 | 21 | public void onCreate() 22 | { 23 | mActivity.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); 24 | mActivity.getWindow().getDecorView().setBackgroundColor(Color.TRANSPARENT); 25 | mSwipeBackLayout = new SwipeBackLayout(mActivity); 26 | } 27 | 28 | public void onPostCreate() 29 | { 30 | mSwipeBackLayout.attachToActivity(mActivity); 31 | } 32 | 33 | public View findViewById(int id) 34 | { 35 | if (mSwipeBackLayout != null) 36 | { 37 | return mSwipeBackLayout.findViewById(id); 38 | } 39 | return null; 40 | } 41 | 42 | protected SwipeBackLayout getSwipeBackLayout() 43 | { 44 | return mSwipeBackLayout; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_zhihu.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 12 | 18 | 19 | 24 | 25 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 27 5 | defaultConfig { 6 | applicationId "com.kongzue.enjoylife" 7 | minSdkVersion 16 8 | targetSdkVersion 27 9 | versionCode 2 10 | versionName "1.1" 11 | renderscriptTargetApi 19 12 | renderscriptSupportModeEnabled true 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | implementation fileTree(include: ['*.jar'], dir: 'libs') 24 | implementation 'com.kongzue.dialog:dialog:2.2.4' 25 | implementation 'com.kongzue.baseframework:baseframework:6.4.8' 26 | implementation 'com.kongzue.kongzueupdatesdk:kongzueupdatesdk:1.4.0' 27 | implementation 'com.squareup.okhttp3:okhttp:3.3.1' 28 | implementation 'com.facebook.fresco:fresco:0.12.0' 29 | implementation 'com.qbw.customview:refreshloadmorelayout:2.3.0-beta2' 30 | implementation 'com.github.chrisbanes:PhotoView:2.1.3' 31 | implementation 'com.github.bumptech.glide:glide:3.7.0' 32 | implementation 'com.shuyu:GSYVideoPlayer:4.1.2' 33 | implementation 'me.majiajie:swipe-back:1.0.0-alpha2' 34 | implementation files('libs/tbs_sdk_thirdapp_v3.2.0.1104_43200_sharewithdownload_withfilereader_withoutGame_obfs_20170609_115346.jar') 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/kongzue/enjoylife/activity/SplashActivity.java: -------------------------------------------------------------------------------- 1 | package com.kongzue.enjoylife.activity; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.os.Handler; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.os.Bundle; 7 | import android.view.WindowManager; 8 | 9 | import com.facebook.drawee.view.SimpleDraweeView; 10 | import com.kongzue.baseframework.BaseActivity; 11 | import com.kongzue.baseframework.interfaces.Layout; 12 | import com.kongzue.enjoylife.R; 13 | import com.tencent.smtt.sdk.QbSdk; 14 | 15 | @Layout(R.layout.activity_splash) 16 | public class SplashActivity extends BaseActivity { 17 | 18 | private SimpleDraweeView imgSplash; 19 | 20 | @Override 21 | public void initViews() { 22 | imgSplash = findViewById(R.id.img_splash); 23 | } 24 | 25 | @Override 26 | public void initDatas() { 27 | getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 28 | imgSplash.setImageURI("https://pic1.zhimg.com/v2-9639852750175df1b80ed995729e64e8.jpg"); 29 | } 30 | 31 | @Override 32 | public void setEvents() { 33 | new Handler().postDelayed(new Runnable() { 34 | @Override 35 | public void run() { 36 | jump(MainActivity.class); 37 | finish(); 38 | } 39 | }, 1000); 40 | } 41 | 42 | @Override 43 | protected void onResume() { 44 | super.onResume(); 45 | new Handler().postDelayed(new Runnable() { 46 | @Override 47 | public void run() { 48 | QbSdk.initX5Environment(me,null); 49 | } 50 | },100); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_photo.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 26 | 27 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_video.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 26 | 27 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_zhihu.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 26 | 27 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15 | 16 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 一日读 2 | 每天一张精选倩图、一个精选小视频,一篇知乎美文。图片数据内容来源于图虫摄影网,视频数据来源于开眼视频 3 | 4 | 5 | EnjoyLife 6 | 7 | 8 | EnjoyLife 9 | 10 | 11 | Maven 12 | 13 | 14 | Maven 15 | 16 | 17 | Kongzue's Dialog、BaseFramework、BaseOkHttp框架的最佳实践Demo 18 | 19 | ![EnjoyLife](https://github.com/kongzue/Res/raw/master/app/src/main/res/mipmap-xxxhdpi/img_photo_onedayread_s.png) 20 | 21 | ### 体验版下载 22 | 试用版可以前往 http://kongzue.com/open_source/EnjoyLife.apk 下载 23 | 24 | ![Download](https://github.com/kongzue/Res/raw/master/app/src/main/res/mipmap-xxxhdpi/qrcode_download_enjoylife.png) 25 | 26 | ### 声明 27 | 「一日读」仅作学习交流之用,数据来源于图虫摄影、开眼视频以及知乎日报,数据接口均属于非正常渠道获取,请勿用于商业用途,原作公司拥有所有权利,如若涉及侵权,请联系删除。 28 | 29 | 本项目由 @Kongzue 完成开发,灵感来源于 @Xiaohaibin 的原作开源项目“乐享”:https://github.com/xiaohaibin/EnjoyLife 30 | 31 | ### 开源协议 32 | ``` 33 | Copyright (C) 2016 Kongzue.EnjoyLife 34 | 35 | Licensed under the Apache License, Version 2.0 (the "License"); 36 | you may not use this file except in compliance with the License. 37 | You may obtain a copy of the License at 38 | 39 | http://www.apache.org/licenses/LICENSE-2.0 40 | 41 | Unless required by applicable law or agreed to in writing, software 42 | distributed under the License is distributed on an "AS IS" BASIS, 43 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 44 | See the License for the specific language governing permissions and 45 | limitations under the License. 46 | ``` 47 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_video.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 16 | 17 | 23 | 24 | 33 | 34 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 31 | 32 | 33 | 34 | 35 | 36 | 38 | -------------------------------------------------------------------------------- /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 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 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 Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 20 | 23 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 35 | 36 | 41 | 44 | 45 | 46 | 49 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /app/src/main/java/com/kongzue/enjoylife/activity/VideoDetailsActivity.java: -------------------------------------------------------------------------------- 1 | package com.kongzue.enjoylife.activity; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.net.Uri; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.os.Bundle; 7 | import android.view.View; 8 | import android.widget.LinearLayout; 9 | import android.widget.RelativeLayout; 10 | import android.widget.TextView; 11 | 12 | import com.facebook.drawee.view.SimpleDraweeView; 13 | import com.kongzue.baseframework.BaseActivity; 14 | import com.kongzue.baseframework.interfaces.Layout; 15 | import com.kongzue.baseframework.util.Parameter; 16 | import com.kongzue.enjoylife.R; 17 | import com.kongzue.enjoylife.adapter.VideoListAdapter; 18 | import com.kongzue.enjoylife.util.SwipBackActivity; 19 | 20 | @Layout(R.layout.activity_video_details) 21 | public class VideoDetailsActivity extends SwipBackActivity { 22 | 23 | private SimpleDraweeView image; 24 | private RelativeLayout boxPlay; 25 | private LinearLayout btnBack; 26 | private TextView txtTitle; 27 | private TextView txtTip; 28 | private TextView txtDescription; 29 | 30 | @Override 31 | public void initViews() { 32 | image = findViewById(R.id.image); 33 | boxPlay = findViewById(R.id.box_play); 34 | btnBack = findViewById(R.id.btn_back); 35 | txtTitle = findViewById(R.id.txt_title); 36 | txtTip = findViewById(R.id.txt_tip); 37 | txtDescription = findViewById(R.id.txt_description); 38 | } 39 | 40 | private VideoListAdapter.VideoBean videoBean; 41 | 42 | @Override 43 | public void initDatas() { 44 | if (getParameter()!=null)videoBean = (VideoListAdapter.VideoBean) getParameter().get("videoBean"); 45 | if (videoBean == null) { 46 | finish(); 47 | return; 48 | } 49 | btnBack.setY(getStatusBarHeight()); 50 | boxPlay.setY(getStatusBarHeight()); 51 | image.setImageURI(Uri.parse(videoBean.getImage())); 52 | txtTitle.setText(videoBean.getTitle()); 53 | txtTip.setText(videoBean.getTip()); 54 | txtDescription.setText(videoBean.getDescription()); 55 | } 56 | 57 | @Override 58 | public void setEvents() { 59 | btnBack.setOnClickListener(new View.OnClickListener() { 60 | @Override 61 | public void onClick(View v) { 62 | onBackPressed(); 63 | } 64 | }); 65 | 66 | boxPlay.setOnClickListener(new View.OnClickListener() { 67 | @Override 68 | public void onClick(View v) { 69 | jump(VideoPlayerActivity.class, new Parameter() 70 | .put("videoBean", videoBean) 71 | ); 72 | } 73 | }); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /app/src/main/java/com/kongzue/enjoylife/adapter/PhotoViewPagerAdapter.java: -------------------------------------------------------------------------------- 1 | package com.kongzue.enjoylife.adapter; 2 | 3 | import android.content.Context; 4 | import android.support.v4.view.PagerAdapter; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.ImageView; 8 | 9 | import com.bumptech.glide.Glide; 10 | import com.bumptech.glide.load.engine.DiskCacheStrategy; 11 | import com.github.chrisbanes.photoview.OnViewTapListener; 12 | import com.github.chrisbanes.photoview.PhotoView; 13 | 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | 17 | public class PhotoViewPagerAdapter extends PagerAdapter { 18 | 19 | private Context context; 20 | private List imageList; 21 | private onImageLayoutOnClickListener mOnClickListener; 22 | 23 | public PhotoViewPagerAdapter(Context context, List imageList) { 24 | this.context = context; 25 | this.imageList = imageList; 26 | } 27 | 28 | @Override 29 | public int getCount() { 30 | return imageList.size(); 31 | } 32 | 33 | @Override 34 | public boolean isViewFromObject(View view, Object object) { 35 | return view==object; 36 | } 37 | 38 | @Override 39 | public Object instantiateItem(ViewGroup container, int position) { 40 | PhotoView photoView = new PhotoView(context); 41 | photoView.setScaleType(ImageView.ScaleType.FIT_CENTER); 42 | final String imgUrl = imageList.get(position).getUrl(); 43 | Glide.with(context) 44 | .load(imgUrl) 45 | .diskCacheStrategy(DiskCacheStrategy.ALL) 46 | .into(photoView); 47 | photoView.setOnViewTapListener(new OnViewTapListener() { 48 | @Override 49 | public void onViewTap(View view, float v, float v1) { 50 | if (mOnClickListener!=null){ 51 | mOnClickListener.setOnImageOnClik(); 52 | } 53 | } 54 | }); 55 | 56 | photoView.setOnLongClickListener(new View.OnLongClickListener() { 57 | @Override 58 | public boolean onLongClick(View v) { 59 | if (mOnClickListener!=null){ 60 | mOnClickListener.setLongClick(imgUrl); 61 | } 62 | return true; 63 | } 64 | }); 65 | container.addView(photoView); 66 | return photoView; 67 | } 68 | 69 | @Override 70 | public void destroyItem(ViewGroup container, int position, Object object) { 71 | container.removeView((View) object); 72 | } 73 | 74 | public void setOnClickListener(onImageLayoutOnClickListener onClickListener) { 75 | mOnClickListener = onClickListener; 76 | } 77 | 78 | public interface onImageLayoutOnClickListener { 79 | void setOnImageOnClik(); 80 | 81 | void setLongClick(String url); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 13 | 14 | 19 | 20 | 21 | 22 | 27 | 28 | 32 | 33 | 36 | 37 | 45 | 46 | 51 | 52 | 59 | 60 | 67 | 68 | 69 | 70 | 75 | 76 | 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /app/src/main/java/com/kongzue/enjoylife/adapter/ZhihuListAdapter.java: -------------------------------------------------------------------------------- 1 | package com.kongzue.enjoylife.adapter; 2 | 3 | import android.content.Context; 4 | import android.net.Uri; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.BaseAdapter; 9 | import android.widget.TextView; 10 | 11 | import com.facebook.drawee.view.SimpleDraweeView; 12 | import com.kongzue.enjoylife.R; 13 | 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | 17 | public class ZhihuListAdapter extends BaseAdapter { 18 | private Context context; 19 | 20 | private List objects = new ArrayList(); 21 | 22 | public ZhihuListAdapter(Context context, List objects) { 23 | super(); 24 | this.context = context; 25 | this.objects = objects; 26 | } 27 | 28 | @Override 29 | public int getCount() { 30 | 31 | if (null != objects) { 32 | return objects.size(); 33 | } else { 34 | return 0; 35 | } 36 | } 37 | 38 | @Override 39 | public Object getItem(int position) { 40 | 41 | return objects.get(position); 42 | } 43 | 44 | @Override 45 | public long getItemId(int position) { 46 | 47 | return position; 48 | } 49 | 50 | @Override 51 | public View getView(int position, View convertView, ViewGroup parent) { 52 | 53 | ViewHolder viewHolder = null; 54 | 55 | if (convertView == null) { 56 | 57 | viewHolder = new ViewHolder(); 58 | // 获得容器 59 | convertView = LayoutInflater.from(this.context).inflate(R.layout.item_zhihu, null); 60 | 61 | // 初始化组件 62 | viewHolder.image = convertView.findViewById(R.id.image); 63 | viewHolder.txtTitle = convertView.findViewById(R.id.txt_title); 64 | 65 | // 给converHolder附加一个对象 66 | convertView.setTag(viewHolder); 67 | } else { 68 | // 取得converHolder附加的对象 69 | viewHolder = (ViewHolder) convertView.getTag(); 70 | } 71 | 72 | // 给组件设置资源 73 | ZhihuBean object = objects.get(position); 74 | viewHolder.txtTitle.setText(object.getTitle()); 75 | viewHolder.image.setImageURI(Uri.parse(object.getImage())); 76 | 77 | return convertView; 78 | } 79 | 80 | class ViewHolder { 81 | SimpleDraweeView image; 82 | TextView txtTitle; 83 | } 84 | 85 | public static class ZhihuBean { 86 | 87 | private int id; 88 | private String image; 89 | private String title; 90 | 91 | public ZhihuBean() { 92 | } 93 | 94 | public ZhihuBean(int id, String image, String title) { 95 | this.id = id; 96 | this.image = image; 97 | this.title = title; 98 | } 99 | 100 | public int getId() { 101 | return id; 102 | } 103 | 104 | public void setId(int id) { 105 | this.id = id; 106 | } 107 | 108 | public String getImage() { 109 | return image; 110 | } 111 | 112 | public void setImage(String image) { 113 | this.image = image; 114 | } 115 | 116 | public String getTitle() { 117 | return title; 118 | } 119 | 120 | public void setTitle(String title) { 121 | this.title = title; 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_zhihu_details.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 16 | 17 | 22 | 23 | 27 | 28 | 31 | 32 | 41 | 42 | 48 | 49 | 54 | 55 | 63 | 64 | 65 | 66 | 70 | 71 | 77 | 78 | 79 | 80 | 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /app/src/main/java/com/kongzue/enjoylife/view/CustomVideoView.java: -------------------------------------------------------------------------------- 1 | package com.kongzue.enjoylife.view; 2 | 3 | import android.content.Context; 4 | import android.graphics.SurfaceTexture; 5 | import android.util.AttributeSet; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.TextView; 9 | 10 | import com.kongzue.enjoylife.R; 11 | import com.shuyu.gsyvideoplayer.utils.GSYVideoType; 12 | import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer; 13 | 14 | /** 15 | * Created by shuyu on 2016/12/7. 16 | * 注意 17 | * 这个播放器的demo配置切换到全屏播放器 18 | * 这只是单纯的作为全屏播放显示,如果需要做大小屏幕切换,请记得在这里耶设置上视频全屏的需要的自定义配置 19 | */ 20 | public class CustomVideoView extends StandardGSYVideoPlayer { 21 | 22 | private TextView mMoreScale; 23 | 24 | //记住切换数据源类型 25 | private int mType = 0; 26 | 27 | /** 28 | * 1.5.0开始加入,如果需要不同布局区分功能,需要重载 29 | */ 30 | public CustomVideoView(Context context, Boolean fullFlag) { 31 | super(context, fullFlag); 32 | } 33 | 34 | public CustomVideoView(Context context) { 35 | super(context); 36 | } 37 | 38 | public CustomVideoView(Context context, AttributeSet attrs) { 39 | super(context, attrs); 40 | } 41 | 42 | @Override 43 | protected void init(Context context) { 44 | super.init(context); 45 | initView(); 46 | } 47 | 48 | private void initView() { 49 | mMoreScale = findViewById(R.id.moreScale); 50 | 51 | //切换清晰度 52 | mMoreScale.setOnClickListener(new OnClickListener() { 53 | @Override 54 | public void onClick(View v) { 55 | if (!mHadPlay) { 56 | return; 57 | } 58 | if (mType == 0) { 59 | mType = 1; 60 | } else if (mType == 1) { 61 | mType = 2; 62 | } else if (mType == 2) { 63 | mType = 3; 64 | } else if (mType == 3) { 65 | mType = 4; 66 | } else if (mType == 4) { 67 | mType = 0; 68 | } 69 | resolveTypeUI(); 70 | } 71 | }); 72 | 73 | } 74 | 75 | @Override 76 | public int getLayoutId() { 77 | return R.layout.custom_video; 78 | } 79 | 80 | /** 81 | * 旋转逻辑 82 | */ 83 | private void resolveRotateUI() { 84 | if (!mHadPlay) { 85 | return; 86 | } 87 | mTextureView.setRotation(mRotate); 88 | mTextureView.requestLayout(); 89 | } 90 | 91 | /** 92 | * 显示比例 93 | * 注意,GSYVideoType.setShowType是全局静态生效,除非重启APP。 94 | */ 95 | private void resolveTypeUI() { 96 | if (!mHadPlay) { 97 | return; 98 | } 99 | if (mType == 1) { 100 | mMoreScale.setText("16:9"); 101 | GSYVideoType.setShowType(GSYVideoType.SCREEN_TYPE_16_9); 102 | } else if (mType == 2) { 103 | mMoreScale.setText("4:3"); 104 | GSYVideoType.setShowType(GSYVideoType.SCREEN_TYPE_4_3); 105 | } else if (mType == 3) { 106 | mMoreScale.setText("全屏"); 107 | GSYVideoType.setShowType(GSYVideoType.SCREEN_TYPE_FULL); 108 | } else if (mType == 4) { 109 | mMoreScale.setText("拉伸全屏"); 110 | GSYVideoType.setShowType(GSYVideoType.SCREEN_MATCH_FULL); 111 | } else if (mType == 0) { 112 | mMoreScale.setText("默认比例"); 113 | GSYVideoType.setShowType(GSYVideoType.SCREEN_TYPE_DEFAULT); 114 | } 115 | changeTextureViewShowType(); 116 | if (mTextureView != null) 117 | mTextureView.requestLayout(); 118 | } 119 | 120 | 121 | } 122 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_gallery.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 13 | 14 | 18 | 19 | 27 | 28 | 29 | 30 | 35 | 36 | 40 | 41 | 44 | 45 | 54 | 55 | 61 | 62 | 67 | 68 | 76 | 77 | 78 | 79 | 83 | 84 | 90 | 91 | 92 | 93 | 98 | 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /app/src/main/java/com/kongzue/enjoylife/activity/VideoPlayerActivity.java: -------------------------------------------------------------------------------- 1 | package com.kongzue.enjoylife.activity; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.annotation.TargetApi; 5 | import android.content.pm.ActivityInfo; 6 | import android.content.res.Configuration; 7 | import android.os.Build; 8 | import android.support.v4.view.ViewCompat; 9 | import android.support.v7.app.AppCompatActivity; 10 | import android.os.Bundle; 11 | import android.text.TextUtils; 12 | import android.view.View; 13 | import android.widget.ImageView; 14 | 15 | import com.bumptech.glide.Glide; 16 | import com.kongzue.baseframework.BaseActivity; 17 | import com.kongzue.baseframework.interfaces.Layout; 18 | import com.kongzue.enjoylife.R; 19 | import com.kongzue.enjoylife.adapter.VideoListAdapter; 20 | import com.kongzue.enjoylife.view.CustomVideoView; 21 | import com.shuyu.gsyvideoplayer.listener.LockClickListener; 22 | import com.shuyu.gsyvideoplayer.utils.OrientationUtils; 23 | import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer; 24 | 25 | @Layout(R.layout.activity_video_player) 26 | public class VideoPlayerActivity extends BaseActivity { 27 | 28 | private CustomVideoView videoPlayer; 29 | 30 | @Override 31 | public void initViews() { 32 | videoPlayer = findViewById(R.id.video_player); 33 | } 34 | 35 | private VideoListAdapter.VideoBean videoBean; 36 | private OrientationUtils orientationUtils; 37 | 38 | private boolean isPlay; 39 | private boolean isPause; 40 | 41 | @Override 42 | public void initDatas() { 43 | videoBean = (VideoListAdapter.VideoBean) getParameter().get("videoBean"); 44 | if (videoBean == null) { 45 | finish(); 46 | return; 47 | } 48 | 49 | videoPlayer.setUp(videoBean.getUrl(), true, ""); 50 | videoPlayer.getTitleTextView().setVisibility(View.VISIBLE); 51 | videoPlayer.getTitleTextView().setText(videoBean.getTitle()); 52 | videoPlayer.getTitleTextView().setSingleLine(true); 53 | videoPlayer.getTitleTextView().setEllipsize(TextUtils.TruncateAt.END); 54 | videoPlayer.getBackButton().setVisibility(View.VISIBLE); 55 | orientationUtils = new OrientationUtils(this, videoPlayer); 56 | orientationUtils.setEnable(false); 57 | videoPlayer.setIsTouchWiget(true); 58 | videoPlayer.setRotateViewAuto(false); 59 | videoPlayer.setLockLand(false); 60 | videoPlayer.setShowFullAnimation(false); 61 | videoPlayer.setNeedLockFull(true); 62 | 63 | videoPlayer.getFullscreenButton().setOnClickListener(new View.OnClickListener() { 64 | @Override 65 | public void onClick(View v) { 66 | orientationUtils.resolveByClick(); 67 | videoPlayer.startWindowFullscreen(me, true, true); 68 | } 69 | }); 70 | videoPlayer.setBottomProgressBarDrawable(getResources().getDrawable(R.drawable.video_new_progress)); 71 | videoPlayer.setDialogVolumeProgressBar(getResources().getDrawable(R.drawable.video_new_volume_progress_bg)); 72 | videoPlayer.setDialogProgressBar(getResources().getDrawable(R.drawable.video_new_progress)); 73 | videoPlayer.setBottomShowProgressBarDrawable(getResources().getDrawable(R.drawable.video_new_seekbar_progress), 74 | getResources().getDrawable(R.drawable.video_new_seekbar_thumb)); 75 | videoPlayer.setDialogProgressColor(getResources().getColor(R.color.colorAccent), -11); 76 | videoPlayer.getBackButton().setOnClickListener(new View.OnClickListener() { 77 | @Override 78 | public void onClick(View v) { 79 | onBackPressed(); 80 | } 81 | }); 82 | } 83 | 84 | @Override 85 | public void setEvents() { 86 | 87 | } 88 | 89 | @Override 90 | protected void onPause() { 91 | super.onPause(); 92 | isPause = true; 93 | videoPlayer.onVideoPause(); 94 | } 95 | 96 | @Override 97 | protected void onResume() { 98 | super.onResume(); 99 | isPause = false; 100 | } 101 | 102 | @TargetApi(Build.VERSION_CODES.KITKAT) 103 | @Override 104 | protected void onDestroy() { 105 | super.onDestroy(); 106 | if (orientationUtils != null) 107 | orientationUtils.releaseListener(); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_video_details.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 15 | 19 | 20 | 23 | 24 | 29 | 30 | 34 | 35 | 40 | 41 | 42 | 43 | 50 | 51 | 56 | 57 | 66 | 67 | 68 | 69 | 70 | 71 | 78 | 79 | 86 | 87 | 95 | 96 | 97 | 98 | 106 | 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /.idea/markdown-navigator.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 36 | 37 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /app/src/main/java/com/kongzue/enjoylife/adapter/VideoListAdapter.java: -------------------------------------------------------------------------------- 1 | package com.kongzue.enjoylife.adapter; 2 | 3 | import android.content.Context; 4 | import android.net.Uri; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.BaseAdapter; 9 | import android.widget.TextView; 10 | 11 | import com.facebook.drawee.view.SimpleDraweeView; 12 | import com.kongzue.enjoylife.R; 13 | 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | 17 | public class VideoListAdapter extends BaseAdapter { 18 | private Context context; 19 | 20 | private List objects = new ArrayList(); 21 | 22 | public VideoListAdapter(Context context, List objects) { 23 | super(); 24 | this.context = context; 25 | this.objects = objects; 26 | } 27 | 28 | @Override 29 | public int getCount() { 30 | 31 | if (null != objects) { 32 | return objects.size(); 33 | } else { 34 | return 0; 35 | } 36 | } 37 | 38 | @Override 39 | public Object getItem(int position) { 40 | 41 | return objects.get(position); 42 | } 43 | 44 | @Override 45 | public long getItemId(int position) { 46 | 47 | return position; 48 | } 49 | 50 | @Override 51 | public View getView(int position, View convertView, ViewGroup parent) { 52 | 53 | ViewHolder viewHolder = null; 54 | 55 | if (convertView == null) { 56 | 57 | viewHolder = new ViewHolder(); 58 | // 获得容器 59 | convertView = LayoutInflater.from(this.context).inflate(R.layout.item_video, null); 60 | 61 | // 初始化组件 62 | viewHolder.image = convertView.findViewById(R.id.image); 63 | viewHolder.txtTitle = convertView.findViewById(R.id.txt_title); 64 | viewHolder.txtTip = convertView.findViewById(R.id.txt_tip); 65 | 66 | // 给converHolder附加一个对象 67 | convertView.setTag(viewHolder); 68 | } else { 69 | // 取得converHolder附加的对象 70 | viewHolder = (ViewHolder) convertView.getTag(); 71 | } 72 | 73 | // 给组件设置资源 74 | VideoBean object = objects.get(position); 75 | viewHolder.txtTitle.setText(object.getTitle()); 76 | viewHolder.txtTip.setText(object.getTip()); 77 | viewHolder.image.setImageURI(Uri.parse(object.getImage())); 78 | 79 | return convertView; 80 | } 81 | 82 | class ViewHolder { 83 | SimpleDraweeView image; 84 | TextView txtTitle; 85 | TextView txtTip; 86 | } 87 | 88 | public static class VideoBean { 89 | 90 | private int type; 91 | private int id; 92 | private String image; 93 | private String title; 94 | private String tip; 95 | private String description; 96 | private String url; 97 | 98 | public VideoBean() { 99 | } 100 | 101 | public VideoBean(int type, int id, String image, String title, String tip, String description, String url) { 102 | this.type = type; 103 | this.id = id; 104 | this.image = image; 105 | this.title = title; 106 | this.tip = tip; 107 | this.description = description; 108 | this.url = url; 109 | } 110 | 111 | public int getType() { 112 | return type; 113 | } 114 | 115 | public VideoBean setType(int type) { 116 | this.type = type; 117 | return this; 118 | } 119 | 120 | public int getId() { 121 | return id; 122 | } 123 | 124 | public VideoBean setId(int id) { 125 | this.id = id; 126 | return this; 127 | } 128 | 129 | public String getImage() { 130 | return image; 131 | } 132 | 133 | public VideoBean setImage(String image) { 134 | this.image = image; 135 | return this; 136 | } 137 | 138 | public String getTitle() { 139 | return title; 140 | } 141 | 142 | public VideoBean setTitle(String title) { 143 | this.title = title; 144 | return this; 145 | } 146 | 147 | public String getTip() { 148 | return tip; 149 | } 150 | 151 | public VideoBean setTip(String tip) { 152 | this.tip = tip; 153 | return this; 154 | } 155 | 156 | public String getDescription() { 157 | return description; 158 | } 159 | 160 | public VideoBean setDescription(String description) { 161 | this.description = description; 162 | return this; 163 | } 164 | 165 | public String getUrl() { 166 | return url; 167 | } 168 | 169 | public VideoBean setUrl(String url) { 170 | this.url = url; 171 | return this; 172 | } 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /app/src/main/java/com/kongzue/enjoylife/fragment/ZhihuFragment.java: -------------------------------------------------------------------------------- 1 | package com.kongzue.enjoylife.fragment; 2 | 3 | import android.view.View; 4 | import android.widget.AdapterView; 5 | import android.widget.ListView; 6 | 7 | import com.kongzue.baseframework.BaseFragment; 8 | import com.kongzue.baseframework.interfaces.Layout; 9 | import com.kongzue.enjoylife.R; 10 | import com.kongzue.enjoylife.activity.ZhihuDetailsActivity; 11 | import com.kongzue.enjoylife.adapter.VideoListAdapter; 12 | import com.kongzue.enjoylife.adapter.ZhihuListAdapter; 13 | import com.kongzue.enjoylife.listener.ResponseListener; 14 | import com.kongzue.enjoylife.request.HttpRequest; 15 | import com.kongzue.enjoylife.util.Parameter; 16 | import com.qbw.customview.RefreshLoadMoreLayout; 17 | 18 | import org.json.JSONArray; 19 | import org.json.JSONObject; 20 | 21 | import java.text.SimpleDateFormat; 22 | import java.util.ArrayList; 23 | import java.util.Calendar; 24 | import java.util.List; 25 | 26 | @Layout(R.layout.fragment_zhihu) 27 | public class ZhihuFragment extends BaseFragment implements RefreshLoadMoreLayout.CallBack { 28 | 29 | private List ZhihuBeanList = new ArrayList<>(); 30 | private ZhihuListAdapter zhihuListAdapter; 31 | 32 | private RefreshLoadMoreLayout refreshView; 33 | private ListView listView; 34 | 35 | @Override 36 | public void initViews() { 37 | refreshView = findViewById(R.id.refreshView); 38 | listView = findViewById(R.id.listView); 39 | } 40 | 41 | @Override 42 | public void initDatas() { 43 | listView.setPadding(0, dip2px(me, 50) + me.getStatusBarHeight(), 0, 0); 44 | refreshView.init(new RefreshLoadMoreLayout.Config(this)); 45 | 46 | loadData(); 47 | } 48 | 49 | private String now_date; 50 | private String load_date; 51 | 52 | private void loadData() { 53 | String url ; 54 | if (isNull(load_date)){ 55 | url="https://news-at.zhihu.com/api/4/news/latest"; 56 | }else{ 57 | url="https://news-at.zhihu.com/api/4/news/before/" + load_date; 58 | } 59 | HttpRequest.getInstance(me).getRequest(url, new Parameter(), new ResponseListener() { 60 | @Override 61 | public void onResponse(JSONObject main, Exception error) { 62 | refreshView.stopRefresh(); 63 | refreshView.stopLoadMore(); 64 | if (error == null) { 65 | try { 66 | now_date = main.getString("date"); 67 | JSONArray storiesList = main.getJSONArray("stories"); 68 | if (ZhihuBeanList == null) ZhihuBeanList = new ArrayList<>(); 69 | for (int i = 0; i < storiesList.length(); i++) { 70 | JSONObject itemOfStoriesList = storiesList.getJSONObject(i); 71 | 72 | int id = itemOfStoriesList.getInt("id"); 73 | String image = (String) itemOfStoriesList.getJSONArray("images").get(0); 74 | String title = itemOfStoriesList.getString("title"); 75 | 76 | ZhihuBeanList.add(new ZhihuListAdapter.ZhihuBean(id, image, title)); 77 | } 78 | if (zhihuListAdapter == null) { 79 | zhihuListAdapter = new ZhihuListAdapter(me, ZhihuBeanList); 80 | listView.setAdapter(zhihuListAdapter); 81 | } else { 82 | zhihuListAdapter.notifyDataSetChanged(); 83 | } 84 | } catch (Exception e) { 85 | toast("解析故障"); 86 | e.printStackTrace(); 87 | } 88 | } else { 89 | toast("出现错误"); 90 | error.printStackTrace(); 91 | } 92 | } 93 | }); 94 | } 95 | 96 | @Override 97 | public void setEvents() { 98 | listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 99 | @Override 100 | public void onItemClick(AdapterView parent, View view, int position, long id) { 101 | jump(ZhihuDetailsActivity.class, new com.kongzue.baseframework.util.Parameter() 102 | .put("ZhihuBean", ZhihuBeanList.get(position)) 103 | ); 104 | } 105 | }); 106 | } 107 | 108 | @Override 109 | public void onRefresh() { 110 | zhihuListAdapter = null; 111 | ZhihuBeanList = null; 112 | loadData(); 113 | } 114 | 115 | @Override 116 | public void onLoadMore() { 117 | try { 118 | SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); 119 | java.util.Date date = sdf.parse(now_date); 120 | Calendar c = Calendar.getInstance(); 121 | c.setTime(date); 122 | c.set(Calendar.DATE, c.get(Calendar.DATE) - 1); 123 | load_date = new SimpleDateFormat("yyyyMMdd").format(c.getTime()); 124 | log(">>>load_date=" + load_date); 125 | loadData(); 126 | }catch (Exception e){ 127 | refreshView.stopLoadMore(); 128 | e.printStackTrace(); 129 | } 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /app/src/main/java/com/kongzue/enjoylife/adapter/PhotoListAdapter.java: -------------------------------------------------------------------------------- 1 | package com.kongzue.enjoylife.adapter; 2 | 3 | import android.content.Context; 4 | import android.net.Uri; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.BaseAdapter; 9 | import android.widget.TextView; 10 | 11 | import com.facebook.drawee.view.SimpleDraweeView; 12 | import com.kongzue.enjoylife.R; 13 | 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | 17 | public class PhotoListAdapter extends BaseAdapter { 18 | 19 | private Context context; 20 | 21 | private List objects = new ArrayList(); 22 | 23 | public PhotoListAdapter(Context context, List objects) { 24 | super(); 25 | this.context = context; 26 | this.objects = objects; 27 | } 28 | 29 | @Override 30 | public int getCount() { 31 | 32 | if (null != objects) { 33 | return objects.size(); 34 | } else { 35 | return 0; 36 | } 37 | } 38 | 39 | @Override 40 | public Object getItem(int position) { 41 | 42 | return objects.get(position); 43 | } 44 | 45 | @Override 46 | public long getItemId(int position) { 47 | 48 | return position; 49 | } 50 | 51 | @Override 52 | public View getView(int position, View convertView, ViewGroup parent) { 53 | 54 | ViewHolder viewHolder = null; 55 | 56 | if (convertView == null) { 57 | 58 | viewHolder = new ViewHolder(); 59 | // 获得容器 60 | convertView = LayoutInflater.from(this.context).inflate(R.layout.item_photo, null); 61 | 62 | // 初始化组件 63 | viewHolder.image = convertView.findViewById(R.id.image); 64 | 65 | // 给converHolder附加一个对象 66 | convertView.setTag(viewHolder); 67 | } else { 68 | // 取得converHolder附加的对象 69 | viewHolder = (ViewHolder) convertView.getTag(); 70 | } 71 | 72 | // 给组件设置资源 73 | GalleryBean object = objects.get(position); 74 | if (object.getImages()!=null && !object.getImages().isEmpty())viewHolder.image.setImageURI(Uri.parse(object.getImages().get(0).getUrl())); 75 | 76 | return convertView; 77 | } 78 | 79 | class ViewHolder { 80 | SimpleDraweeView image; 81 | TextView title; 82 | TextView type; 83 | } 84 | 85 | public static class GalleryBean { 86 | 87 | private String id; 88 | private String title; 89 | private List images; 90 | 91 | public GalleryBean() { 92 | } 93 | 94 | public GalleryBean(String id, String title, List images) { 95 | this.id = id; 96 | this.title = title; 97 | this.images = images; 98 | } 99 | 100 | public String getId() { 101 | return id; 102 | } 103 | 104 | public GalleryBean setId(String id) { 105 | this.id = id; 106 | return this; 107 | } 108 | 109 | public String getTitle() { 110 | return title; 111 | } 112 | 113 | public GalleryBean setTitle(String title) { 114 | this.title = title; 115 | return this; 116 | } 117 | 118 | public List getImages() { 119 | return images; 120 | } 121 | 122 | public GalleryBean setImages(List images) { 123 | this.images = images; 124 | return this; 125 | } 126 | } 127 | 128 | 129 | public static class PhotoBean { 130 | 131 | private int img_id; 132 | private int user_id; 133 | private int width; 134 | private int height; 135 | private String url; 136 | 137 | public PhotoBean() { 138 | } 139 | 140 | public PhotoBean(int img_id, int user_id, int width, int height, String url) { 141 | this.img_id = img_id; 142 | this.user_id = user_id; 143 | this.width = width; 144 | this.height = height; 145 | this.url = url; 146 | } 147 | 148 | public int getImg_id() { 149 | return img_id; 150 | } 151 | 152 | public PhotoBean setImg_id(int img_id) { 153 | this.img_id = img_id; 154 | return this; 155 | } 156 | 157 | public int getUser_id() { 158 | return user_id; 159 | } 160 | 161 | public PhotoBean setUser_id(int user_id) { 162 | this.user_id = user_id; 163 | return this; 164 | } 165 | 166 | public int getWidth() { 167 | return width; 168 | } 169 | 170 | public PhotoBean setWidth(int width) { 171 | this.width = width; 172 | return this; 173 | } 174 | 175 | public int getHeight() { 176 | return height; 177 | } 178 | 179 | public PhotoBean setHeight(int height) { 180 | this.height = height; 181 | return this; 182 | } 183 | 184 | public String getUrl() { 185 | return url; 186 | } 187 | 188 | public PhotoBean setUrl(String url) { 189 | this.url = url; 190 | return this; 191 | } 192 | } 193 | 194 | } 195 | -------------------------------------------------------------------------------- /app/src/main/java/com/kongzue/enjoylife/fragment/PhotoFragment.java: -------------------------------------------------------------------------------- 1 | package com.kongzue.enjoylife.fragment; 2 | 3 | import android.os.Handler; 4 | import android.view.View; 5 | import android.widget.AdapterView; 6 | import android.widget.GridView; 7 | 8 | import com.kongzue.baseframework.BaseFragment; 9 | import com.kongzue.baseframework.interfaces.Layout; 10 | import com.kongzue.enjoylife.R; 11 | import com.kongzue.enjoylife.activity.GalleryActivity; 12 | import com.kongzue.enjoylife.adapter.PhotoListAdapter; 13 | import com.kongzue.enjoylife.listener.ResponseListener; 14 | import com.kongzue.enjoylife.request.HttpRequest; 15 | import com.kongzue.enjoylife.util.Parameter; 16 | import com.qbw.customview.RefreshLoadMoreLayout; 17 | 18 | import org.json.JSONArray; 19 | import org.json.JSONObject; 20 | 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | 24 | @Layout(R.layout.fragment_photo) 25 | public class PhotoFragment extends BaseFragment implements RefreshLoadMoreLayout.CallBack { 26 | 27 | private List GalleryBeanList; 28 | private PhotoListAdapter photoListAdapter; 29 | 30 | private RefreshLoadMoreLayout refreshView; 31 | private GridView gridView; 32 | 33 | @Override 34 | public void initViews() { 35 | refreshView = findViewById(R.id.refreshView); 36 | gridView = findViewById(R.id.grid_view); 37 | } 38 | 39 | @Override 40 | public void initDatas() { 41 | gridView.setPadding(0, dip2px(me, 50) + me.getStatusBarHeight(), 0, 0); 42 | refreshView.init(new RefreshLoadMoreLayout.Config(this)); 43 | 44 | loadData(); 45 | } 46 | 47 | private void loadData() { 48 | HttpRequest.getInstance(me).getRequest("https://api.tuchong.com/feed-app", new Parameter(), new ResponseListener() { 49 | @Override 50 | public void onResponse(JSONObject main, Exception error) { 51 | refreshView.stopRefresh(); 52 | refreshView.stopLoadMore(); 53 | if (error == null) { 54 | try { 55 | JSONArray feedList = main.getJSONArray("feedList"); 56 | if (GalleryBeanList == null) GalleryBeanList = new ArrayList<>(); 57 | for (int i = 0; i < feedList.length(); i++) { 58 | JSONObject itemOfFeedList = feedList.getJSONObject(i); 59 | JSONArray images = itemOfFeedList.getJSONArray("images"); 60 | List PhotoBeanList = new ArrayList<>(); 61 | for (int j = 0; j < images.length(); j++) { 62 | JSONObject itemOfImages = images.getJSONObject(j); 63 | PhotoListAdapter.PhotoBean photoBean = new PhotoListAdapter.PhotoBean( 64 | itemOfImages.getInt("img_id"), 65 | itemOfImages.getInt("user_id"), 66 | itemOfImages.getInt("width"), 67 | itemOfImages.getInt("height"), 68 | "https://photo.tuchong.com/" + itemOfImages.getInt("user_id") + "/f/" + itemOfImages.getInt("img_id") + ".jpg" 69 | ); 70 | PhotoBeanList.add(photoBean); 71 | } 72 | if (!PhotoBeanList.isEmpty()) { 73 | PhotoListAdapter.GalleryBean galleryBean = new PhotoListAdapter.GalleryBean( 74 | itemOfFeedList.getString("post_id"), 75 | itemOfFeedList.getString("title"), 76 | PhotoBeanList 77 | ); 78 | GalleryBeanList.add(galleryBean); 79 | } 80 | } 81 | if (photoListAdapter == null) { 82 | photoListAdapter = new PhotoListAdapter(me, GalleryBeanList); 83 | gridView.setAdapter(photoListAdapter); 84 | } else { 85 | photoListAdapter.notifyDataSetChanged(); 86 | } 87 | } catch (Exception e) { 88 | toast("解析故障"); 89 | e.printStackTrace(); 90 | } 91 | } else { 92 | toast("出现错误"); 93 | error.printStackTrace(); 94 | } 95 | } 96 | }); 97 | } 98 | 99 | @Override 100 | public void setEvents() { 101 | gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 102 | @Override 103 | public void onItemClick(AdapterView parent, View view, int position, long id) { 104 | jump(GalleryActivity.class, new com.kongzue.baseframework.util.Parameter() 105 | .put("GalleryBean",GalleryBeanList.get(position)) 106 | ); 107 | } 108 | }); 109 | } 110 | 111 | @Override 112 | public void onRefresh() { 113 | GalleryBeanList = null; 114 | photoListAdapter = null; 115 | loadData(); 116 | } 117 | 118 | @Override 119 | public void onLoadMore() { 120 | loadData(); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /app/src/main/java/com/kongzue/enjoylife/fragment/VideoFragment.java: -------------------------------------------------------------------------------- 1 | package com.kongzue.enjoylife.fragment; 2 | 3 | import android.view.View; 4 | import android.widget.AdapterView; 5 | import android.widget.ListView; 6 | 7 | import com.kongzue.baseframework.BaseFragment; 8 | import com.kongzue.baseframework.interfaces.Layout; 9 | import com.kongzue.enjoylife.R; 10 | import com.kongzue.enjoylife.activity.VideoDetailsActivity; 11 | import com.kongzue.enjoylife.adapter.PhotoListAdapter; 12 | import com.kongzue.enjoylife.adapter.VideoListAdapter; 13 | import com.kongzue.enjoylife.listener.ResponseListener; 14 | import com.kongzue.enjoylife.request.HttpRequest; 15 | import com.kongzue.enjoylife.util.Parameter; 16 | import com.qbw.customview.RefreshLoadMoreLayout; 17 | 18 | import org.json.JSONArray; 19 | import org.json.JSONObject; 20 | 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | 24 | @Layout(R.layout.fragment_video) 25 | public class VideoFragment extends BaseFragment implements RefreshLoadMoreLayout.CallBack { 26 | 27 | private List VideoBeanList = new ArrayList<>(); 28 | private VideoListAdapter videoListAdapter; 29 | 30 | private RefreshLoadMoreLayout refreshView; 31 | private ListView listView; 32 | 33 | @Override 34 | public void initViews() { 35 | refreshView = findViewById(R.id.refreshView); 36 | listView = findViewById(R.id.listView); 37 | } 38 | 39 | @Override 40 | public void initDatas() { 41 | listView.setPadding(0, dip2px(me, 50) + me.getStatusBarHeight(), 0, 0); 42 | refreshView.init(new RefreshLoadMoreLayout.Config(this)); 43 | post_url = "http://baobab.kaiyanapp.com/api/v2/feed"; 44 | loadData(); 45 | } 46 | 47 | private String post_url = "http://baobab.kaiyanapp.com/api/v2/feed"; 48 | 49 | private void loadData() { 50 | HttpRequest.getInstance(me).getRequest(post_url, new Parameter(), new ResponseListener() { 51 | @Override 52 | public void onResponse(JSONObject main, Exception error) { 53 | refreshView.stopRefresh(); 54 | refreshView.stopLoadMore(); 55 | if (error == null) { 56 | try { 57 | JSONArray itemList = main.getJSONArray("issueList").getJSONObject(0).getJSONArray("itemList"); 58 | if (VideoBeanList == null) VideoBeanList = new ArrayList<>(); 59 | for (int i = 0; i < itemList.length(); i++) { 60 | JSONObject item = itemList.getJSONObject(i); 61 | int type = item.getString("type").equals("video") ? 0 : 1; 62 | int id = 0; 63 | String title = ""; 64 | String description = ""; 65 | String image = ""; 66 | String url = ""; 67 | String tip = ""; 68 | if (type == 0) { 69 | description = item.getJSONObject("data").getString("description"); 70 | title = item.getJSONObject("data").getString("title"); 71 | id = item.getJSONObject("data").getInt("id"); 72 | image = item.getJSONObject("data").getJSONObject("cover").getString("homepage"); 73 | url = item.getJSONObject("data").getString("playUrl"); 74 | tip = "#" + item.getJSONObject("data").getString("category") + " / " + parseTimeToMinAndSec(item.getJSONObject("data").getInt("duration")); 75 | } else { 76 | try { 77 | image = item.getJSONObject("data").getString("image"); 78 | } catch (Exception e) { 79 | e.printStackTrace(); 80 | } 81 | } 82 | post_url = main.getString("nextPageUrl"); 83 | if (!isNull(image)) 84 | VideoBeanList.add(new VideoListAdapter.VideoBean(type, id, image, title, tip, description, url)); 85 | } 86 | if (videoListAdapter == null) { 87 | videoListAdapter = new VideoListAdapter(me, VideoBeanList); 88 | listView.setAdapter(videoListAdapter); 89 | } else { 90 | videoListAdapter.notifyDataSetChanged(); 91 | } 92 | } catch (Exception e) { 93 | toast("解析故障"); 94 | e.printStackTrace(); 95 | } 96 | } else { 97 | toast("出现错误"); 98 | error.printStackTrace(); 99 | } 100 | } 101 | }); 102 | } 103 | 104 | @Override 105 | public void setEvents() { 106 | listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 107 | @Override 108 | public void onItemClick(AdapterView parent, View view, int position, long id) { 109 | VideoListAdapter.VideoBean videoBean = VideoBeanList.get(position); 110 | if (videoBean.getType() == 0) { 111 | jump(VideoDetailsActivity.class, new com.kongzue.baseframework.util.Parameter().put("videoBean", videoBean)); 112 | } 113 | } 114 | }); 115 | } 116 | 117 | @Override 118 | public void onRefresh() { 119 | videoListAdapter = null; 120 | VideoBeanList = null; 121 | post_url = "http://baobab.kaiyanapp.com/api/v2/feed"; 122 | loadData(); 123 | } 124 | 125 | @Override 126 | public void onLoadMore() { 127 | loadData(); 128 | } 129 | 130 | public String parseTimeToMinAndSec(int sec) { 131 | int minutes = sec / 60; 132 | int remainingSeconds = sec % 60; 133 | return minutes + "'" + remainingSeconds + "\""; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /app/src/main/java/com/kongzue/enjoylife/activity/AboutActivity.java: -------------------------------------------------------------------------------- 1 | package com.kongzue.enjoylife.activity; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.content.Intent; 5 | import android.graphics.Color; 6 | import android.graphics.Paint; 7 | import android.net.Uri; 8 | import android.support.v7.app.AppCompatActivity; 9 | import android.os.Bundle; 10 | import android.view.View; 11 | import android.view.ViewGroup; 12 | import android.widget.ImageView; 13 | import android.widget.LinearLayout; 14 | import android.widget.RelativeLayout; 15 | import android.widget.TextView; 16 | 17 | import com.kongzue.baseframework.BaseActivity; 18 | import com.kongzue.baseframework.interfaces.DarkStatusBarTheme; 19 | import com.kongzue.baseframework.interfaces.Layout; 20 | import com.kongzue.dialog.util.BlurView; 21 | import com.kongzue.enjoylife.R; 22 | import com.kongzue.enjoylife.util.SwipBackActivity; 23 | 24 | @Layout(R.layout.activity_about) 25 | @DarkStatusBarTheme(true) 26 | public class AboutActivity extends SwipBackActivity { 27 | 28 | private TextView linkGithub; 29 | private TextView linkXhbEl; 30 | private TextView linkKongzueDialog; 31 | private TextView linkKongzueBaseframework; 32 | private TextView linkKongzueBaseOkHttp; 33 | private TextView linkKongzueUpdate; 34 | private TextView linkFresco; 35 | private TextView linkRefreshLoadMoreLayout; 36 | private TextView linkPhotoView; 37 | private TextView linkGlide; 38 | private TextView linkGSYVideoPlayer; 39 | private TextView linkSwipeBack; 40 | private RelativeLayout boxTable; 41 | private BlurView blur; 42 | private LinearLayout boxTableChild; 43 | private LinearLayout btnBack; 44 | private ImageView btnShare; 45 | 46 | @Override 47 | public void initViews() { 48 | linkGithub = findViewById(R.id.link_github); 49 | linkXhbEl = findViewById(R.id.link_xhb_el); 50 | linkKongzueDialog = findViewById(R.id.link_kongzue_dialog); 51 | linkKongzueBaseframework = findViewById(R.id.link_kongzue_baseframework); 52 | linkKongzueBaseOkHttp = findViewById(R.id.link_kongzue_baseOkHttp); 53 | linkKongzueUpdate = findViewById(R.id.link_kongzue_update); 54 | linkFresco = findViewById(R.id.link_fresco); 55 | linkRefreshLoadMoreLayout = findViewById(R.id.link_RefreshLoadMoreLayout); 56 | linkPhotoView = findViewById(R.id.link_PhotoView); 57 | linkGlide = findViewById(R.id.link_glide); 58 | linkGSYVideoPlayer = findViewById(R.id.link_GSYVideoPlayer); 59 | linkSwipeBack = findViewById(R.id.link_SwipeBack); 60 | boxTable = findViewById(R.id.box_table); 61 | blur = findViewById(R.id.blur); 62 | boxTableChild = findViewById(R.id.box_table_child); 63 | btnBack = findViewById(R.id.btn_back); 64 | btnShare = findViewById(R.id.btn_share); 65 | } 66 | 67 | @Override 68 | public void initDatas() { 69 | blur.setOverlayColor(Color.argb(200, 235, 235, 235)); 70 | blur.setRadius(me, 0, 0); 71 | boxTable.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dip2px(me, 50) + getStatusBarHeight())); 72 | 73 | linkGithub.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG); 74 | linkXhbEl.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG); 75 | linkKongzueDialog.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG); 76 | linkKongzueBaseframework.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG); 77 | linkKongzueBaseOkHttp.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG); 78 | linkKongzueUpdate.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG); 79 | linkFresco.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG); 80 | linkRefreshLoadMoreLayout.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG); 81 | linkPhotoView.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG); 82 | linkGlide.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG); 83 | linkGSYVideoPlayer.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG); 84 | linkSwipeBack.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG); 85 | } 86 | 87 | @Override 88 | public void setEvents() { 89 | linkGithub.setOnClickListener(onLinkClickListener); 90 | linkXhbEl.setOnClickListener(onLinkClickListener); 91 | linkKongzueDialog.setOnClickListener(onLinkClickListener); 92 | linkKongzueBaseframework.setOnClickListener(onLinkClickListener); 93 | linkKongzueBaseOkHttp.setOnClickListener(onLinkClickListener); 94 | linkKongzueUpdate.setOnClickListener(onLinkClickListener); 95 | linkFresco.setOnClickListener(onLinkClickListener); 96 | linkRefreshLoadMoreLayout.setOnClickListener(onLinkClickListener); 97 | linkPhotoView.setOnClickListener(onLinkClickListener); 98 | linkGlide.setOnClickListener(onLinkClickListener); 99 | linkGSYVideoPlayer.setOnClickListener(onLinkClickListener); 100 | linkSwipeBack.setOnClickListener(onLinkClickListener); 101 | 102 | btnBack.setOnClickListener(new View.OnClickListener() { 103 | @Override 104 | public void onClick(View v) { 105 | onBackPressed(); 106 | } 107 | }); 108 | 109 | btnShare.setOnClickListener(new View.OnClickListener() { 110 | @Override 111 | public void onClick(View v) { 112 | Intent share_intent = new Intent(); 113 | share_intent.setAction(Intent.ACTION_SEND); 114 | share_intent.setType("text/plain"); 115 | share_intent.putExtra(Intent.EXTRA_SUBJECT, "分享"); 116 | share_intent.putExtra(Intent.EXTRA_TEXT, "发现了一款非常棒的App「一日读」,每天一张精选照片、一个精选短视频,知乎美文,完全开源不收费,太赞了! " + getString(R.string.link_github)); 117 | share_intent = Intent.createChooser(share_intent, "分享"); 118 | startActivity(share_intent); 119 | } 120 | }); 121 | } 122 | 123 | private View.OnClickListener onLinkClickListener = new View.OnClickListener() { 124 | @Override 125 | public void onClick(View v) { 126 | String url = ((TextView)v).getText().toString(); 127 | Uri uri = Uri.parse(url); 128 | Intent intent = new Intent(Intent.ACTION_VIEW, uri); 129 | startActivity(intent); 130 | } 131 | }; 132 | } 133 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/java/com/kongzue/enjoylife/activity/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.kongzue.enjoylife.activity; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.graphics.Color; 5 | import android.support.v4.app.FragmentTransaction; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.os.Bundle; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.widget.FrameLayout; 11 | import android.widget.ImageView; 12 | import android.widget.LinearLayout; 13 | import android.widget.RelativeLayout; 14 | 15 | import com.kongzue.baseframework.BaseActivity; 16 | import com.kongzue.baseframework.BaseFragment; 17 | import com.kongzue.baseframework.interfaces.DarkStatusBarTheme; 18 | import com.kongzue.baseframework.interfaces.Layout; 19 | import com.kongzue.dialog.util.BlurView; 20 | import com.kongzue.dialog.v2.DialogSettings; 21 | import com.kongzue.dialog.v2.MessageDialog; 22 | import com.kongzue.dialog.v2.Notification; 23 | import com.kongzue.enjoylife.R; 24 | import com.kongzue.enjoylife.fragment.PhotoFragment; 25 | import com.kongzue.enjoylife.fragment.VideoFragment; 26 | import com.kongzue.enjoylife.fragment.ZhihuFragment; 27 | 28 | import static com.kongzue.dialog.v2.DialogSettings.TYPE_IOS; 29 | import static com.kongzue.dialog.v2.DialogSettings.TYPE_KONGZUE; 30 | 31 | @Layout(R.layout.activity_main) 32 | @DarkStatusBarTheme(true) 33 | public class MainActivity extends BaseActivity { 34 | 35 | public final static int ID_PHOTO = 0; 36 | public final static int ID_VIDEO = 1; 37 | public final static int ID_ZHIHU = 2; 38 | 39 | private PhotoFragment photoFragment; 40 | private VideoFragment videoFragment; 41 | private ZhihuFragment zhihuFragment; 42 | 43 | private FrameLayout frame; 44 | private RelativeLayout boxTable; 45 | private BlurView blur; 46 | private LinearLayout boxTableChild; 47 | private ImageView btnPhoto; 48 | private ImageView btnVideo; 49 | private ImageView btnZhihu; 50 | private ImageView btnAbout; 51 | 52 | @Override 53 | public void initViews() { 54 | frame = findViewById(R.id.frame); 55 | boxTable = findViewById(R.id.box_table); 56 | blur = findViewById(R.id.blur); 57 | boxTableChild = findViewById(R.id.box_table_child); 58 | btnPhoto = findViewById(R.id.btn_photo); 59 | btnVideo = findViewById(R.id.btn_video); 60 | btnZhihu = findViewById(R.id.btn_zhihu); 61 | btnAbout = findViewById(R.id.btn_about); 62 | } 63 | 64 | @Override 65 | public void initDatas() { 66 | blur.setOverlayColor(Color.argb(200, 235, 235, 235)); 67 | blur.setRadius(me, 0, 0); 68 | boxTable.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dip2px(me, 50) + getStatusBarHeight())); 69 | 70 | showFragment(ID_PHOTO); 71 | 72 | MessageDialog.show(me, "欢迎来到一日读", "本项目为开源项目,仅供学习交流使用,程序内使用到的资源来源于图虫、开眼和知乎日报,数据版权归原作者所有,请勿用于商业用途。\n项目Github地址:https://github.com/kongzue/EnjoyLife"); 73 | } 74 | 75 | @Override 76 | public void setEvents() { 77 | btnAbout.setOnClickListener(new View.OnClickListener() { 78 | @Override 79 | public void onClick(View v) { 80 | jump(AboutActivity.class); 81 | } 82 | }); 83 | 84 | btnPhoto.setOnClickListener(new View.OnClickListener() { 85 | @Override 86 | public void onClick(View v) { 87 | showFragment(ID_PHOTO); 88 | } 89 | }); 90 | 91 | btnVideo.setOnClickListener(new View.OnClickListener() { 92 | @Override 93 | public void onClick(View v) { 94 | showFragment(ID_VIDEO); 95 | } 96 | }); 97 | 98 | btnZhihu.setOnClickListener(new View.OnClickListener() { 99 | @Override 100 | public void onClick(View v) { 101 | showFragment(ID_ZHIHU); 102 | } 103 | }); 104 | } 105 | 106 | public void showFragment(int id) { 107 | FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 108 | transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); 109 | if (photoFragment != null) transaction.hide(photoFragment); 110 | if (videoFragment != null) transaction.hide(videoFragment); 111 | if (zhihuFragment != null) transaction.hide(zhihuFragment); 112 | btnPhoto.setAlpha(0.3f); 113 | btnVideo.setAlpha(0.3f); 114 | btnZhihu.setAlpha(0.3f); 115 | switch (id) { 116 | case ID_PHOTO: 117 | btnPhoto.setAlpha(1.0f); 118 | if (photoFragment == null) { 119 | photoFragment = new PhotoFragment(); 120 | transaction.add(R.id.frame, photoFragment); 121 | } 122 | transaction.show(photoFragment); 123 | break; 124 | case ID_VIDEO: 125 | btnVideo.setAlpha(1.0f); 126 | if (videoFragment == null) { 127 | videoFragment = new VideoFragment(); 128 | transaction.add(R.id.frame, videoFragment); 129 | } 130 | transaction.show(videoFragment); 131 | break; 132 | case ID_ZHIHU: 133 | btnZhihu.setAlpha(1.0f); 134 | if (zhihuFragment == null) { 135 | zhihuFragment = new ZhihuFragment(); 136 | transaction.add(R.id.frame, zhihuFragment); 137 | } 138 | transaction.show(zhihuFragment); 139 | break; 140 | default: 141 | break; 142 | } 143 | transaction.commit(); 144 | } 145 | 146 | 147 | private long firstPressedTime; 148 | 149 | @Override 150 | public void onBackPressed() { 151 | if (System.currentTimeMillis() - firstPressedTime < 2000) { 152 | DialogSettings.type = TYPE_KONGZUE; 153 | Notification.show(me, 0, "欢迎下次再来~", Notification.TYPE_FINISH); 154 | DialogSettings.type = TYPE_IOS; 155 | super.onBackPressed(); 156 | } else { 157 | DialogSettings.type = TYPE_KONGZUE; 158 | Notification.show(me, 0, "再按一次退出", Notification.TYPE_ERROR); 159 | DialogSettings.type = TYPE_IOS; 160 | firstPressedTime = System.currentTimeMillis(); 161 | } 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /app/src/main/res/layout/custom_video.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 12 | 13 | 14 | 15 | 16 | 28 | 29 | 38 | 39 | 46 | 47 | 61 | 62 | 69 | 70 | 71 | 78 | 79 | 80 | 88 | 89 | 96 | 97 | 104 | 105 | 112 | 113 | 114 | 123 | 124 | 134 | 135 | 144 | 145 | 152 | 153 | 161 | 162 | 172 | 173 | 174 | 175 | 183 | 184 | 185 | -------------------------------------------------------------------------------- /app/src/main/java/com/kongzue/enjoylife/request/HttpRequest.java: -------------------------------------------------------------------------------- 1 | package com.kongzue.enjoylife.request; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.util.Log; 6 | 7 | import com.kongzue.enjoylife.BuildConfig; 8 | import com.kongzue.enjoylife.listener.ResponseListener; 9 | import com.kongzue.enjoylife.util.Parameter; 10 | 11 | import org.json.JSONObject; 12 | 13 | import java.io.File; 14 | import java.io.IOException; 15 | import java.io.InputStream; 16 | import java.security.KeyStore; 17 | import java.security.SecureRandom; 18 | import java.security.cert.CertificateFactory; 19 | import java.util.Map; 20 | import java.util.concurrent.TimeUnit; 21 | 22 | import javax.net.ssl.SSLContext; 23 | import javax.net.ssl.SSLSocketFactory; 24 | import javax.net.ssl.TrustManagerFactory; 25 | 26 | import okhttp3.Cache; 27 | import okhttp3.Call; 28 | import okhttp3.Callback; 29 | import okhttp3.OkHttpClient; 30 | import okhttp3.RequestBody; 31 | 32 | /** 33 | * BaseOkHttp 34 | * Created by myzcx on 2017/12/27. 35 | * ver:1.0 36 | */ 37 | 38 | public class HttpRequest { 39 | 40 | private static int GET_REQUEST = 1; 41 | private static int POST_REQUEST = 0; 42 | 43 | //Https请求需要传入Assets目录下的证书文件名称 44 | private String SSLInAssetsFileName; 45 | 46 | private Parameter headers; 47 | 48 | private static OkHttpClient okHttpClient; 49 | private static Activity context; 50 | 51 | //单例 52 | private static HttpRequest httpRequest; 53 | 54 | private HttpRequest() { 55 | } 56 | 57 | //默认请求创建方法 58 | public static HttpRequest getInstance(Activity c) { 59 | if (httpRequest == null) { 60 | synchronized (HttpRequest.class) { 61 | if (httpRequest == null) { 62 | httpRequest = new HttpRequest(); 63 | context = c; 64 | } 65 | } 66 | } 67 | return httpRequest; 68 | } 69 | 70 | //信任指定证书的Https请求 71 | public static HttpRequest getInstance(Activity c, String SSLFileNameInAssets) { 72 | if (httpRequest == null) { 73 | synchronized (HttpRequest.class) { 74 | if (httpRequest == null) { 75 | httpRequest = new HttpRequest(); 76 | httpRequest.context = c; 77 | httpRequest.SSLInAssetsFileName = SSLFileNameInAssets; 78 | } 79 | } 80 | } 81 | return httpRequest; 82 | } 83 | 84 | public String getSSLInAssetsFileName() { 85 | return SSLInAssetsFileName; 86 | } 87 | 88 | public HttpRequest setSSLInAssetsFileName(String SSLInAssetsFileName) { 89 | this.SSLInAssetsFileName = SSLInAssetsFileName; 90 | return this; 91 | } 92 | 93 | public Parameter getHeaders() { 94 | return headers; 95 | } 96 | 97 | public HttpRequest setHeaders(Parameter headers) { 98 | this.headers = headers; 99 | return this; 100 | } 101 | 102 | public void postRequest(String partUrl, final Parameter parameter, 103 | final ResponseListener listener) { 104 | doRequest(partUrl, parameter, listener, POST_REQUEST); 105 | } 106 | 107 | public void getRequest(String partUrl, final Parameter parameter, 108 | final ResponseListener listener) { 109 | doRequest(partUrl, parameter, listener, GET_REQUEST); 110 | } 111 | 112 | private void doRequest(final String partUrl, final Parameter parameter, final ResponseListener listener, int requestType) { 113 | 114 | if (BuildConfig.DEBUG) 115 | Log.i(">>>", "buildRequest:" + partUrl + "\nparameter:" + parameter.toParameterString()); 116 | 117 | try { 118 | OkHttpClient okHttpClient; 119 | if (SSLInAssetsFileName == null || SSLInAssetsFileName.isEmpty()) { 120 | okHttpClient = new OkHttpClient(); 121 | } else { 122 | okHttpClient = getOkHttpClient(context, context.getAssets().open(SSLInAssetsFileName)); 123 | } 124 | 125 | RequestBody requestBody = parameter.toOkHttpParameter(); 126 | 127 | //创建请求 128 | okhttp3.Request request; 129 | okhttp3.Request.Builder builder = new okhttp3.Request.Builder(); 130 | //请求类型处理 131 | if (requestType == GET_REQUEST) { 132 | builder.url(partUrl.contains("?") ? partUrl : partUrl + "?" + parameter.toParameterString()); 133 | } else { 134 | builder.url(partUrl); 135 | builder.post(requestBody); 136 | } 137 | //请求头处理 138 | if (parameter != null) { 139 | if (headers != null && !headers.entrySet().isEmpty()) { 140 | for (Map.Entry entry : headers.entrySet()) { 141 | builder.addHeader(entry.getKey(), entry.getValue()); 142 | } 143 | } 144 | } 145 | request = builder.build(); 146 | 147 | okHttpClient.newCall(request).enqueue(new Callback() { 148 | @Override 149 | public void onFailure(Call call, final IOException e) { 150 | Log.e(">>>", "failure:" + partUrl + "\nparameter:" + parameter.toParameterString() + "\ninfo:" + e); 151 | //回到主线程处理 152 | context.runOnUiThread(new Runnable() { 153 | @Override 154 | public void run() { 155 | listener.onResponse(null, e); 156 | } 157 | }); 158 | } 159 | 160 | @Override 161 | public void onResponse(Call call, okhttp3.Response response) throws IOException { 162 | final String strResponse = response.body().string(); 163 | if (BuildConfig.DEBUG) 164 | Log.i(">>>", "request:" + partUrl + "\nparameter:" + parameter.toParameterString() + "\nresponse:" + strResponse); 165 | 166 | //回到主线程处理 167 | context.runOnUiThread(new Runnable() { 168 | @Override 169 | public void run() { 170 | try { 171 | listener.onResponse(new JSONObject(strResponse), null); 172 | } catch (Exception e) { 173 | listener.onResponse(null, e); 174 | } 175 | } 176 | }); 177 | } 178 | }); 179 | } catch (Exception e) { 180 | e.printStackTrace(); 181 | } 182 | 183 | } 184 | 185 | public static OkHttpClient getOkHttpClient(Context context, InputStream... certificates) { 186 | if (okHttpClient == null) { 187 | File sdcache = context.getExternalCacheDir(); 188 | int cacheSize = 10 * 1024 * 1024; 189 | OkHttpClient.Builder builder = new OkHttpClient.Builder() 190 | .connectTimeout(20, TimeUnit.SECONDS) 191 | .writeTimeout(20, TimeUnit.SECONDS) 192 | .readTimeout(20, TimeUnit.SECONDS) 193 | .cache(new Cache(sdcache.getAbsoluteFile(), cacheSize)); 194 | if (certificates != null) { 195 | builder.sslSocketFactory(getSSLSocketFactory(certificates)); 196 | } 197 | okHttpClient = builder.build(); 198 | } 199 | return okHttpClient; 200 | } 201 | 202 | private static SSLSocketFactory getSSLSocketFactory(InputStream... certificates) { 203 | try { 204 | CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); 205 | KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); 206 | keyStore.load(null); 207 | int index = 0; 208 | for (InputStream certificate : certificates) { 209 | String certificateAlias = Integer.toString(index++); 210 | keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate)); 211 | 212 | try { 213 | if (certificate != null) 214 | certificate.close(); 215 | } catch (IOException e) { 216 | } 217 | } 218 | SSLContext sslContext = SSLContext.getInstance("TLS"); 219 | TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 220 | trustManagerFactory.init(keyStore); 221 | sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom()); 222 | return sslContext.getSocketFactory(); 223 | } catch (Exception e) { 224 | e.printStackTrace(); 225 | } 226 | return null; 227 | } 228 | } 229 | -------------------------------------------------------------------------------- /app/src/main/java/com/kongzue/enjoylife/activity/ZhihuDetailsActivity.java: -------------------------------------------------------------------------------- 1 | package com.kongzue.enjoylife.activity; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.content.Intent; 5 | import android.graphics.Color; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.os.Bundle; 8 | import android.text.TextUtils; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | import android.widget.ImageView; 12 | import android.widget.LinearLayout; 13 | import android.widget.RelativeLayout; 14 | 15 | import com.kongzue.baseframework.BaseActivity; 16 | import com.kongzue.baseframework.interfaces.DarkStatusBarTheme; 17 | import com.kongzue.baseframework.interfaces.Layout; 18 | import com.kongzue.dialog.listener.OnMenuItemClickListener; 19 | import com.kongzue.dialog.util.BlurView; 20 | import com.kongzue.dialog.v2.BottomMenu; 21 | import com.kongzue.dialog.v2.WaitDialog; 22 | import com.kongzue.enjoylife.R; 23 | import com.kongzue.enjoylife.adapter.ZhihuListAdapter; 24 | import com.kongzue.enjoylife.listener.ResponseListener; 25 | import com.kongzue.enjoylife.request.HttpRequest; 26 | import com.kongzue.enjoylife.util.Parameter; 27 | import com.kongzue.enjoylife.util.SwipBackActivity; 28 | import com.tencent.smtt.sdk.WebSettings; 29 | import com.tencent.smtt.sdk.WebView; 30 | import com.tencent.smtt.sdk.WebViewClient; 31 | 32 | import org.json.JSONObject; 33 | 34 | import java.util.ArrayList; 35 | import java.util.List; 36 | 37 | @Layout(R.layout.activity_zhihu_details) 38 | @DarkStatusBarTheme(true) 39 | public class ZhihuDetailsActivity extends SwipBackActivity { 40 | 41 | private WebView webView; 42 | private RelativeLayout boxTable; 43 | private BlurView blur; 44 | private LinearLayout boxTableChild; 45 | private LinearLayout btnBack; 46 | private ImageView btnShare; 47 | 48 | @Override 49 | public void initViews() { 50 | webView = findViewById(R.id.webView); 51 | boxTable = findViewById(R.id.box_table); 52 | blur = findViewById(R.id.blur); 53 | boxTableChild = findViewById(R.id.box_table_child); 54 | btnBack = findViewById(R.id.btn_back); 55 | btnShare = findViewById(R.id.btn_share); 56 | } 57 | 58 | private ZhihuListAdapter.ZhihuBean zhihuBean; 59 | 60 | @Override 61 | public void initDatas() { 62 | blur.setOverlayColor(Color.argb(200, 235, 235, 235)); 63 | blur.setRadius(me, 0, 0); 64 | boxTable.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dip2px(me, 50) + getStatusBarHeight())); 65 | webView.getView().setPadding(0, dip2px(me, 50) + me.getStatusBarHeight(), 0, 0); 66 | 67 | if (getParameter() == null) { 68 | finish(); 69 | return; 70 | } 71 | if (getParameter().get("ZhihuBean") == null) { 72 | finish(); 73 | return; 74 | } else { 75 | zhihuBean = (ZhihuListAdapter.ZhihuBean) getParameter().get("ZhihuBean"); 76 | } 77 | initWebView(); 78 | loadPage(); 79 | } 80 | 81 | private void initWebView() { 82 | WebSettings webSettings = webView.getSettings(); 83 | 84 | //如果访问的页面中要与Javascript交互,则webview必须设置支持Javascript 85 | webSettings.setJavaScriptEnabled(true); 86 | 87 | //设置自适应屏幕,两者合用 88 | webSettings.setUseWideViewPort(true); //将图片调整到适合webview的大小 89 | webSettings.setLoadWithOverviewMode(true); // 缩放至屏幕的大小 90 | 91 | //缩放操作 92 | webSettings.setSupportZoom(true); //支持缩放,默认为true。是下面那个的前提。 93 | webSettings.setBuiltInZoomControls(true); //设置内置的缩放控件。若为false,则该WebView不可缩放 94 | webSettings.setDisplayZoomControls(false); //隐藏原生的缩放控件 95 | 96 | //其他细节操作 97 | webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //关闭webview中缓存 98 | webSettings.setAllowFileAccess(true); //设置可以访问文件 99 | webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //支持通过JS打开新窗口 100 | webSettings.setLoadsImagesAutomatically(true); //支持自动加载图片 101 | webSettings.setDefaultTextEncodingName("utf-8");//设置编码格式 102 | 103 | webView.setWebViewClient(new WebViewClient() { 104 | @Override 105 | public boolean shouldOverrideUrlLoading(WebView view, String url) { 106 | view.loadUrl(url); 107 | return true; 108 | } 109 | }); 110 | } 111 | 112 | private String body; 113 | private String css; 114 | private String share_url; 115 | 116 | private void loadPage() { 117 | WaitDialog.show(me, "加载中..."); 118 | HttpRequest.getInstance(me).getRequest("https://news-at.zhihu.com/api/4/news/" + zhihuBean.getId(), new Parameter(), new ResponseListener() { 119 | @Override 120 | public void onResponse(JSONObject main, Exception error) { 121 | WaitDialog.dismiss(); 122 | try { 123 | body = main.getString("body"); 124 | share_url = main.getString("share_url"); 125 | css = (String) main.getJSONArray("css").get(0); 126 | webView.loadData(htmlText(body, css), "text/html; charset=utf-8", "utf-8"); 127 | } catch (Exception e) { 128 | e.printStackTrace(); 129 | } 130 | } 131 | }); 132 | } 133 | 134 | @Override 135 | public void setEvents() { 136 | btnBack.setOnClickListener(new View.OnClickListener() { 137 | @Override 138 | public void onClick(View v) { 139 | onBackPressed(); 140 | } 141 | }); 142 | 143 | btnShare.setOnClickListener(new View.OnClickListener() { 144 | @Override 145 | public void onClick(View v) { 146 | List listMenu = new ArrayList<>(); 147 | listMenu.add("分享此文章"); 148 | BottomMenu.show(me, listMenu, new OnMenuItemClickListener() { 149 | @Override 150 | public void onClick(String text, int index) { 151 | Intent share_intent = new Intent(); 152 | share_intent.setAction(Intent.ACTION_SEND); 153 | share_intent.setType("text/plain"); 154 | share_intent.putExtra(Intent.EXTRA_SUBJECT, "分享"); 155 | share_intent.putExtra(Intent.EXTRA_TEXT, zhihuBean.getTitle() + " " +share_url + " 分享自知乎网"); 156 | share_intent = Intent.createChooser(share_intent, "分享"); 157 | startActivity(share_intent); 158 | } 159 | }); 160 | } 161 | }); 162 | } 163 | 164 | @Override 165 | public void onBackPressed() { 166 | if (webView.canGoBack()) { 167 | webView.goBack(); 168 | } else { 169 | super.onBackPressed(); 170 | } 171 | } 172 | 173 | public static String htmlText(String htmlContnet, String htmlCss) { 174 | if (TextUtils.isEmpty(htmlContnet)) { 175 | return ""; 176 | } 177 | String html = "\n" + 178 | "\n " + 179 | "\n" + 180 | "\n" + 181 | "" + 182 | "" + 183 | "\n" + 215 | "\n" + 216 | "\n" + 217 | "" + htmlContnet + "\n" + 218 | "\n" + 219 | ""; 220 | return html; 221 | } 222 | } 223 | -------------------------------------------------------------------------------- /app/src/main/java/com/kongzue/enjoylife/activity/GalleryActivity.java: -------------------------------------------------------------------------------- 1 | package com.kongzue.enjoylife.activity; 2 | 3 | import android.Manifest; 4 | import android.annotation.SuppressLint; 5 | import android.app.Dialog; 6 | import android.app.WallpaperManager; 7 | import android.content.DialogInterface; 8 | import android.content.Intent; 9 | import android.graphics.Bitmap; 10 | import android.graphics.BitmapFactory; 11 | import android.graphics.Color; 12 | import android.net.Uri; 13 | import android.os.Build; 14 | import android.os.Environment; 15 | import android.os.Message; 16 | import android.support.v4.content.FileProvider; 17 | import android.support.v4.view.ViewCompat; 18 | import android.support.v4.view.ViewPager; 19 | import android.support.v7.app.AlertDialog; 20 | import android.support.v7.app.AppCompatActivity; 21 | import android.os.Bundle; 22 | import android.view.View; 23 | import android.view.ViewGroup; 24 | import android.widget.ImageView; 25 | import android.widget.LinearLayout; 26 | import android.widget.RelativeLayout; 27 | import android.widget.TextView; 28 | 29 | import com.kongzue.baseframework.BaseActivity; 30 | import com.kongzue.baseframework.interfaces.Layout; 31 | import com.kongzue.baseframework.util.OnPermissionResponseListener; 32 | import com.kongzue.dialog.listener.DialogLifeCycleListener; 33 | import com.kongzue.dialog.listener.OnMenuItemClickListener; 34 | import com.kongzue.dialog.util.BlurView; 35 | import com.kongzue.dialog.v2.BottomMenu; 36 | import com.kongzue.dialog.v2.DialogSettings; 37 | import com.kongzue.dialog.v2.TipDialog; 38 | import com.kongzue.dialog.v2.WaitDialog; 39 | import com.kongzue.enjoylife.BuildConfig; 40 | import com.kongzue.enjoylife.R; 41 | import com.kongzue.enjoylife.adapter.PhotoListAdapter; 42 | import com.kongzue.enjoylife.adapter.PhotoViewPagerAdapter; 43 | 44 | import java.io.File; 45 | import java.io.FileNotFoundException; 46 | import java.io.FileOutputStream; 47 | import java.io.IOException; 48 | import java.util.ArrayList; 49 | import java.util.List; 50 | 51 | import okhttp3.Call; 52 | import okhttp3.Callback; 53 | import okhttp3.OkHttpClient; 54 | import okhttp3.Request; 55 | import okhttp3.Response; 56 | 57 | @Layout(R.layout.activity_gallery) 58 | public class GalleryActivity extends BaseActivity { 59 | 60 | private ViewPager photoViewpager; 61 | private TextView tvIndicator; 62 | private RelativeLayout boxTable; 63 | private BlurView blur; 64 | private LinearLayout boxTableChild; 65 | private LinearLayout btnBack; 66 | private ImageView btnShare; 67 | 68 | @Override 69 | public void initViews() { 70 | photoViewpager = findViewById(R.id.photo_viewpager); 71 | tvIndicator = findViewById(R.id.tv_indicator); 72 | boxTable = findViewById(R.id.box_table); 73 | blur = findViewById(R.id.blur); 74 | boxTableChild = findViewById(R.id.box_table_child); 75 | btnBack = findViewById(R.id.btn_back); 76 | btnShare = findViewById(R.id.btn_share); 77 | } 78 | 79 | private PhotoListAdapter.GalleryBean galleryBean; 80 | private List photoBeanList; 81 | private String now_image_url; 82 | private String now_image_id; 83 | public static final String TRANSIT_PIC = "transit_img"; 84 | 85 | @Override 86 | public void initDatas() { 87 | 88 | galleryBean = (PhotoListAdapter.GalleryBean) getParameter().get("GalleryBean"); 89 | if (galleryBean == null) { 90 | finish(); 91 | return; 92 | } 93 | if (galleryBean.getImages() == null || galleryBean.getImages().isEmpty()) { 94 | TipDialog.show(me, "出错啦", TipDialog.SHOW_TIME_SHORT, TipDialog.TYPE_ERROR).setDialogLifeCycleListener(new DialogLifeCycleListener() { 95 | @Override 96 | public void onCreate(Dialog alertDialog) { 97 | 98 | } 99 | 100 | @Override 101 | public void onShow(Dialog alertDialog) { 102 | 103 | } 104 | 105 | @Override 106 | public void onDismiss() { 107 | finish(); 108 | } 109 | }); 110 | return; 111 | } 112 | photoBeanList = galleryBean.getImages(); 113 | 114 | blur.setOverlayColor(Color.argb(200, 20, 20, 20)); 115 | blur.setRadius(me, 0, 0); 116 | boxTable.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dip2px(me, 50) + getStatusBarHeight())); 117 | 118 | photoViewpager.setPageMargin((int) (getResources().getDisplayMetrics().density * 15)); 119 | photoViewpager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { 120 | @Override 121 | public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 122 | now_image_url = photoBeanList.get(photoViewpager.getCurrentItem()).getUrl(); 123 | now_image_id = photoBeanList.get(photoViewpager.getCurrentItem()).getImg_id() + ""; 124 | tvIndicator.setText(String.valueOf((photoViewpager.getCurrentItem() + 1) + "/" + photoBeanList.size())); 125 | } 126 | }); 127 | ViewCompat.setTransitionName(photoViewpager, TRANSIT_PIC); 128 | tvIndicator.setText(0 + "/" + photoBeanList.size()); 129 | 130 | //加载 131 | PhotoViewPagerAdapter adapter = new PhotoViewPagerAdapter(this, photoBeanList); 132 | photoViewpager.setAdapter(adapter); 133 | photoViewpager.setCurrentItem(0); 134 | } 135 | 136 | public int jobType = 0; 137 | 138 | @Override 139 | public void setEvents() { 140 | btnBack.setOnClickListener(new View.OnClickListener() { 141 | @Override 142 | public void onClick(View v) { 143 | onBackPressed(); 144 | } 145 | }); 146 | 147 | btnShare.setOnClickListener(new View.OnClickListener() { 148 | @Override 149 | public void onClick(View v) { 150 | List listMenu = new ArrayList<>(); 151 | listMenu.add("下载此照片"); 152 | listMenu.add("分享此照片"); 153 | listMenu.add("设置为壁纸"); 154 | BottomMenu.show(me, listMenu, new OnMenuItemClickListener() { 155 | @Override 156 | public void onClick(String text, int index) { 157 | jobType = index; 158 | saveImage(); 159 | } 160 | }); 161 | } 162 | }); 163 | } 164 | 165 | private void saveImage() { 166 | requestPermission(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, new OnPermissionResponseListener() { 167 | @Override 168 | public void onSuccess(String[] permissions) { 169 | downloadImage(); 170 | } 171 | 172 | @Override 173 | public void onFail() { 174 | TipDialog.show(me, "没有存储权限", TipDialog.SHOW_TIME_SHORT, TipDialog.TYPE_ERROR); 175 | } 176 | }); 177 | } 178 | 179 | private Bitmap bitmap_cache; 180 | 181 | public void downloadImage() { 182 | File f = new File("/sdcard/" + now_image_id + ".png"); 183 | if (f.exists()) { 184 | doJob(); 185 | return; 186 | } 187 | WaitDialog.show(me, "请稍候..."); 188 | OkHttpClient client = new OkHttpClient(); 189 | final Request request = new Request.Builder().get() 190 | .url(now_image_url) 191 | .build(); 192 | 193 | client.newCall(request).enqueue(new Callback() { 194 | @Override 195 | public void onFailure(Call call, IOException e) { 196 | e.printStackTrace(); 197 | runOnUiThread(new Runnable() { 198 | @Override 199 | public void run() { 200 | WaitDialog.dismiss(); 201 | if (jobType == 0) 202 | TipDialog.show(me, "保存失败", TipDialog.SHOW_TIME_SHORT, TipDialog.TYPE_ERROR); 203 | } 204 | }); 205 | } 206 | 207 | @Override 208 | public void onResponse(Call call, final Response response) throws IOException { 209 | if (response.isSuccessful()) { 210 | final byte[] bytes = response.body().bytes(); 211 | runOnUiThread(new Runnable() { 212 | @Override 213 | public void run() { 214 | WaitDialog.dismiss(); 215 | bitmap_cache = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); 216 | saveImageByBitmap(bitmap_cache); 217 | if (jobType == 0) 218 | TipDialog.show(me, "图片已保存", TipDialog.SHOW_TIME_SHORT, TipDialog.TYPE_FINISH); 219 | } 220 | }); 221 | } else { 222 | runOnUiThread(new Runnable() { 223 | @Override 224 | public void run() { 225 | WaitDialog.dismiss(); 226 | if (jobType == 0) 227 | TipDialog.show(me, "保存失败", TipDialog.SHOW_TIME_SHORT, TipDialog.TYPE_ERROR); 228 | } 229 | }); 230 | } 231 | } 232 | }); 233 | } 234 | 235 | public void saveImageByBitmap(Bitmap bitmap) { 236 | File f = new File("/sdcard/" + now_image_id + ".png"); 237 | log("存储 -> " + f.getPath()); 238 | try { 239 | f.createNewFile(); 240 | } catch (IOException e) { 241 | if (jobType == 0) 242 | TipDialog.show(me, "保存失败", TipDialog.SHOW_TIME_SHORT, TipDialog.TYPE_ERROR); 243 | } 244 | FileOutputStream fOut = null; 245 | try { 246 | fOut = new FileOutputStream(f); 247 | bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut); 248 | fOut.flush(); 249 | fOut.close(); 250 | } catch (Exception e) { 251 | e.printStackTrace(); 252 | if (jobType == 0) 253 | TipDialog.show(me, "保存失败", TipDialog.SHOW_TIME_SHORT, TipDialog.TYPE_ERROR); 254 | } 255 | 256 | doJob(); 257 | } 258 | 259 | public void shareMsg(String activityTitle, String msgTitle, String msgText, String imgPath) { 260 | Intent intent = new Intent(Intent.ACTION_SEND); 261 | if (imgPath == null || imgPath.equals("")) { 262 | intent.setType("text/plain"); // 纯文本 263 | } else { 264 | File f = new File(imgPath); 265 | if (f != null && f.exists() && f.isFile()) { 266 | intent.setType("image/jpg"); 267 | Uri u = Uri.fromFile(f); 268 | intent.putExtra(Intent.EXTRA_STREAM, u); 269 | } 270 | } 271 | intent.putExtra(Intent.EXTRA_SUBJECT, msgTitle); 272 | intent.putExtra(Intent.EXTRA_TEXT, msgText); 273 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 274 | 275 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 276 | intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 277 | Uri contentUri = FileProvider.getUriForFile(me, BuildConfig.APPLICATION_ID + ".fileProvider", new File(imgPath)); 278 | intent.setDataAndType(contentUri, "image/jpg"); 279 | } 280 | startActivity(Intent.createChooser(intent, activityTitle)); 281 | } 282 | 283 | private void doJob() { 284 | switch (jobType) { 285 | case 0: 286 | TipDialog.show(me, "图片已保存", TipDialog.SHOW_TIME_SHORT, TipDialog.TYPE_FINISH); 287 | break; 288 | case 1: 289 | shareMsg("分享图片","来自" + getResources().getString(R.string.app_name) + "的分享","此照片来源图虫摄影社区,原作者保留所有版权。","/sdcard/" + now_image_id + ".png"); 290 | break; 291 | case 2: 292 | WallpaperManager manager = WallpaperManager.getInstance(me); 293 | try { 294 | manager.setBitmap(bitmap_cache); 295 | TipDialog.show(me, "已设为壁纸", TipDialog.SHOW_TIME_SHORT, TipDialog.TYPE_FINISH); 296 | } catch (IOException e) { 297 | e.printStackTrace(); 298 | TipDialog.show(me, "设置失败", TipDialog.SHOW_TIME_SHORT, TipDialog.TYPE_ERROR); 299 | } 300 | break; 301 | } 302 | } 303 | } 304 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_about.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 13 | 14 | 21 | 22 | 27 | 28 | 36 | 37 | 45 | 46 | 54 | 55 | 63 | 64 | 73 | 74 | 82 | 83 | 92 | 93 | 101 | 102 | 110 | 111 | 119 | 120 | 129 | 130 | 138 | 139 | 148 | 149 | 157 | 158 | 167 | 168 | 176 | 177 | 186 | 187 | 195 | 196 | 205 | 206 | 214 | 215 | 224 | 225 | 233 | 234 | 243 | 244 | 252 | 253 | 262 | 263 | 271 | 272 | 281 | 282 | 290 | 291 | 300 | 301 | 302 | 303 | 304 | 305 | 310 | 311 | 315 | 316 | 319 | 320 | 329 | 330 | 336 | 337 | 342 | 343 | 351 | 352 | 353 | 354 | 358 | 359 | 365 | 366 | 367 | 368 | 373 | 374 | 384 | 385 | 386 | 387 | 388 | 389 | --------------------------------------------------------------------------------