├── .gitignore ├── .idea ├── compiler.xml ├── copyright │ └── CoorChiceCopyright.xml ├── dictionaries │ └── chenbing.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── README.md ├── _config.yml ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── coorchice │ │ └── ban │ │ ├── BanApplication.kt │ │ ├── model │ │ ├── MainActivity.kt │ │ ├── base │ │ │ ├── AppFragmentPagerAdapter │ │ │ │ ├── FragmentCompat.java │ │ │ │ ├── FragmentCompat23.java │ │ │ │ ├── FragmentCompatApi24.java │ │ │ │ ├── FragmentCompatICS.java │ │ │ │ ├── FragmentCompatICSMR1.java │ │ │ │ └── FragmentPagerAdapter.java │ │ │ ├── BaseActivity.kt │ │ │ ├── BaseFragment.kt │ │ │ ├── BaseRecyclerViewHolder.kt │ │ │ ├── ModelAbstract.kt │ │ │ ├── Navigator.kt │ │ │ ├── OnItemViewClickListener.kt │ │ │ ├── OnResponseListener.kt │ │ │ └── ViewAbstract.kt │ │ ├── constellation │ │ │ ├── entry │ │ │ │ ├── Constellation.kt │ │ │ │ └── ConstellationDataType.kt │ │ │ ├── model │ │ │ │ └── ConstellationModel.kt │ │ │ ├── presenter │ │ │ │ └── ConstellationFragmentPresenter.kt │ │ │ └── view │ │ │ │ └── fragment │ │ │ │ ├── ConstellationDetailFragment.kt │ │ │ │ └── ConstellationFragment.kt │ │ ├── joke │ │ │ ├── adapter │ │ │ │ ├── JokePictureListAdapter.kt │ │ │ │ ├── JokeWordListAdapter.kt │ │ │ │ └── itemview │ │ │ │ │ ├── JokePictureListItemView.kt │ │ │ │ │ ├── JokeWordListLeftItemView.kt │ │ │ │ │ └── JokeWordListRightItemView.kt │ │ │ ├── model │ │ │ │ └── JokeModel.kt │ │ │ ├── presenter │ │ │ │ └── JokeFragmentPresenter.kt │ │ │ └── view │ │ │ │ └── fragment │ │ │ │ ├── JokeFragment.kt │ │ │ │ ├── JokePictureFragment.kt │ │ │ │ └── JokeWordFragment.kt │ │ ├── news │ │ │ ├── adapter │ │ │ │ ├── ItemView │ │ │ │ │ ├── NewsListMorePicItemView.kt │ │ │ │ │ ├── NewsListSinglePicItemView.kt │ │ │ │ │ └── NewsNavigatorListItemView.kt │ │ │ │ ├── NewsListAdapter.kt │ │ │ │ └── NewsNavigatorListAdapter.kt │ │ │ ├── entry │ │ │ │ └── NewsNavigation.kt │ │ │ ├── model │ │ │ │ └── NewsModel.kt │ │ │ ├── presenter │ │ │ │ └── NewsListFragmentPresenter.kt │ │ │ └── view │ │ │ │ └── fragment │ │ │ │ ├── NewsFragment.kt │ │ │ │ └── NewsListFragment.kt │ │ ├── web │ │ │ └── activity │ │ │ │ └── WebActivity.kt │ │ ├── wechat │ │ │ ├── adapter │ │ │ │ ├── WechatNewsListAdapter.kt │ │ │ │ └── itemview │ │ │ │ │ └── WechatNewsListItemView.kt │ │ │ ├── model │ │ │ │ └── WechatNewsModel.kt │ │ │ ├── presenter │ │ │ │ └── WechatNewsFragmentPresenter.kt │ │ │ └── view │ │ │ │ └── fragment │ │ │ │ └── WechatNewsFragment.kt │ │ └── welcome │ │ │ └── view │ │ │ └── WelcomeActivity.kt │ │ ├── network │ │ ├── ApiAvatardata.kt │ │ ├── ApiJuhe.java │ │ ├── BaseResponse.kt │ │ ├── DataModel │ │ │ ├── ConstellationDataModel.kt │ │ │ ├── JokeWordDataModel.kt │ │ │ ├── NewsDataModel.kt │ │ │ └── WechatNewsDataModel.kt │ │ ├── Net.kt │ │ └── ResponseCallback.kt │ │ └── utils │ │ ├── Animation.kt │ │ ├── AppUtils.kt │ │ ├── CrashHandler.kt │ │ ├── DateUtils.kt │ │ ├── FileUtil.kt │ │ ├── LogUtil.kt │ │ ├── NetworkUtil.kt │ │ ├── SpCacher.kt │ │ └── ViewExtension.kt │ └── res │ ├── drawable-hdpi │ └── app_icon.png │ ├── drawable-xhdpi │ ├── app_icon.png │ └── coorchice.png │ ├── drawable-xxhdpi │ └── app_icon.png │ ├── drawable-xxxhdpi │ └── app_icon.png │ ├── drawable │ ├── aquarius.png │ ├── aquarius_bg.jpg │ ├── aries.png │ ├── aries_bg.jpg │ ├── back.png │ ├── cancer.png │ ├── cancer_bg.jpg │ ├── capricorn.png │ ├── capricorn_bg.jpg │ ├── color_12.png │ ├── constellation.png │ ├── constellation_bg.jpg │ ├── constellation_select.png │ ├── curiosity.png │ ├── dream.png │ ├── dream_select.png │ ├── entertainment.png │ ├── gemini.png │ ├── gemini_bg.jpg │ ├── inland.png │ ├── international.png │ ├── joke.png │ ├── joke_select.png │ ├── libra.png │ ├── libra_bg.jpg │ ├── like0.png │ ├── like1.png │ ├── lion.png │ ├── lion_bg.jpg │ ├── news.png │ ├── news_select.png │ ├── no_data.png │ ├── pe.png │ ├── pisces.png │ ├── pisces_bg.jpg │ ├── progress_bar_all.xml │ ├── progress_bar_health.xml │ ├── progress_bar_love.xml │ ├── progress_bar_money.xml │ ├── progress_bar_work.xml │ ├── sagittarius.png │ ├── sagittarius_bg.jpg │ ├── scorpio.png │ ├── scorpio_bg.jpg │ ├── select_constellation.png │ ├── taurus.png │ ├── taurus_bg.jpg │ ├── technology.png │ ├── test.jpg │ ├── virgo.png │ ├── virgo_bg.jpg │ ├── wechat.png │ ├── wechat_left.9.png │ ├── wechat_right.9.png │ ├── wechat_select.png │ └── welcome.jpg │ ├── layout │ ├── activity_main.xml │ ├── activity_web.xml │ ├── activity_welcome.xml │ ├── fragment_base.xml │ ├── fragment_constellation.xml │ ├── fragment_constellation_detail_today.xml │ ├── fragment_joke.xml │ ├── fragment_joke_picture.xml │ ├── fragment_joke_word.xml │ ├── fragment_news.xml │ ├── fragment_news_list.xml │ ├── fragment_wechat_news.xml │ ├── item_view_joke_picture_list.xml │ ├── item_view_joke_word_list_left.xml │ ├── item_view_joke_word_list_right.xml │ ├── item_view_news_list_more_pic.xml │ ├── item_view_news_list_single_pic.xml │ ├── item_view_news_navigator_list.xml │ ├── item_view_wechat_news_list.xml │ ├── layout_empty.xml │ ├── layout_header_bar.xml │ ├── layout_select_constellation.xml │ ├── layout_week_constellation.xml │ └── line_0_3_grey_50.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── index.html └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /.idea/copyright/CoorChiceCopyright.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/dictionaries/chenbing.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ![image](http://ogemdlrap.bkt.clouddn.com/ban_cover.png) 3 | 4 | > ## 这城市太寂寞,《伴》在你身边 5 | 6 | # 《伴》之序 7 | **《伴》** 是一款完全的Kotlin项目,她展示了部分**Kotlin** 的知识。诸如类、函数、变量、流程控制语句等基础知识点,以及单例、伴生、数据类、延迟注入、转型、扩展方法、扩展属性等进阶知识点。随着项目的发展,CoorChice期待加入更多有趣实用的特性进去。 8 | 9 | 在 **《伴》** 中,CoorChice向你展示了如何使用Kotlin快速的构建一个App,以及如何轻松愉悦的、持续的进行迭代。如果你忍受够了Java各种冗余的、反人类的语法,如果你被Java圈住太久,想要尝尝自由的味道,那么你可以在 **《伴》** 中看到Kotlin是如何来解放一个程序员的。 10 | 11 | CoorChice在这里准备一些Kotlin的入门知识,顺利的话你将能很快的上手Kotlin。[秘术Kotlin【http://www.jianshu.com/nb/12698208】](http://www.jianshu.com/nb/12698208)。如果你想了解更多的进阶知识,可以在网上找到很多不错的资料。 12 | 13 | 下面,CoorChice将会简单的介绍一下《伴》。如果你希望获得更多的信息和讨论,可以进入我的主页关注我。 14 | 15 | # 《伴》之形 16 | 《伴》使用了纯Kotlin进行开发,总体架构选用了时下流行的、稳定的MVP架构。关于MVP已经有很多资料在网络中流传了,建议大家可以先查找相关资料熟悉一下。什么?怎么查找?这会是对你有用的一篇文章:[这十个搜索技巧至少价值100万!【http://www.jianshu.com/p/a2f0f5a39cc3】](http://www.jianshu.com/p/a2f0f5a39cc3)。 17 | ## 使用到的库 18 | 下面是一些《伴》中用到的流行库: 19 | - **Gson**,解析Json数据。 20 | - **OkHttp3 + Retrofit2**,处理网络请求。 21 | - **Fresco**,展示图片。 22 | - **SuperTextView**,这是**CoorChice**喜爱的控件,他真是可以无处不在啊!如果你感兴趣的话,这是地址[从未如此惊艳!你好,SuperTextView (v1.3)【http://www.jianshu.com/p/1b91e11e441d】](http://www.jianshu.com/p/1b91e11e441d)。 23 | 24 | CoorChice想说的是,Kotlin完全可以兼容现有的流行库。你还在为Kotlin的生态不够全面而害怕尝试吗?Java能用的,Kotlin也能有办法使用。 25 | 26 | ## 听说Kotlin和Anko更配哦 27 | 28 | 《伴》还使用Kotlin的专属扩展库**Anko**。 29 | 30 | Anko是Kotlin的一个扩展库,它包含了很多使用的工具和强大的特性。比如用DSL语言来在代码中创建布局,虽然CoorChice对它没什么好感,但它确实是一个有意思的东西。比起在xml中写布局,这个在代码中写布局的特性实在差太多了。 31 | 32 | 但是,Anko有一个十分让人爱不释手的特性,就是布局id就可以直接操作控件实例。强烈建议大家尝试一下,真的是爱不释手。`findViewById()`,`ButterKnife`等等你都可以停止了。 33 | ``` 34 | fragment_joke.xml 35 | 36 | 37 | 53 | ``` 54 | 通过import在Activity或Fragment中导入布局文件: 55 | ``` 56 | import kotlinx.android.synthetic.main.fragment_joke.* 57 | 58 | ``` 59 | 就是【`kotlinx.android.synthetic.main` + 布局文件 + *】的格式。 60 | 61 | 然后,你可以这样来使用: 62 | 63 | ``` 64 | btn_picture.solid = *** 65 | ``` 66 | 看到没,不用**findViewById()**,不用**ButterKnife** 。真是太棒了! 67 | 68 | 当然,Anko还有许多有趣的特性,比如可以通过这个函数`dip()`,来快速的将dp转为px,你都不用自己去封装。相关资料可以到这里查看:[Kotlin/anko【https://github.com/Kotlin/anko#which-anko-libraries-are-available-and-1which-do-i-need】](https://github.com/Kotlin/anko#which-anko-libraries-are-available-and-1which-do-i-need)。 69 | 70 | # 遇见《伴》 71 | 目前,**《伴》** 共有4个模块:新闻头条,微信精选,轻松一刻,星座运势。她们被打造来陪伴寂寞的你(如果你寂寞的话)。下面CoorChice展示一下《伴》的大致面貌吧。 72 | 73 | ## 新闻头条 74 | 将世界收入你的口袋中!足不出户而知天下事,大概说的就是这样吧。 75 | 76 | ![0](http://ogemdlrap.bkt.clouddn.com/%E4%BC%B4-00.gif) 77 | 78 | 79 | 80 | ## 微信精选 81 | 每日微信精选文章让你看到微信中不一样的世界。 82 | 83 | ![1](http://ogemdlrap.bkt.clouddn.com/%E4%BC%B4-1.gif) 84 | 85 | ## 轻松一刻 86 | 随身的图文笑话,让你走到哪都是最有幽默感的那一个。 87 | 88 | ![image](http://ogemdlrap.bkt.clouddn.com/%E4%BC%B4-2.gif) 89 | 90 | ## 星座运势 91 | 让你每天都可以了解自己的星座动态。 92 | 93 | ![image](http://ogemdlrap.bkt.clouddn.com/%E4%BC%B4-3.gif) 94 | 95 | # 总结 96 | > - 抽出空余时间写文章分享需要动力,还请各位看官动动小手 **【点个赞】**,给CoorChice点鼓励 97 | > - CoorChice一直在不定期的创作新的干货,想要上车只需进到【个人主页】点个关注就好了哦。发车喽~ 98 | 99 | 本篇CoorChice分享了自己的Kotlin项目《伴》,如果你现在任然感谢兴趣的话,下面是项目的地址: 100 | 101 | > [《伴》【https://github.com/chenBingX/Ban】](https://github.com/chenBingX/Ban) 102 | 103 | 或者,你可以在这个地址下载解压安装体验《伴》。 104 | > [《伴》http://ogemdlrap.bkt.clouddn.com/app-debug.apk.zip](http://ogemdlrap.bkt.clouddn.com/app-debug.apk.zip) 105 | 106 | ## 喜欢的话,记得顺手给个star,点个赞,鼓励下CoorChice哦! 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'kotlin-android-extensions' 3 | apply plugin: 'kotlin-android' 4 | 5 | 6 | 7 | android { 8 | compileSdkVersion 25 9 | buildToolsVersion "25.0.2" 10 | defaultConfig { 11 | applicationId "com.coorchice.ban" 12 | minSdkVersion 17 13 | targetSdkVersion 25 14 | versionCode 1 15 | versionName "1.0" 16 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 17 | } 18 | buildTypes { 19 | release { 20 | minifyEnabled false 21 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 22 | } 23 | } 24 | productFlavors { 25 | } 26 | } 27 | 28 | 29 | 30 | 31 | dependencies { 32 | compile fileTree(include: ['*.jar'], dir: 'libs') 33 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 34 | exclude group: 'com.android.support', module: 'support-annotations' 35 | }) 36 | compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" 37 | compile 'com.android.support:appcompat-v7:25.3.1' 38 | compile 'com.android.support.constraint:constraint-layout:1.0.2' 39 | compile 'com.google.code.gson:gson:2.8.1' 40 | compile 'com.squareup.retrofit2:retrofit:2.3.0' 41 | compile 'com.squareup.retrofit2:adapter-rxjava:2.3.0' 42 | compile 'com.squareup.retrofit2:converter-gson:2.3.0' 43 | compile 'com.github.chenBingX:SuperTextView:v1.3' 44 | compile 'com.github.nuptboyzhb.lib.uikit:superswiperefreshlayout:1.0.0' 45 | // anko 46 | def anko_version = "0.10.1" 47 | compile "org.jetbrains.anko:anko-commons:$anko_version" 48 | compile "org.jetbrains.anko:anko-sdk25:$anko_version" 49 | compile "org.jetbrains.anko:anko-appcompat-v7:$anko_version" 50 | compile "org.jetbrains.anko:anko-design:$anko_version" 51 | compile "org.jetbrains.anko:anko-recyclerview-v7:$anko_version" 52 | compile "org.jetbrains.anko:anko-cardview-v7:$anko_version" 53 | compile 'com.android.support:recyclerview-v7:25.3.1' 54 | compile 'com.android.support:cardview-v7:25.3.1' 55 | compile 'com.facebook.fresco:fresco:1.3.0' 56 | compile 'com.android.support:design:25.3.1' 57 | implementation 'com.android.support.constraint:constraint-layout:1.0.2' 58 | } 59 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/chenbing/Downloads/android_sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 26 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/BanApplication.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban 2 | 3 | import android.app.Application 4 | import android.content.Context 5 | import com.chenbing.oneweather.Utils.CrashHandler 6 | import com.facebook.drawee.backends.pipeline.Fresco 7 | 8 | /** 9 | * Project Name:Ban 10 | * Author:CoorChice 11 | * Date:2017/6/10 12 | * Notes: 13 | */ 14 | class BanApplication : Application() { 15 | override fun onCreate() { 16 | super.onCreate() 17 | appContext = this 18 | CrashHandler.instance.init(appContext as BanApplication) 19 | Fresco.initialize(this) 20 | 21 | 22 | } 23 | 24 | companion object { 25 | var appContext: Context? = null 26 | } 27 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/base/AppFragmentPagerAdapter/FragmentCompat.java: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.base.AppFragmentPagerAdapter; 2 | 3 | import java.util.Arrays; 4 | 5 | import android.app.Fragment; 6 | import android.content.Context; 7 | import android.content.pm.PackageManager; 8 | import android.os.Build; 9 | import android.os.Handler; 10 | import android.os.Looper; 11 | import android.support.annotation.NonNull; 12 | import android.support.v4.os.BuildCompat; 13 | 14 | /** 15 | * Project Name:kratos 16 | * Author:Chice 17 | * Date:2016/12/19 18 | * Notes: 19 | */ 20 | 21 | public class FragmentCompat { 22 | interface FragmentCompatImpl { 23 | void setMenuVisibility(Fragment f, boolean visible); 24 | void setUserVisibleHint(Fragment f, boolean deferStart); 25 | void requestPermissions(Fragment fragment, String[] permissions, int requestCode); 26 | boolean shouldShowRequestPermissionRationale(Fragment fragment, String permission); 27 | } 28 | 29 | static class BaseFragmentCompatImpl implements FragmentCompatImpl { 30 | @Override 31 | public void setMenuVisibility(Fragment f, boolean visible) { 32 | } 33 | @Override 34 | public void setUserVisibleHint(Fragment f, boolean deferStart) { 35 | } 36 | @Override 37 | public void requestPermissions(final Fragment fragment, final String[] permissions, 38 | final int requestCode) { 39 | Handler handler = new Handler(Looper.getMainLooper()); 40 | handler.post(new Runnable() { 41 | @Override 42 | public void run() { 43 | final int[] grantResults = new int[permissions.length]; 44 | 45 | Context context = fragment.getActivity(); 46 | if (context != null) { 47 | PackageManager packageManager = context.getPackageManager(); 48 | String packageName = context.getPackageName(); 49 | 50 | final int permissionCount = permissions.length; 51 | for (int i = 0; i < permissionCount; i++) { 52 | grantResults[i] = packageManager.checkPermission( 53 | permissions[i], packageName); 54 | } 55 | } else { 56 | Arrays.fill(grantResults, PackageManager.PERMISSION_DENIED); 57 | } 58 | 59 | ((FragmentCompat.OnRequestPermissionsResultCallback) fragment).onRequestPermissionsResult( 60 | requestCode, permissions, grantResults); 61 | } 62 | }); 63 | } 64 | @Override 65 | public boolean shouldShowRequestPermissionRationale(Fragment fragment, String permission) { 66 | return false; 67 | } 68 | } 69 | 70 | static class ICSFragmentCompatImpl extends BaseFragmentCompatImpl { 71 | @Override 72 | public void setMenuVisibility(Fragment f, boolean visible) { 73 | FragmentCompatICS.setMenuVisibility(f, visible); 74 | } 75 | } 76 | 77 | static class ICSMR1FragmentCompatImpl extends ICSFragmentCompatImpl { 78 | @Override 79 | public void setUserVisibleHint(Fragment f, boolean deferStart) { 80 | FragmentCompatICSMR1.setUserVisibleHint(f, deferStart); 81 | } 82 | } 83 | 84 | static class MncFragmentCompatImpl extends ICSMR1FragmentCompatImpl { 85 | @Override 86 | public void requestPermissions(Fragment fragment, String[] permissions, int requestCode) { 87 | FragmentCompat23.requestPermissions(fragment, permissions, requestCode); 88 | } 89 | 90 | @Override 91 | public boolean shouldShowRequestPermissionRationale(Fragment fragment, String permission) { 92 | return FragmentCompat23.shouldShowRequestPermissionRationale(fragment, permission); 93 | } 94 | } 95 | 96 | static class NFragmentCompatImpl extends MncFragmentCompatImpl { 97 | @Override 98 | public void setUserVisibleHint(Fragment f, boolean deferStart) { 99 | FragmentCompatApi24.setUserVisibleHint(f, deferStart); 100 | } 101 | } 102 | 103 | static final FragmentCompatImpl IMPL; 104 | static { 105 | if (BuildCompat.isAtLeastN()) { 106 | IMPL = new NFragmentCompatImpl(); 107 | } else if (Build.VERSION.SDK_INT >= 23) { 108 | IMPL = new MncFragmentCompatImpl(); 109 | } else if (android.os.Build.VERSION.SDK_INT >= 15) { 110 | IMPL = new ICSMR1FragmentCompatImpl(); 111 | } else if (android.os.Build.VERSION.SDK_INT >= 14) { 112 | IMPL = new ICSFragmentCompatImpl(); 113 | } else { 114 | IMPL = new BaseFragmentCompatImpl(); 115 | } 116 | } 117 | 118 | public interface OnRequestPermissionsResultCallback { 119 | public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, 120 | @NonNull int[] grantResults); 121 | } 122 | 123 | public static void setMenuVisibility(Fragment f, boolean visible) { 124 | IMPL.setMenuVisibility(f, visible); 125 | } 126 | 127 | public static void setUserVisibleHint(Fragment f, boolean deferStart) { 128 | IMPL.setUserVisibleHint(f, deferStart); 129 | } 130 | 131 | public static void requestPermissions(@NonNull Fragment fragment, 132 | @NonNull String[] permissions, int requestCode) { 133 | IMPL.requestPermissions(fragment, permissions, requestCode); 134 | } 135 | 136 | public static boolean shouldShowRequestPermissionRationale(@NonNull Fragment fragment, 137 | @NonNull String permission) { 138 | return IMPL.shouldShowRequestPermissionRationale(fragment, permission); 139 | } 140 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/base/AppFragmentPagerAdapter/FragmentCompat23.java: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.base.AppFragmentPagerAdapter; /** 2 | * Project Name:kratos 3 | * Author:Chice 4 | * Date:2016/12/19 5 | * Notes: 6 | */ 7 | 8 | import android.annotation.TargetApi; 9 | import android.app.Fragment; 10 | import android.support.annotation.RequiresApi; 11 | 12 | @RequiresApi(23) 13 | @TargetApi(23) 14 | class FragmentCompat23 { 15 | public static void requestPermissions(Fragment fragment, String[] permissions, 16 | int requestCode) { 17 | fragment.requestPermissions(permissions, requestCode); 18 | } 19 | 20 | public static boolean shouldShowRequestPermissionRationale(Fragment fragment, 21 | String permission) { 22 | return fragment.shouldShowRequestPermissionRationale(permission); 23 | } 24 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/base/AppFragmentPagerAdapter/FragmentCompatApi24.java: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.base.AppFragmentPagerAdapter; 2 | 3 | import android.annotation.TargetApi; 4 | import android.app.Fragment; 5 | import android.support.annotation.RequiresApi; 6 | 7 | /** 8 | * Project Name:kratos 9 | * Author:Chice 10 | * Date:2016/12/19 11 | * Notes: 12 | */ 13 | 14 | @RequiresApi(24) 15 | @TargetApi(24) 16 | class FragmentCompatApi24 { 17 | public static void setUserVisibleHint(Fragment f, boolean isVisible) { 18 | f.setUserVisibleHint(isVisible); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/base/AppFragmentPagerAdapter/FragmentCompatICS.java: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.base.AppFragmentPagerAdapter; 2 | 3 | /** 4 | * Project Name:kratos 5 | * Author:Chice 6 | * Date:2016/12/19 7 | * Notes: 8 | */ 9 | 10 | import android.annotation.TargetApi; 11 | import android.app.Fragment; 12 | import android.support.annotation.RequiresApi; 13 | 14 | @RequiresApi(14) 15 | @TargetApi(14) 16 | class FragmentCompatICS { 17 | public static void setMenuVisibility(Fragment f, boolean visible) { 18 | f.setMenuVisibility(visible); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/base/AppFragmentPagerAdapter/FragmentCompatICSMR1.java: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.base.AppFragmentPagerAdapter; 2 | 3 | /** 4 | * Project Name:kratos 5 | * Author:Chice 6 | * Date:2016/12/19 7 | * Notes: 8 | */ 9 | 10 | import android.annotation.TargetApi; 11 | import android.app.Fragment; 12 | import android.support.annotation.RequiresApi; 13 | 14 | @RequiresApi(15) 15 | @TargetApi(15) 16 | class FragmentCompatICSMR1 { 17 | public static void setUserVisibleHint(Fragment f, boolean isVisible) { 18 | if (f.getFragmentManager() != null) { 19 | f.setUserVisibleHint(isVisible); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/base/AppFragmentPagerAdapter/FragmentPagerAdapter.java: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.base.AppFragmentPagerAdapter; 2 | 3 | import android.app.Fragment; 4 | import android.app.FragmentManager; 5 | import android.app.FragmentTransaction; 6 | import android.os.Parcelable; 7 | import android.support.v4.view.PagerAdapter; 8 | import android.util.Log; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | 12 | /** 13 | * Project Name:kratos 14 | * Author:Chice 15 | * Date:2016/12/19 16 | * Notes: 17 | */ 18 | 19 | public abstract class FragmentPagerAdapter extends PagerAdapter { 20 | private static final String TAG = "FragmentPagerAdapter"; 21 | private static final boolean DEBUG = false; 22 | 23 | private final FragmentManager mFragmentManager; 24 | private FragmentTransaction mCurTransaction = null; 25 | private Fragment mCurrentPrimaryItem = null; 26 | 27 | public FragmentPagerAdapter(FragmentManager fm) { 28 | mFragmentManager = fm; 29 | } 30 | 31 | /** 32 | * Return the Fragment associated with a specified position. 33 | */ 34 | public abstract Fragment getItem(int position); 35 | 36 | @Override 37 | public void startUpdate(ViewGroup container) { 38 | if (container.getId() == View.NO_ID) { 39 | throw new IllegalStateException("ViewPager with adapter " + this 40 | + " requires a view id"); 41 | } 42 | } 43 | 44 | @Override 45 | public Object instantiateItem(ViewGroup container, int position) { 46 | if (mCurTransaction == null) { 47 | mCurTransaction = mFragmentManager.beginTransaction(); 48 | } 49 | 50 | final long itemId = getItemId(position); 51 | 52 | // Do we already have this fragment? 53 | String name = makeFragmentName(container.getId(), itemId); 54 | Fragment fragment = mFragmentManager.findFragmentByTag(name); 55 | if (fragment != null) { 56 | if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment); 57 | mCurTransaction.attach(fragment); 58 | } else { 59 | fragment = getItem(position); 60 | if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment); 61 | mCurTransaction.add(container.getId(), fragment, 62 | makeFragmentName(container.getId(), itemId)); 63 | } 64 | if (fragment != mCurrentPrimaryItem) { 65 | FragmentCompat.setMenuVisibility(fragment, false); 66 | FragmentCompat.setUserVisibleHint(fragment, false); 67 | } 68 | return fragment; 69 | } 70 | 71 | @Override 72 | public void destroyItem(ViewGroup container, int position, Object object) { 73 | if (mCurTransaction == null) { 74 | mCurTransaction = mFragmentManager.beginTransaction(); 75 | } 76 | if (DEBUG) Log.v(TAG, "Detaching item #" + getItemId(position) + ": f=" + object 77 | + " v=" + ((Fragment)object).getView()); 78 | mCurTransaction.detach((Fragment)object); 79 | } 80 | 81 | @Override 82 | public void setPrimaryItem(ViewGroup container, int position, Object object) { 83 | Fragment fragment = (Fragment)object; 84 | if (fragment != mCurrentPrimaryItem) { 85 | if (mCurrentPrimaryItem != null) { 86 | FragmentCompat.setMenuVisibility(mCurrentPrimaryItem, false); 87 | FragmentCompat.setUserVisibleHint(mCurrentPrimaryItem, false); 88 | } 89 | if (fragment != null) { 90 | FragmentCompat.setMenuVisibility(fragment, true); 91 | FragmentCompat.setUserVisibleHint(fragment, true); 92 | } 93 | mCurrentPrimaryItem = fragment; 94 | } 95 | } 96 | 97 | @Override 98 | public void finishUpdate(ViewGroup container) { 99 | if (mCurTransaction != null) { 100 | mCurTransaction.commitAllowingStateLoss(); 101 | mCurTransaction = null; 102 | mFragmentManager.executePendingTransactions(); 103 | } 104 | } 105 | 106 | @Override 107 | public boolean isViewFromObject(View view, Object object) { 108 | return ((Fragment)object).getView() == view; 109 | } 110 | 111 | @Override 112 | public Parcelable saveState() { 113 | return null; 114 | } 115 | 116 | @Override 117 | public void restoreState(Parcelable state, ClassLoader loader) { 118 | } 119 | 120 | public long getItemId(int position) { 121 | return position; 122 | } 123 | 124 | private static String makeFragmentName(int viewId, long id) { 125 | return "android:switcher:" + viewId + ":" + id; 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/base/BaseActivity.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.base 2 | 3 | import android.os.Bundle 4 | import android.support.v7.app.AppCompatActivity 5 | 6 | /** 7 | * Project Name:Ban 8 | * Author:CoorChice 9 | * Date:2017/6/10 10 | * Notes: 11 | */ 12 | abstract class BaseActivity : AppCompatActivity() { 13 | 14 | override fun onCreate(savedInstanceState: Bundle?) { 15 | super.onCreate(savedInstanceState) 16 | setContentView(getContentViewResId()) 17 | initData() 18 | initView() 19 | addListener() 20 | } 21 | 22 | abstract fun getContentViewResId(): Int 23 | 24 | abstract fun initData() 25 | 26 | abstract fun initView() 27 | 28 | abstract fun addListener() 29 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/base/BaseFragment.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.base 2 | 3 | import android.app.Fragment 4 | import android.os.Bundle 5 | import android.view.LayoutInflater 6 | import android.view.View 7 | import android.view.ViewGroup 8 | import com.coorchice.ban.R 9 | import kotlinx.android.synthetic.main.fragment_base.* 10 | 11 | /** 12 | * Project Name:Ban 13 | * Author:CoorChice 14 | * Date:2017/6/10 15 | * Notes: 16 | */ 17 | abstract class BaseFragment : Fragment() { 18 | 19 | var rootView: ViewGroup? = null 20 | override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View { 21 | rootView = inflater?.inflate(R.layout.fragment_base, container, false) as ViewGroup? 22 | rootView?.addView(inflater?.inflate(getContentViewResId(), null, false), 0) 23 | return rootView!! 24 | } 25 | 26 | override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { 27 | layout_empty.setOnClickListener({ 28 | reload() 29 | }) 30 | initData() 31 | initView() 32 | addListener() 33 | } 34 | 35 | abstract fun getContentViewResId(): Int 36 | 37 | abstract fun initData() 38 | 39 | abstract fun initView() 40 | 41 | abstract fun addListener() 42 | 43 | fun showEmpty(show: Boolean){ 44 | if (show) 45 | layout_empty.visibility = View.VISIBLE 46 | else 47 | layout_empty.visibility = View.GONE 48 | } 49 | 50 | fun reload(){ 51 | 52 | } 53 | 54 | 55 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/base/BaseRecyclerViewHolder.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.base 2 | 3 | import android.support.v7.widget.RecyclerView 4 | import android.view.View 5 | 6 | /** 7 | * Project Name:Ban 8 | * Author:CoorChice 9 | * Date:2017/6/10 10 | * Notes: 11 | */ 12 | class BaseRecyclerViewHolder(itemView: View?) : RecyclerView.ViewHolder(itemView) { 13 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/base/ModelAbstract.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.base 2 | 3 | import com.coorchice.ban.network.DataModel.* 4 | 5 | /** 6 | * Project Name:Ban 7 | * Author:CoorChice 8 | * Date:2017/6/11 9 | * Notes: 10 | */ 11 | interface INewsModel { 12 | fun requestNewsData(type: String, onResponseListener: OnResponseListener) 13 | } 14 | 15 | interface IWeChatNewsModel { 16 | fun requestWechatNewsData(pno:Int, ps:Int, onResponseListener: OnResponseListener) 17 | } 18 | 19 | interface IJokeModel { 20 | fun requestJokeWordData(page: Int, rows: Int, onResponseListener: OnResponseListener?>) 21 | 22 | fun requestJokePictureData(page: Int, rows: Int, onResponseListener: OnResponseListener?>) 23 | } 24 | 25 | interface IConstellationModel { 26 | fun requestConstellationInfo(consName: String, type: String, onResponseListener: OnResponseListener) 27 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/base/Navigator.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.base 2 | 3 | import android.content.Context 4 | import com.coorchice.ban.model.MainActivity 5 | import com.coorchice.ban.model.web.activity.WebActivity 6 | 7 | /** 8 | * Project Name:Ban 9 | * Author:CoorChice 10 | * Date:2017/6/12 11 | * Notes: 12 | */ 13 | 14 | fun toWebActivity(context: Context, url: String?, title: String?) { 15 | context.startActivity(WebActivity.getIntent(context, url, title)) 16 | } 17 | 18 | fun toMainActivity(context: Context) { 19 | context.startActivity(MainActivity.getIntent(context)) 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/base/OnItemViewClickListener.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.base 2 | 3 | /** 4 | * Project Name:Ban 5 | * Author:CoorChice 6 | * Date:2017/6/11 7 | * Notes: 8 | */ 9 | interface OnItemViewClickListener { 10 | fun OnItemViewClick(data: T, position: Int) 11 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/base/OnResponseListener.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.base 2 | 3 | /** 4 | * Project Name:Ban 5 | * Author:CoorChice 6 | * Date:2017/6/11 7 | * Notes: 8 | */ 9 | interface OnResponseListener { 10 | fun onSuccess(data: T?) 11 | fun onFailure(message: String?) 12 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/base/ViewAbstract.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.base 2 | 3 | import com.coorchice.ban.network.DataModel.ConstellationInfo 4 | import com.coorchice.ban.network.DataModel.News 5 | import com.coorchice.ban.network.DataModel.WechatNews 6 | 7 | /** 8 | * Project Name:Ban 9 | * Author:CoorChice 10 | * Date:2017/6/11 11 | * Notes: 12 | */ 13 | interface INewsListFragment { 14 | fun updateNewsData(data: List?) 15 | } 16 | 17 | interface IWechatNewsFragment { 18 | fun updateWechatNewsData(data: List?) 19 | 20 | fun onSpecialSituation(message: String?) 21 | } 22 | 23 | interface IJokeFragment { 24 | fun updateJokeData(data: List?) 25 | } 26 | 27 | interface IConstellationFragment{ 28 | fun updateConstellationData(data: ConstellationInfo?) 29 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/constellation/entry/Constellation.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.constellation.entry 2 | 3 | import android.graphics.Color 4 | import com.coorchice.ban.R 5 | 6 | /** 7 | * Project Name:Ban 8 | * Author:CoorChice 9 | * Date:2017/6/26 10 | * Notes: 11 | */ 12 | 13 | enum class Constellation(val type: String, val date: String, val color: Int, val icon: Int, val bg: Int) { 14 | /** 15 | * 16 | * 白羊座 (3/21 - 4/20) Aries 17 | 金牛座 (4/21 - 5/20) Taurus 18 | 双子座 (5/21 - 6/21) Gemini 19 | 巨蟹座 (6/22 - 7/22) Cancer 20 | 狮子座 (7/23 - 8/22) Leo 21 | 处女座 (8/23 - 9/22) Virgo 22 | 天秤座 (9/23 - 10/22) Libra 23 | 天蝎座 (10/23 - 11/21) Scorpio 24 | 射手座 (11/22 - 12/21) Sagittarius 25 | 魔羯座 (12/22 - 1/19) Capricorn 26 | 水瓶座 (1/20 - 2/18) Aquarius 27 | 双鱼座 (2/19 - 3/20) Pisces 28 | */ 29 | 30 | ARIES("白羊座", "3.21 - 4.20", Color.parseColor("#75AD15"), R.drawable.aries, R.drawable.aries_bg), 31 | TAURUS("金牛座", "4.21 - 5.20", Color.parseColor("#87622F"), R.drawable.taurus, R.drawable.taurus_bg), 32 | GEMINI("双子座", "5.21 - 6.21", Color.parseColor("#DD2210"), R.drawable.gemini, R.drawable.gemini_bg), 33 | CANCER("巨蟹座", "6.22 - 7.22", Color.parseColor("#F4C119"), R.drawable.cancer, R.drawable.cancer_bg), 34 | LEO("狮子座", "7.23 - 8.22", Color.parseColor("#622B19"), R.drawable.lion, R.drawable.lion_bg), 35 | VIRGO("处女座", "8.23 - 9.22", Color.parseColor("#945398"), R.drawable.virgo, R.drawable.virgo_bg), 36 | LIBRA("天秤座", "9.23 - 10.22", Color.parseColor("#2DAFA0"), R.drawable.libra, R.drawable.libra_bg), 37 | SCORPIO("天蝎座", "10.23 - 11.21", Color.parseColor("#525390"), R.drawable.scorpio, R.drawable.scorpio_bg), 38 | SAGITTARIUS("射手座", "11.22 - 12.21", Color.parseColor("#909090"), R.drawable.sagittarius, R.drawable.sagittarius_bg), 39 | CAPRICORN("魔羯座", "12.22 - 1.19", Color.parseColor("#31190D"), R.drawable.capricorn, R.drawable.capricorn_bg), 40 | AQUARIUS("水瓶座", "1.20 - 2.18", Color.parseColor("#2898DE"), R.drawable.aquarius, R.drawable.aquarius_bg), 41 | PISCES("双鱼座", "2.19 - 3.20", Color.parseColor("#D87B9A"), R.drawable.pisces, R.drawable.pisces_bg); 42 | 43 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/constellation/entry/ConstellationDataType.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.constellation.entry 2 | 3 | /** 4 | * Project Name:Ban 5 | * Author:CoorChice 6 | * Date:2017/6/26 7 | * Notes: 8 | */ 9 | enum class ConstellationDataType(val type: String, val title: String) { 10 | /** 11 | * today,tomorrow,week,nextweek,month,year 12 | */ 13 | TODAY("today", "今日运势"), 14 | TOMORROW("tomorrow", "明日运势"), 15 | WEEK("week", "本周运势"), 16 | NEXTWEEK("nextweek", "下周运势"), 17 | MONTH("month", "本月运势"), 18 | YEAR("year", "今年运势") 19 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/constellation/model/ConstellationModel.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.constellation.model 2 | 3 | import com.coorchice.ban.model.base.IConstellationModel 4 | import com.coorchice.ban.model.base.OnResponseListener 5 | import com.coorchice.ban.network.DataModel.ConstellationInfo 6 | import com.coorchice.ban.network.Net 7 | import com.coorchice.ban.network.OnFailureCallback 8 | import com.coorchice.ban.network.OnSuccessCallback 9 | 10 | /** 11 | * Project Name:Ban 12 | * Author:CoorChice 13 | * Date:2017/6/26 14 | * Notes: 15 | */ 16 | class ConstellationModel : IConstellationModel { 17 | 18 | override fun requestConstellationInfo(consName: String, type: String, onResponseListener: OnResponseListener) { 19 | Net.getConstellationInfo(consName, type, 20 | object : OnSuccessCallback { 21 | override fun onSuccess(data: ConstellationInfo?) { 22 | onResponseListener.onSuccess(data) 23 | } 24 | 25 | }, 26 | object : OnFailureCallback { 27 | override fun onFailure(message: String?) { 28 | onResponseListener.onFailure(message) 29 | } 30 | 31 | } 32 | ) 33 | } 34 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/constellation/presenter/ConstellationFragmentPresenter.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.constellation.presenter 2 | 3 | import com.coorchice.ban.model.base.IConstellationFragment 4 | import com.coorchice.ban.model.base.OnResponseListener 5 | import com.coorchice.ban.model.constellation.model.ConstellationModel 6 | import com.coorchice.ban.network.DataModel.ConstellationInfo 7 | import com.coorchice.ban.utils.loge 8 | 9 | /** 10 | * Project Name:Ban 11 | * Author:CoorChice 12 | * Date:2017/6/26 13 | * Notes: 14 | */ 15 | class ConstellationFragmentPresenter(var view: IConstellationFragment) { 16 | val model = ConstellationModel() 17 | 18 | fun requestConstellationData(consName: String, type: String){ 19 | model.requestConstellationInfo(consName, type, object: OnResponseListener{ 20 | 21 | override fun onSuccess(data: ConstellationInfo?) { 22 | view.updateConstellationData(data) 23 | } 24 | 25 | override fun onFailure(message: String?) { 26 | if (message != null) { 27 | loge(message) 28 | } 29 | } 30 | 31 | }) 32 | } 33 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/joke/adapter/JokePictureListAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.joke.adapter 2 | 3 | import android.content.Context 4 | import android.support.v7.widget.RecyclerView 5 | import android.view.ViewGroup 6 | import com.coorchice.ban.model.base.BaseRecyclerViewHolder 7 | import com.coorchice.ban.model.joke.adapter.itemview.JokePictureListItemView 8 | import com.coorchice.ban.network.DataModel.JokePicture 9 | 10 | /** 11 | * Project Name:Ban 12 | * Author:CoorChice 13 | * Date:2017/6/26 14 | * Notes: 15 | */ 16 | class JokePictureListAdapter(var context: Context, var data: List?) : RecyclerView.Adapter() { 17 | 18 | override fun getItemCount(): Int { 19 | return data?.size as Int 20 | 21 | } 22 | 23 | override fun onCreateViewHolder(p0: ViewGroup?, p1: Int): RecyclerView.ViewHolder { 24 | return BaseRecyclerViewHolder(JokePictureListItemView(context)) 25 | } 26 | 27 | override fun onBindViewHolder(p0: RecyclerView.ViewHolder?, p1: Int) { 28 | val itemView = p0?.itemView 29 | if (itemView is JokePictureListItemView) { 30 | itemView.setData(data?.get(p1), p1) 31 | } 32 | } 33 | 34 | fun updateData(data:List?){ 35 | this.data = data 36 | notifyDataSetChanged() 37 | } 38 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/joke/adapter/JokeWordListAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.joke.adapter 2 | 3 | import android.content.Context 4 | import android.support.v7.widget.RecyclerView 5 | import android.view.ViewGroup 6 | import com.coorchice.ban.model.base.BaseRecyclerViewHolder 7 | import com.coorchice.ban.model.joke.adapter.itemview.JokeWordListLeftItemView 8 | import com.coorchice.ban.model.joke.adapter.itemview.JokeWordListRightItemView 9 | import com.coorchice.ban.network.DataModel.JokeWord 10 | import com.coorchice.ban.utils.loge 11 | 12 | /** 13 | * Project Name:Ban 14 | * Author:CoorChice 15 | * Date:2017/6/25 16 | * Notes: 17 | */ 18 | class JokeWordListAdapter(var context: Context, var data: List?) : RecyclerView.Adapter() { 19 | 20 | private val TYPE_LEFT = 1 21 | private val TYPE_RIGHT = 2 22 | 23 | override fun onCreateViewHolder(p0: ViewGroup?, p1: Int): RecyclerView.ViewHolder { 24 | if (p1 == TYPE_LEFT) { 25 | loge("position = $p1, type = left") 26 | return BaseRecyclerViewHolder(JokeWordListLeftItemView(context)) 27 | } else { 28 | loge("position = $p1, type = right") 29 | return BaseRecyclerViewHolder(JokeWordListRightItemView(context)) 30 | } 31 | } 32 | 33 | override fun onBindViewHolder(p0: RecyclerView.ViewHolder?, p1: Int) { 34 | if (p0?.itemView is JokeWordListLeftItemView) { 35 | val itemView = p0?.itemView as JokeWordListLeftItemView 36 | itemView.setData(data?.get(p1), p1) 37 | } else { 38 | val itemView = p0?.itemView as JokeWordListRightItemView 39 | itemView.setData(data?.get(p1), p1) 40 | } 41 | } 42 | 43 | override fun getItemCount(): Int { 44 | return data?.size as Int 45 | } 46 | 47 | override fun getItemViewType(position: Int): Int { 48 | if ((position % 2) == 0) { 49 | return TYPE_LEFT 50 | } else { 51 | return TYPE_RIGHT 52 | } 53 | } 54 | 55 | 56 | fun updateData(data: List?) { 57 | this.data = data 58 | notifyDataSetChanged() 59 | } 60 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/joke/adapter/itemview/JokePictureListItemView.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.joke.adapter.itemview 2 | 3 | import android.content.Context 4 | import android.view.LayoutInflater 5 | import android.widget.RelativeLayout 6 | import com.coorchice.ban.R 7 | import com.coorchice.ban.network.DataModel.JokePicture 8 | import kotlinx.android.synthetic.main.item_view_joke_picture_list.view.* 9 | 10 | /** 11 | * Project Name:Ban 12 | * Author:CoorChice 13 | * Date:2017/6/26 14 | * Notes: 15 | */ 16 | class JokePictureListItemView(context: Context) : RelativeLayout(context) { 17 | 18 | init { 19 | LayoutInflater.from(context).inflate(R.layout.item_view_joke_picture_list, this, true) 20 | initView() 21 | } 22 | 23 | private fun initView() { 24 | 25 | } 26 | 27 | fun setData(data: JokePicture?, position: Int) { 28 | sd_pic.setImageURI(data?.url) 29 | tv_content.text = data?.content 30 | tv_time.text = data?.updatetime?.substring(0, 10) 31 | } 32 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/joke/adapter/itemview/JokeWordListLeftItemView.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.joke.adapter.itemview 2 | 3 | import android.content.Context 4 | import android.view.LayoutInflater 5 | import android.widget.RelativeLayout 6 | import com.coorchice.ban.R 7 | import com.coorchice.ban.network.DataModel.JokeWord 8 | import kotlinx.android.synthetic.main.item_view_joke_word_list_left.* 9 | import kotlinx.android.synthetic.main.item_view_joke_word_list_left.view.* 10 | 11 | /** 12 | * Project Name:Ban 13 | * Author:CoorChice 14 | * Date:2017/6/25 15 | * Notes: 16 | */ 17 | class JokeWordListLeftItemView(context: Context) : RelativeLayout(context) { 18 | 19 | init { 20 | LayoutInflater.from(context).inflate(R.layout.item_view_joke_word_list_left, this, true) 21 | initView() 22 | } 23 | 24 | private fun initView() { 25 | 26 | } 27 | 28 | fun setData(data: JokeWord?, position: Int){ 29 | tv_content.text = data?.content 30 | } 31 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/joke/adapter/itemview/JokeWordListRightItemView.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.joke.adapter.itemview 2 | 3 | import android.content.Context 4 | import android.view.LayoutInflater 5 | import android.widget.RelativeLayout 6 | import com.coorchice.ban.R 7 | import com.coorchice.ban.network.DataModel.JokeWord 8 | import kotlinx.android.synthetic.main.item_view_joke_word_list_left.view.* 9 | 10 | /** 11 | * Project Name:Ban 12 | * Author:CoorChice 13 | * Date:2017/6/25 14 | * Notes: 15 | */ 16 | class JokeWordListRightItemView(context: Context) : RelativeLayout(context) { 17 | 18 | init { 19 | LayoutInflater.from(context).inflate(R.layout.item_view_joke_word_list_right, this, true) 20 | initView() 21 | } 22 | 23 | private fun initView() { 24 | 25 | } 26 | 27 | fun setData(data: JokeWord?, position: Int){ 28 | tv_content.text = data?.content 29 | } 30 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/joke/model/JokeModel.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.joke.model 2 | 3 | import com.coorchice.ban.model.base.IJokeModel 4 | import com.coorchice.ban.model.base.OnResponseListener 5 | import com.coorchice.ban.network.DataModel.JokePicture 6 | import com.coorchice.ban.network.DataModel.JokeWord 7 | import com.coorchice.ban.network.Net 8 | import com.coorchice.ban.network.OnFailureCallback 9 | import com.coorchice.ban.network.OnSuccessCallback 10 | 11 | /** 12 | * Project Name:Ban 13 | * Author:CoorChice 14 | * Date:2017/6/25 15 | * Notes: 16 | */ 17 | class JokeModel : IJokeModel { 18 | 19 | override fun requestJokeWordData(page: Int, rows: Int, onResponseListener: OnResponseListener?>) { 20 | Net.getJokeWordData(page, rows, 21 | object : OnSuccessCallback?> { 22 | override fun onSuccess(data: List?) { 23 | onResponseListener.onSuccess(data) 24 | } 25 | 26 | }, 27 | object : OnFailureCallback?> { 28 | override fun onFailure(message: String?) { 29 | onResponseListener.onFailure(message) 30 | } 31 | 32 | } 33 | ) 34 | } 35 | 36 | override fun requestJokePictureData(page: Int, rows: Int, onResponseListener: OnResponseListener?>) { 37 | Net.getJokePictureData(page, rows, 38 | object : OnSuccessCallback?> { 39 | override fun onSuccess(data: List?) { 40 | onResponseListener.onSuccess(data) 41 | } 42 | 43 | }, 44 | object : OnFailureCallback?> { 45 | override fun onFailure(message: String?) { 46 | onResponseListener.onFailure(message) 47 | } 48 | 49 | } 50 | ) 51 | } 52 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/joke/presenter/JokeFragmentPresenter.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.joke.presenter 2 | 3 | import com.coorchice.ban.model.base.IJokeFragment 4 | import com.coorchice.ban.model.base.IJokeModel 5 | import com.coorchice.ban.model.base.OnResponseListener 6 | import com.coorchice.ban.model.joke.model.JokeModel 7 | import com.coorchice.ban.network.DataModel.JokePicture 8 | import com.coorchice.ban.network.DataModel.JokeWord 9 | import com.coorchice.ban.utils.loge 10 | 11 | /** 12 | * Project Name:Ban 13 | * Author:CoorChice 14 | * Date:2017/6/25 15 | * Notes: 16 | */ 17 | class JokeFragmentPresenter(var view: IJokeFragment) { 18 | val model: IJokeModel = JokeModel() 19 | val datas = mutableListOf() 20 | var page: Int = 0 21 | val rows: Int = 10 22 | 23 | fun requestJokeWordData(refresh: Boolean){ 24 | page++ 25 | if (refresh){ 26 | page = 0 27 | datas.clear() 28 | } 29 | model.requestJokeWordData(page, rows, object:OnResponseListener?>{ 30 | override fun onSuccess(data: List?) { 31 | if (data != null && !data.isEmpty()){ 32 | datas.addAll(data as List) 33 | val newDatas = mutableListOf() 34 | newDatas.addAll(datas) 35 | view.updateJokeData(newDatas) 36 | } else { 37 | // 没有了 38 | 39 | } 40 | } 41 | 42 | override fun onFailure(message: String?) { 43 | loge(message?:"无错误信息") 44 | } 45 | }) 46 | } 47 | 48 | fun requestJokePictureData(refresh: Boolean){ 49 | page++ 50 | if (refresh){ 51 | page = 0 52 | datas.clear() 53 | } 54 | model.requestJokePictureData(page, rows, object:OnResponseListener?>{ 55 | override fun onSuccess(data: List?) { 56 | if (data != null && !data.isEmpty()){ 57 | datas.addAll(data as List) 58 | val newDatas = mutableListOf() 59 | newDatas.addAll(datas) 60 | view.updateJokeData(newDatas) 61 | } else { 62 | // 没有了 63 | 64 | } 65 | } 66 | 67 | override fun onFailure(message: String?) { 68 | loge(message?:"无错误信息") 69 | } 70 | }) 71 | } 72 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/joke/view/fragment/JokeFragment.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.joke.view.fragment 2 | 3 | import android.animation.AnimatorSet 4 | import android.app.Fragment 5 | import android.os.Bundle 6 | import android.view.View 7 | import android.widget.ImageView 8 | import android.widget.TextView 9 | import com.coorchice.ban.R 10 | import com.coorchice.ban.model.base.BaseFragment 11 | import com.coorchice.ban.utils.ScaleAnimation 12 | import com.coorchice.ban.utils.floatJumpAnim 13 | import com.coorchice.library.SuperTextView 14 | import org.jetbrains.anko.find 15 | 16 | /** 17 | * Project Name:Ban 18 | * Author:CoorChice 19 | * Date:2017/6/24 20 | * Notes: 21 | */ 22 | class JokeFragment : BaseFragment() { 23 | 24 | private val JOKE_WORD = 1 25 | private val JOKE_PICTURE = 2 26 | 27 | 28 | private var tvTitle: TextView? = null 29 | private var btnWord: SuperTextView? = null 30 | private var btnPicture: SuperTextView? = null 31 | 32 | private var currentShowFragment: Fragment? = null 33 | private var currentModel: Int? = null 34 | private var jokeWordFragment: JokeWordFragment? = null 35 | private var jokePictureFragment: JokePictureFragment? = null 36 | 37 | companion object { 38 | fun getInstance(): JokeFragment { 39 | val bundle = Bundle() 40 | val fragment = JokeFragment() 41 | fragment.arguments = bundle 42 | return fragment 43 | } 44 | } 45 | 46 | override fun getContentViewResId(): Int { 47 | return R.layout.fragment_joke 48 | } 49 | 50 | override fun initData() { 51 | } 52 | 53 | override fun initView() { 54 | findViews() 55 | showModel(JOKE_WORD) 56 | btnWord?.alpha = 1f 57 | btnPicture?.alpha = 0.5f 58 | if (btnWordAnim == null) { 59 | btnWordAnim = floatJumpAnim(btnWord) 60 | } else { 61 | btnWordAnim?.start() 62 | } 63 | if (btnPictureAnim != null) { 64 | btnPictureAnim?.cancel() 65 | } 66 | } 67 | 68 | 69 | private fun findViews() { 70 | tvTitle = rootView?.find(R.id.tv_title) 71 | tvTitle?.text = resources.getString(R.string.btn_model_3) 72 | rootView?.find(R.id.btn_back)?.visibility = View.INVISIBLE 73 | 74 | btnWord = rootView?.find(R.id.btn_word) 75 | btnPicture = rootView?.find(R.id.btn_picture) 76 | } 77 | 78 | 79 | private fun showModel(model: Int) { 80 | if (currentModel == model) { 81 | return 82 | } 83 | if (currentShowFragment != null) { 84 | childFragmentManager.beginTransaction() 85 | .hide(currentShowFragment) 86 | .commitAllowingStateLoss() 87 | } 88 | when (model) { 89 | JOKE_WORD -> { 90 | if (jokeWordFragment == null) { 91 | jokeWordFragment = JokeWordFragment.getInstance() 92 | } 93 | showFragment(jokeWordFragment, model) 94 | } 95 | JOKE_PICTURE -> { 96 | if (jokePictureFragment == null) { 97 | jokePictureFragment = JokePictureFragment.getInstance() 98 | } 99 | showFragment(jokePictureFragment, model) 100 | } 101 | } 102 | } 103 | 104 | 105 | private fun showFragment(fragment: Fragment?, model: Int) { 106 | if (!(fragment?.isAdded as Boolean)) { 107 | childFragmentManager.beginTransaction() 108 | .add(R.id.layout_fragment, fragment) 109 | .commitAllowingStateLoss() 110 | } 111 | if (fragment?.isDetached) { 112 | childFragmentManager.beginTransaction().attach(fragment).commitAllowingStateLoss() 113 | } else if (fragment?.isHidden) { 114 | childFragmentManager.beginTransaction().show(fragment).commitAllowingStateLoss() 115 | } 116 | currentShowFragment = fragment 117 | currentModel = model 118 | } 119 | 120 | private var btnWordAnim: AnimatorSet? = null 121 | private var btnPictureAnim: AnimatorSet? = null 122 | 123 | override fun addListener() { 124 | btnWord?.setOnClickListener({ 125 | if (currentModel != JOKE_WORD) { 126 | showModel(JOKE_WORD) 127 | btnWord?.alpha = 1f 128 | btnPicture?.alpha = 0.5f 129 | if (btnWordAnim == null) { 130 | btnWordAnim = floatJumpAnim(btnWord) 131 | } else { 132 | btnWordAnim?.start() 133 | } 134 | if (btnPictureAnim != null) { 135 | btnPictureAnim?.cancel() 136 | btnPicture?.scaleX = 1f 137 | btnPicture?.scaleY = 1f 138 | } 139 | } 140 | }) 141 | 142 | btnPicture?.setOnClickListener({ 143 | if (currentModel != JOKE_PICTURE) { 144 | showModel(JOKE_PICTURE) 145 | btnWord?.alpha = 0.5f 146 | btnPicture?.alpha = 1f 147 | if (btnWordAnim != null) { 148 | btnWordAnim?.cancel() 149 | btnWord?.scaleX = 1f 150 | btnWord?.scaleY = 1f 151 | } 152 | if (btnPictureAnim == null) { 153 | btnPictureAnim = floatJumpAnim(btnPicture) 154 | } else { 155 | btnPictureAnim?.start() 156 | } 157 | } 158 | 159 | }) 160 | } 161 | 162 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/joke/view/fragment/JokePictureFragment.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.joke.view.fragment 2 | 3 | import android.graphics.Rect 4 | import android.os.Bundle 5 | import android.support.v7.widget.DefaultItemAnimator 6 | import android.support.v7.widget.LinearLayoutManager 7 | import android.support.v7.widget.RecyclerView 8 | import android.view.Gravity 9 | import android.view.View 10 | import android.view.ViewGroup 11 | import com.coorchice.ban.R 12 | import com.coorchice.ban.model.base.BaseFragment 13 | import com.coorchice.ban.model.base.IJokeFragment 14 | import com.coorchice.ban.model.joke.adapter.JokePictureListAdapter 15 | import com.coorchice.ban.model.joke.presenter.JokeFragmentPresenter 16 | import com.coorchice.ban.network.DataModel.JokePicture 17 | import com.coorchice.ban.utils.loge 18 | import com.coorchice.library.SuperTextView 19 | import com.github.nuptboyzhb.lib.SuperSwipeRefreshLayout 20 | import org.jetbrains.anko.dip 21 | import org.jetbrains.anko.find 22 | import org.jetbrains.anko.textColor 23 | 24 | /** 25 | * Project Name:Ban 26 | * Author:CoorChice 27 | * Date:2017/6/25 28 | * Notes: 29 | */ 30 | class JokePictureFragment : BaseFragment(), IJokeFragment { 31 | 32 | 33 | private var layoutRefresh: SuperSwipeRefreshLayout? = null 34 | private var jokePictureList: RecyclerView? = null 35 | 36 | private val presenter: JokeFragmentPresenter by lazy { JokeFragmentPresenter(this) } 37 | private var jokePictureListAdapter: JokePictureListAdapter? = null 38 | 39 | companion object { 40 | fun getInstance(): JokePictureFragment { 41 | val bundle = Bundle() 42 | val fragment = JokePictureFragment() 43 | fragment.arguments = bundle 44 | return fragment 45 | } 46 | } 47 | 48 | override fun getContentViewResId(): Int { 49 | return R.layout.fragment_joke_picture 50 | 51 | } 52 | 53 | override fun initData() { 54 | presenter.requestJokePictureData(true) 55 | } 56 | 57 | override fun initView() { 58 | showEmpty(true) 59 | findViews() 60 | initLayoutRefresh() 61 | initJokeWordList() 62 | } 63 | 64 | private fun findViews() { 65 | layoutRefresh = rootView?.find(R.id.layout_refresh) 66 | jokePictureList = rootView?.find(R.id.rv_joke_picture_list) 67 | 68 | } 69 | 70 | private fun initLayoutRefresh() { 71 | setLoadView() 72 | layoutRefresh?.setOnPullRefreshListener(object : SuperSwipeRefreshLayout.OnPullRefreshListener { 73 | override fun onPullEnable(p0: Boolean) { 74 | loge("refresh -> onPullEnable") 75 | } 76 | 77 | override fun onPullDistance(p0: Int) { 78 | loge("refresh -> onPullDistance") 79 | 80 | } 81 | 82 | override fun onRefresh() { 83 | presenter.requestJokePictureData(true) 84 | } 85 | }) 86 | 87 | layoutRefresh?.setOnPushLoadMoreListener(object : SuperSwipeRefreshLayout.OnPushLoadMoreListener { 88 | override fun onPushDistance(p0: Int) { 89 | loge("loadmore -> onPushDistance") 90 | } 91 | 92 | override fun onPushEnable(p0: Boolean) { 93 | loge("loadmore -> onPushEnable") 94 | 95 | } 96 | 97 | override fun onLoadMore() { 98 | presenter.requestJokePictureData(false) 99 | } 100 | 101 | }) 102 | 103 | } 104 | 105 | private fun setLoadView() { 106 | var refreshFooterView = SuperTextView(activity) 107 | refreshFooterView.gravity = Gravity.CENTER 108 | refreshFooterView.text = "奋力加载中..." 109 | refreshFooterView.textColor = resources.getColor(R.color.md_black_1000) 110 | refreshFooterView.textSize = 12f 111 | val lp = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) 112 | refreshFooterView.layoutParams = lp 113 | layoutRefresh?.setFooterView(refreshFooterView) 114 | } 115 | 116 | private fun initJokeWordList() { 117 | jokePictureList?.layoutManager = LinearLayoutManager(activity) 118 | jokePictureList?.itemAnimator = DefaultItemAnimator() 119 | jokePictureList?.addItemDecoration(object : RecyclerView.ItemDecoration() { 120 | override fun getItemOffsets(outRect: Rect?, view: View?, parent: RecyclerView?, state: RecyclerView.State?) { 121 | var position = parent?.layoutManager?.getPosition(view) 122 | if (position == 0) { 123 | outRect?.top = dip(16) 124 | } 125 | outRect?.left = dip(16) 126 | outRect?.right = dip(16) 127 | outRect?.bottom = dip(8) 128 | if (position == parent?.adapter?.itemCount?.minus(1)) { 129 | outRect?.bottom = dip(26) 130 | } 131 | } 132 | }) 133 | jokePictureListAdapter = JokePictureListAdapter(activity, emptyList()) 134 | jokePictureList?.adapter = jokePictureListAdapter 135 | } 136 | 137 | 138 | override fun addListener() { 139 | } 140 | 141 | override fun updateJokeData(data: List?) { 142 | showEmpty(false) 143 | if (layoutRefresh?.isRefreshing == true) { 144 | layoutRefresh?.isRefreshing = false 145 | } 146 | layoutRefresh?.setLoadMore(false) 147 | jokePictureListAdapter?.updateData(data) 148 | } 149 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/joke/view/fragment/JokeWordFragment.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.joke.view.fragment 2 | 3 | import android.graphics.Rect 4 | import android.os.Bundle 5 | import android.support.v7.widget.DefaultItemAnimator 6 | import android.support.v7.widget.LinearLayoutManager 7 | import android.support.v7.widget.RecyclerView 8 | import android.view.Gravity 9 | import android.view.View 10 | import android.view.ViewGroup 11 | import com.coorchice.ban.R 12 | import com.coorchice.ban.model.base.BaseFragment 13 | import com.coorchice.ban.model.base.IJokeFragment 14 | import com.coorchice.ban.model.joke.adapter.JokeWordListAdapter 15 | import com.coorchice.ban.model.joke.presenter.JokeFragmentPresenter 16 | import com.coorchice.ban.network.DataModel.JokeWord 17 | import com.coorchice.ban.utils.loge 18 | import com.coorchice.library.SuperTextView 19 | import com.github.nuptboyzhb.lib.SuperSwipeRefreshLayout 20 | import org.jetbrains.anko.dip 21 | import org.jetbrains.anko.find 22 | import org.jetbrains.anko.textColor 23 | 24 | /** 25 | * Project Name:Ban 26 | * Author:CoorChice 27 | * Date:2017/6/25 28 | * Notes: 29 | */ 30 | class JokeWordFragment : BaseFragment(), IJokeFragment { 31 | 32 | private var layoutRefresh: SuperSwipeRefreshLayout? = null 33 | private var jokeWordList: RecyclerView? = null 34 | 35 | private val presenter: JokeFragmentPresenter by lazy { JokeFragmentPresenter(this) } 36 | private var jokeWordListAdapter: JokeWordListAdapter? = null 37 | 38 | companion object { 39 | fun getInstance(): JokeWordFragment { 40 | val bundle = Bundle() 41 | val fragment = JokeWordFragment() 42 | fragment.arguments = bundle 43 | return fragment 44 | } 45 | } 46 | 47 | override fun getContentViewResId(): Int { 48 | return R.layout.fragment_joke_word 49 | } 50 | 51 | override fun initData() { 52 | presenter.requestJokeWordData(true) 53 | } 54 | 55 | override fun initView() { 56 | showEmpty(true) 57 | findViews() 58 | initLayoutRefresh() 59 | initJokeWordList() 60 | } 61 | 62 | private fun findViews() { 63 | layoutRefresh = rootView?.find(R.id.layout_refresh) 64 | jokeWordList = rootView?.find(R.id.rv_joke_word_list) 65 | 66 | } 67 | 68 | private fun initLayoutRefresh() { 69 | setLoadView() 70 | layoutRefresh?.setOnPullRefreshListener(object : SuperSwipeRefreshLayout.OnPullRefreshListener { 71 | override fun onPullEnable(p0: Boolean) { 72 | loge("refresh -> onPullEnable") 73 | } 74 | 75 | override fun onPullDistance(p0: Int) { 76 | loge("refresh -> onPullDistance") 77 | 78 | } 79 | 80 | override fun onRefresh() { 81 | presenter.requestJokeWordData(true) 82 | } 83 | }) 84 | 85 | layoutRefresh?.setOnPushLoadMoreListener(object : SuperSwipeRefreshLayout.OnPushLoadMoreListener { 86 | override fun onPushDistance(p0: Int) { 87 | loge("loadmore -> onPushDistance") 88 | } 89 | 90 | override fun onPushEnable(p0: Boolean) { 91 | loge("loadmore -> onPushEnable") 92 | 93 | } 94 | 95 | override fun onLoadMore() { 96 | presenter.requestJokeWordData(false) 97 | } 98 | 99 | }) 100 | 101 | } 102 | 103 | private fun setLoadView() { 104 | var refreshFooterView = SuperTextView(activity) 105 | refreshFooterView.gravity = Gravity.CENTER 106 | refreshFooterView.text = "奋力加载中..." 107 | refreshFooterView.textColor = resources.getColor(R.color.md_black_1000) 108 | refreshFooterView.textSize = 12f 109 | val lp = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) 110 | refreshFooterView.layoutParams = lp 111 | layoutRefresh?.setFooterView(refreshFooterView) 112 | } 113 | 114 | 115 | private fun initJokeWordList() { 116 | jokeWordList?.layoutManager = LinearLayoutManager(activity) 117 | jokeWordList?.itemAnimator = DefaultItemAnimator() 118 | jokeWordList?.addItemDecoration(object : RecyclerView.ItemDecoration() { 119 | override fun getItemOffsets(outRect: Rect?, view: View?, parent: RecyclerView?, state: RecyclerView.State?) { 120 | var position = parent?.layoutManager?.getPosition(view) 121 | if (position == 0) { 122 | outRect?.top = dip(16) 123 | } 124 | outRect?.left = dip(10) 125 | outRect?.right = dip(10) 126 | outRect?.bottom = dip(16) 127 | if (position == parent?.adapter?.itemCount?.minus(1)) { 128 | outRect?.bottom = dip(26) 129 | } 130 | } 131 | }) 132 | jokeWordListAdapter = JokeWordListAdapter(activity, emptyList()) 133 | jokeWordList?.adapter = jokeWordListAdapter 134 | } 135 | 136 | override fun addListener() { 137 | 138 | } 139 | 140 | override fun updateJokeData(data: List?) { 141 | showEmpty(false) 142 | if (layoutRefresh?.isRefreshing == true) { 143 | layoutRefresh?.isRefreshing = false 144 | } 145 | layoutRefresh?.setLoadMore(false) 146 | jokeWordListAdapter?.updateData(data) 147 | } 148 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/news/adapter/ItemView/NewsListMorePicItemView.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.news.adapter.ItemView 2 | 3 | import android.content.Context 4 | import android.view.LayoutInflater 5 | import android.widget.RelativeLayout 6 | import com.coorchice.ban.R 7 | import com.coorchice.ban.model.base.toWebActivity 8 | import com.coorchice.ban.network.DataModel.News 9 | import kotlinx.android.synthetic.main.item_view_news_list_more_pic.view.* 10 | 11 | /** 12 | * Project Name:Ban 13 | * Author:CoorChice 14 | * Date:2017/6/11 15 | * Notes: 16 | */ 17 | class NewsListMorePicItemView(context: Context) : RelativeLayout(context) { 18 | 19 | init { 20 | LayoutInflater.from(context).inflate(R.layout.item_view_news_list_more_pic, this, true) 21 | initView() 22 | } 23 | 24 | private fun initView() { 25 | 26 | } 27 | 28 | fun setData(data: News?, position: Int) { 29 | title.text = data?.title 30 | pic_1.setImageURI(data?.thumbnail_pic_s) 31 | pic_2.setImageURI(data?.thumbnail_pic_s02) 32 | pic_3.setImageURI(data?.thumbnail_pic_s03) 33 | author.text = data?.author_name 34 | time.text = data?.date 35 | setOnClickListener { 36 | toWebActivity(context, data?.url, data?.title) 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/news/adapter/ItemView/NewsListSinglePicItemView.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.news.adapter.ItemView 2 | 3 | import android.content.Context 4 | import android.view.LayoutInflater 5 | import android.widget.RelativeLayout 6 | import com.coorchice.ban.R 7 | import com.coorchice.ban.model.base.toWebActivity 8 | import com.coorchice.ban.network.DataModel.News 9 | import kotlinx.android.synthetic.main.item_view_news_list_single_pic.view.* 10 | 11 | /** 12 | * Project Name:Ban 13 | * Author:CoorChice 14 | * Date:2017/6/11 15 | * Notes: 16 | */ 17 | class NewsListSinglePicItemView(context: Context) : RelativeLayout(context) { 18 | 19 | init { 20 | LayoutInflater.from(context).inflate(R.layout.item_view_news_list_single_pic, this, true) 21 | initView() 22 | } 23 | 24 | private fun initView() { 25 | 26 | } 27 | 28 | fun setData(data: News?, position: Int) { 29 | title.text = data?.title 30 | pic.setImageURI(data?.thumbnail_pic_s) 31 | author.text = data?.author_name 32 | time.text = data?.date 33 | setOnClickListener { 34 | toWebActivity(context, data?.url, data?.title) 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/news/adapter/ItemView/NewsNavigatorListItemView.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.news.adapter.ItemView 2 | 3 | import android.content.Context 4 | import android.view.LayoutInflater 5 | import android.widget.RelativeLayout 6 | import com.coorchice.ban.R 7 | import com.coorchice.ban.model.base.OnItemViewClickListener 8 | import com.coorchice.ban.model.news.entry.NewsNavigation 9 | import kotlinx.android.synthetic.main.item_view_news_navigator_list.view.* 10 | 11 | /** 12 | * Project Name:Ban 13 | * Author:CoorChice 14 | * Date:2017/6/10 15 | * Notes: 16 | */ 17 | class NewsNavigatorListItemView(context: Context?) : RelativeLayout(context) { 18 | 19 | var onItemViewClickListener: OnItemViewClickListener? = null 20 | 21 | init { 22 | LayoutInflater.from(context).inflate(R.layout.item_view_news_navigator_list, this, true) 23 | initView() 24 | } 25 | 26 | private fun initView() { 27 | } 28 | 29 | fun setData(data: NewsNavigation, position: Int) { 30 | bg.solid = resources.getColor(data.bg) 31 | iv_icon.setImageResource(data.icon) 32 | tv_title.text = data.title 33 | setOnClickListener { 34 | onItemViewClickListener?.OnItemViewClick(data, position) 35 | } 36 | } 37 | 38 | 39 | } 40 | 41 | -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/news/adapter/NewsListAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.news.adapter 2 | 3 | import android.content.Context 4 | import android.support.v7.widget.RecyclerView 5 | import android.text.TextUtils 6 | import android.view.ViewGroup 7 | import com.coorchice.ban.model.base.BaseRecyclerViewHolder 8 | import com.coorchice.ban.model.news.adapter.ItemView.NewsListMorePicItemView 9 | import com.coorchice.ban.model.news.adapter.ItemView.NewsListSinglePicItemView 10 | import com.coorchice.ban.network.DataModel.News 11 | 12 | /** 13 | * Project Name:Ban 14 | * Author:CoorChice 15 | * Date:2017/6/11 16 | * Notes: 17 | */ 18 | class NewsListAdapter(val context: Context, var data: List?) : RecyclerView.Adapter() { 19 | 20 | val SINGLE_PIC = 1 21 | val MORE_PIC = 2 22 | 23 | override fun onCreateViewHolder(viewGroup: ViewGroup?, position: Int): RecyclerView.ViewHolder { 24 | if (getItemViewType(position) == SINGLE_PIC) { 25 | return BaseRecyclerViewHolder(NewsListSinglePicItemView(context)) 26 | } else { 27 | return BaseRecyclerViewHolder(NewsListMorePicItemView(context)) 28 | } 29 | } 30 | 31 | override fun onBindViewHolder(viewHolder: RecyclerView.ViewHolder?, position: Int) { 32 | var itemView = viewHolder?.itemView 33 | if (itemView is NewsListSinglePicItemView) { 34 | itemView.setData(data?.get(position), position) 35 | } else if (itemView is NewsListMorePicItemView) { 36 | itemView.setData(data?.get(position), position) 37 | } 38 | } 39 | 40 | override fun getItemCount(): Int { 41 | return data?.size as Int 42 | } 43 | 44 | override fun getItemViewType(position: Int): Int { 45 | if (TextUtils.isEmpty(data?.get(position)?.thumbnail_pic_s02)) { 46 | return SINGLE_PIC 47 | } else { 48 | return MORE_PIC 49 | } 50 | } 51 | 52 | fun updateData(data: List?) { 53 | this.data = data 54 | notifyDataSetChanged() 55 | } 56 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/news/adapter/NewsNavigatorListAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.news.adapter 2 | 3 | import android.content.Context 4 | import android.support.v7.widget.RecyclerView 5 | import android.view.ViewGroup 6 | import android.view.animation.AccelerateInterpolator 7 | import android.view.animation.LinearInterpolator 8 | import com.coorchice.ban.model.base.BaseRecyclerViewHolder 9 | import com.coorchice.ban.model.base.OnItemViewClickListener 10 | import com.coorchice.ban.model.news.adapter.ItemView.NewsNavigatorListItemView 11 | import com.coorchice.ban.model.news.entry.NewsNavigation 12 | import com.coorchice.ban.utils.ScaleAnimation 13 | import com.coorchice.ban.utils.playScaleAnimation 14 | 15 | /** 16 | * Project Name:Ban 17 | * Author:CoorChice 18 | * Date:2017/6/10 19 | * Notes: 20 | */ 21 | class NewsNavigatorListAdapter(val context: Context?) : RecyclerView.Adapter() { 22 | 23 | var onItemViewClickListener: OnItemViewClickListener? = null 24 | var selectedItem: Int = 0 25 | set(value) { 26 | field = value 27 | notifyDataSetChanged() 28 | } 29 | 30 | override fun onCreateViewHolder(viewGroup: ViewGroup?, position: Int): RecyclerView.ViewHolder { 31 | return BaseRecyclerViewHolder(NewsNavigatorListItemView(context)) 32 | } 33 | 34 | override fun onBindViewHolder(viewHolder: RecyclerView.ViewHolder?, position: Int) { 35 | val itemView = viewHolder?.itemView as NewsNavigatorListItemView 36 | itemView.setData(NewsNavigation.values()[position], position) 37 | itemView.onItemViewClickListener = onItemViewClickListener 38 | playScaleAnimation(itemView, 1f, 0, LinearInterpolator()) 39 | itemView.alpha = 0.5f 40 | if (selectedItem == position) { 41 | playScaleAnimation(itemView, 1.02f, 300, AccelerateInterpolator()) 42 | itemView.alpha = 1f 43 | } 44 | } 45 | 46 | override fun getItemCount(): Int { 47 | return NewsNavigation.values().size 48 | } 49 | 50 | 51 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/news/entry/NewsNavigation.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.news.entry 2 | 3 | import com.coorchice.ban.R 4 | 5 | /** 6 | * Project Name:Ban 7 | * Author:CoorChice 8 | * Date:2017/6/10 9 | * Notes: 10 | */ 11 | enum class NewsNavigation(val title: String, val bg : Int, val icon : Int, val requestCode : String) { 12 | 13 | INTERNATIONAL("国际", R.color.news_navigator_1_bg, R.drawable.international, "guoji"), 14 | INLAND("国内", R.color.news_navigator_2_bg, R.drawable.inland, "guonei"), 15 | TECHNOLOGY("科技", R.color.news_navigator_3_bg, R.drawable.technology, "keji"), 16 | CURIOSITY("奇闻", R.color.news_navigator_4_bg, R.drawable.curiosity, "shehui"), 17 | ENTERTAINMENT("娱乐", R.color.news_navigator_5_bg, R.drawable.entertainment, "yule"), 18 | PE("体育", R.color.news_navigator_6_bg, R.drawable.pe, "tiyu") 19 | 20 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/news/model/NewsModel.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.news.model 2 | 3 | import com.coorchice.ban.model.base.INewsModel 4 | import com.coorchice.ban.model.base.OnResponseListener 5 | import com.coorchice.ban.network.DataModel.NewsResponse 6 | import com.coorchice.ban.network.Net 7 | import com.coorchice.ban.network.OnFailureCallback 8 | import com.coorchice.ban.network.OnSuccessCallback 9 | 10 | /** 11 | * Project Name:Ban 12 | * Author:CoorChice 13 | * Date:2017/6/11 14 | * Notes: 15 | */ 16 | class NewsModel : INewsModel { 17 | 18 | override fun requestNewsData(type: String, onResponseListener: OnResponseListener) { 19 | Net.getNewsData(type, 20 | object : OnSuccessCallback { 21 | override fun onSuccess(data: NewsResponse?) { 22 | onResponseListener.onSuccess(data) 23 | } 24 | }, 25 | 26 | object : OnFailureCallback { 27 | override fun onFailure(message: String?) { 28 | onResponseListener.onFailure(message) 29 | } 30 | 31 | } 32 | ) 33 | } 34 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/news/presenter/NewsListFragmentPresenter.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.news.presenter 2 | 3 | import com.coorchice.ban.model.base.OnResponseListener 4 | import com.coorchice.ban.model.base.INewsModel 5 | import com.coorchice.ban.model.news.model.NewsModel 6 | import com.coorchice.ban.model.base.INewsListFragment 7 | import com.coorchice.ban.network.DataModel.NewsResponse 8 | 9 | /** 10 | * Project Name:Ban 11 | * Author:CoorChice 12 | * Date:2017/6/11 13 | * Notes: 14 | */ 15 | class NewsListFragmentPresenter(var view: INewsListFragment) { 16 | 17 | val newsModel: INewsModel = NewsModel() 18 | 19 | fun requestNewsData(type: String) { 20 | newsModel.requestNewsData(type, object : OnResponseListener { 21 | override fun onSuccess(data: NewsResponse?) { 22 | view?.updateNewsData(data?.data) 23 | } 24 | 25 | override fun onFailure(message: String?) { 26 | } 27 | }) 28 | } 29 | 30 | 31 | 32 | 33 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/news/view/fragment/NewsFragment.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.news.view.fragment 2 | 3 | import android.app.Fragment 4 | import android.graphics.Rect 5 | import android.os.Bundle 6 | import android.support.v4.view.ViewPager 7 | import android.support.v7.widget.DefaultItemAnimator 8 | import android.support.v7.widget.LinearLayoutManager 9 | import android.support.v7.widget.RecyclerView 10 | import android.view.View 11 | import com.coorchice.ban.R 12 | import com.coorchice.ban.model.base.BaseFragment 13 | import com.coorchice.ban.model.base.OnItemViewClickListener 14 | import com.coorchice.ban.model.base.AppFragmentPagerAdapter.FragmentPagerAdapter 15 | import com.coorchice.ban.model.news.adapter.NewsNavigatorListAdapter 16 | import com.coorchice.ban.model.news.entry.NewsNavigation 17 | import kotlinx.android.synthetic.main.layout_header_bar.* 18 | import org.jetbrains.anko.dip 19 | import org.jetbrains.anko.find 20 | 21 | /** 22 | * Project Name:Ban 23 | * Author:CoorChice 24 | * Date:2017/6/10 25 | * Notes: 26 | */ 27 | class NewsFragment : BaseFragment() { 28 | 29 | private var newsNavigationList: RecyclerView? = null 30 | private var vpNewsListFragment: ViewPager? = null 31 | 32 | private var newsNavigatorListAdapter: NewsNavigatorListAdapter? = null 33 | private var currentModel: Int = 0 34 | private val fragments = arrayOfNulls(6) 35 | 36 | companion object { 37 | fun getInstance(): Fragment { 38 | val bundle = Bundle() 39 | val instance = NewsFragment() 40 | instance.arguments = bundle 41 | return instance 42 | } 43 | } 44 | 45 | override fun getContentViewResId(): Int { 46 | return R.layout.fragment_news 47 | } 48 | 49 | override fun initData() { 50 | } 51 | 52 | 53 | override fun initView() { 54 | findView() 55 | btn_back.visibility = View.INVISIBLE 56 | tv_title.text = resources.getString(R.string.btn_model_1) 57 | // header_line.visibility = View.GONE 58 | initNewNavigationList() 59 | initVpNewsListFragment() 60 | } 61 | 62 | private fun findView() { 63 | newsNavigationList = rootView?.find(R.id.rv_news_navigation) 64 | vpNewsListFragment = rootView?.find(R.id.vp_news_list_fragment) 65 | } 66 | 67 | private fun initNewNavigationList() { 68 | newsNavigationList?.layoutManager = LinearLayoutManager(activity, RecyclerView.HORIZONTAL, false) 69 | newsNavigationList?.itemAnimator = DefaultItemAnimator() 70 | newsNavigationList?.addItemDecoration(object : RecyclerView.ItemDecoration() { 71 | override fun getItemOffsets(outRect: Rect?, view: View?, parent: RecyclerView?, state: RecyclerView.State?) { 72 | val position = parent?.layoutManager?.getPosition(view) 73 | if (position == 0) { 74 | outRect?.left = dip(16) 75 | } else { 76 | outRect?.left = dip(8f) 77 | } 78 | if (position == parent?.layoutManager?.childCount) { 79 | outRect?.right = dip(16) 80 | } 81 | } 82 | }) 83 | newsNavigatorListAdapter = NewsNavigatorListAdapter(activity) 84 | newsNavigatorListAdapter?.onItemViewClickListener = 85 | object : OnItemViewClickListener { 86 | override fun OnItemViewClick(data: NewsNavigation, position: Int) { 87 | currentModel = position 88 | vpNewsListFragment?.setCurrentItem(position, true) 89 | newsNavigatorListAdapter?.selectedItem = position 90 | } 91 | 92 | } 93 | newsNavigationList?.adapter = newsNavigatorListAdapter 94 | } 95 | 96 | private fun initVpNewsListFragment() { 97 | vpNewsListFragment?.offscreenPageLimit = 6 98 | vpNewsListFragment?.adapter = object : FragmentPagerAdapter(childFragmentManager) { 99 | override fun getItem(position: Int): Fragment { 100 | var fragment: Fragment? = fragments[position] 101 | if (fragment == null) { 102 | fragment = NewsListFragment.getInstance(NewsNavigation.values()[position].requestCode) 103 | fragments[position] = fragment 104 | } 105 | return fragment 106 | } 107 | 108 | override fun getCount(): Int { 109 | return NewsNavigation.values().size 110 | } 111 | } 112 | vpNewsListFragment?.setOnPageChangeListener(object : ViewPager.OnPageChangeListener { 113 | override fun onPageScrollStateChanged(p0: Int) { 114 | 115 | } 116 | 117 | override fun onPageScrolled(p0: Int, p1: Float, p2: Int) { 118 | } 119 | 120 | override fun onPageSelected(position: Int) { 121 | currentModel = position 122 | newsNavigationList?.smoothScrollToPosition(position) 123 | newsNavigatorListAdapter?.selectedItem = position 124 | } 125 | 126 | }) 127 | vpNewsListFragment?.currentItem = 0 128 | } 129 | 130 | override fun addListener() { 131 | 132 | } 133 | 134 | } 135 | 136 | -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/news/view/fragment/NewsListFragment.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.news.view.fragment 2 | 3 | import android.graphics.Rect 4 | import android.os.Bundle 5 | import android.support.v7.widget.DefaultItemAnimator 6 | import android.support.v7.widget.LinearLayoutManager 7 | import android.support.v7.widget.RecyclerView 8 | import android.view.View 9 | import com.coorchice.ban.R 10 | import com.coorchice.ban.model.base.BaseFragment 11 | import com.coorchice.ban.model.base.INewsListFragment 12 | import com.coorchice.ban.model.news.adapter.NewsListAdapter 13 | import com.coorchice.ban.model.news.presenter.NewsListFragmentPresenter 14 | import com.coorchice.ban.network.DataModel.News 15 | import com.coorchice.ban.utils.loge 16 | import com.github.nuptboyzhb.lib.SuperSwipeRefreshLayout 17 | import org.jetbrains.anko.dip 18 | import org.jetbrains.anko.find 19 | 20 | /** 21 | * Project Name:Ban 22 | * Author:CoorChice 23 | * Date:2017/6/11 24 | * Notes: 25 | */ 26 | class NewsListFragment : BaseFragment(), INewsListFragment { 27 | 28 | private val presenter: NewsListFragmentPresenter by lazy { 29 | NewsListFragmentPresenter(this) 30 | } 31 | 32 | private var newsList: RecyclerView? = null 33 | private var layoutRefresh: SuperSwipeRefreshLayout? = null 34 | 35 | var newsListAdapter: NewsListAdapter? = null 36 | 37 | companion object { 38 | val KEY_TYPE = "key_type" 39 | fun getInstance(type: String): NewsListFragment { 40 | val bundle = Bundle() 41 | bundle.putString(KEY_TYPE, type) 42 | val fragment = NewsListFragment() 43 | fragment.arguments = bundle 44 | return fragment 45 | } 46 | } 47 | 48 | override fun getContentViewResId(): Int { 49 | return R.layout.fragment_news_list 50 | } 51 | 52 | override fun initData() { 53 | presenter.requestNewsData(arguments.getString(KEY_TYPE)) 54 | } 55 | 56 | override fun initView() { 57 | showEmpty(true) 58 | findView() 59 | initNewsList() 60 | } 61 | 62 | 63 | private fun findView() { 64 | layoutRefresh = rootView?.find(R.id.layout_refresh) 65 | newsList = rootView?.find(R.id.rv_news_list) 66 | } 67 | 68 | private fun initNewsList() { 69 | newsList?.layoutManager = LinearLayoutManager(activity, RecyclerView.VERTICAL, false) 70 | newsList?.itemAnimator = DefaultItemAnimator() 71 | newsList?.addItemDecoration(object : RecyclerView.ItemDecoration() { 72 | override fun getItemOffsets(outRect: Rect?, view: View?, parent: RecyclerView?, state: RecyclerView.State?) { 73 | val position = parent?.layoutManager?.getPosition(view) 74 | if (position == 0) { 75 | outRect?.top = dip(11) 76 | } 77 | if (position == parent?.adapter?.itemCount?.minus(1)) { 78 | outRect?.bottom = dip(11) 79 | } else { 80 | outRect?.bottom = dip(2) 81 | } 82 | } 83 | }) 84 | newsListAdapter = NewsListAdapter(activity, emptyList()) 85 | newsList?.adapter = newsListAdapter 86 | } 87 | 88 | 89 | override fun addListener() { 90 | layoutRefresh?.setOnPullRefreshListener(object : SuperSwipeRefreshLayout.OnPullRefreshListener { 91 | override fun onPullEnable(p0: Boolean) { 92 | loge("refresh -> onPullEnable") 93 | } 94 | 95 | override fun onPullDistance(p0: Int) { 96 | loge("refresh -> onPullDistance") 97 | 98 | } 99 | 100 | override fun onRefresh() { 101 | loge("refresh -> onRefresh") 102 | presenter.requestNewsData(arguments.getString(KEY_TYPE)) 103 | } 104 | }) 105 | } 106 | 107 | override fun updateNewsData(data: List?) { 108 | showEmpty(false) 109 | if (layoutRefresh?.isRefreshing == true) { 110 | layoutRefresh?.isRefreshing = false 111 | } 112 | newsListAdapter?.updateData(data) 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/web/activity/WebActivity.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.web.activity 2 | 3 | import android.content.Context 4 | import android.content.Intent 5 | import android.net.http.SslError 6 | import android.os.Build 7 | import android.webkit.SslErrorHandler 8 | import android.webkit.WebSettings 9 | import android.webkit.WebView 10 | import android.webkit.WebViewClient 11 | import com.coorchice.ban.R 12 | import com.coorchice.ban.model.base.BaseActivity 13 | import com.coorchice.ban.utils.logi 14 | import kotlinx.android.synthetic.main.activity_web.* 15 | import kotlinx.android.synthetic.main.layout_header_bar.* 16 | 17 | class WebActivity : BaseActivity() { 18 | 19 | companion object { 20 | val KEY_URL = "key_url" 21 | val KEY_TITLE = "key_title" 22 | 23 | fun getIntent(context: Context, url: String?, title: String?): Intent { 24 | var intent = Intent(context, WebActivity::class.java) 25 | intent.putExtra(KEY_URL, url) 26 | intent.putExtra(KEY_TITLE, title) 27 | return intent 28 | } 29 | } 30 | 31 | override fun getContentViewResId(): Int { 32 | return R.layout.activity_web 33 | } 34 | 35 | override fun initData() { 36 | } 37 | 38 | override fun initView() { 39 | tv_title.text = intent.getStringExtra(KEY_TITLE) 40 | initWebView() 41 | } 42 | 43 | private fun initWebView() { 44 | val client = object : WebViewClient() { 45 | override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean { 46 | web_view.loadUrl(url) 47 | return true 48 | } 49 | 50 | override fun onReceivedSslError(view: WebView?, handler: SslErrorHandler?, error: SslError?) { 51 | handler?.proceed() 52 | } 53 | } 54 | web_view.setWebViewClient(client) 55 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 56 | web_view.settings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW 57 | } 58 | web_view.settings.javaScriptEnabled = true 59 | web_view.settings.blockNetworkImage = false 60 | web_view.settings.setAppCacheEnabled(true) 61 | web_view.settings.databaseEnabled = true 62 | web_view.settings.domStorageEnabled = true 63 | web_view.settings.cacheMode = WebSettings.LOAD_DEFAULT 64 | val url = intent.getStringExtra(KEY_URL) 65 | web_view.loadUrl(url) 66 | logi("URL -> " + url) 67 | } 68 | 69 | override fun addListener() { 70 | btn_back.setOnClickListener { 71 | finish() 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/wechat/adapter/WechatNewsListAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.wechat.adapter 2 | 3 | import android.content.Context 4 | import android.support.v7.widget.RecyclerView 5 | import android.view.ViewGroup 6 | import com.coorchice.ban.model.base.BaseRecyclerViewHolder 7 | import com.coorchice.ban.model.wechat.adapter.itemview.WechatNewsListItemView 8 | import com.coorchice.ban.network.DataModel.WechatNews 9 | 10 | /** 11 | * Project Name:Ban 12 | * Author:CoorChice 13 | * Date:2017/6/12 14 | * Notes: 15 | */ 16 | class WechatNewsListAdapter(var context: Context, var data : List?) : RecyclerView.Adapter(){ 17 | 18 | override fun onCreateViewHolder(viewGroup: ViewGroup?, position: Int): RecyclerView.ViewHolder { 19 | return BaseRecyclerViewHolder(WechatNewsListItemView(context)) 20 | } 21 | 22 | override fun onBindViewHolder(viewHolder: RecyclerView.ViewHolder?, position: Int) { 23 | var itemView = viewHolder?.itemView as WechatNewsListItemView 24 | itemView?.setData(data?.get(position), position) 25 | } 26 | 27 | override fun getItemCount(): Int { 28 | return data?.size as Int 29 | } 30 | 31 | fun updateData(data: List?){ 32 | this.data = data 33 | notifyDataSetChanged() 34 | } 35 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/wechat/adapter/itemview/WechatNewsListItemView.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.wechat.adapter.itemview 2 | 3 | import android.content.Context 4 | import android.view.LayoutInflater 5 | import android.widget.RelativeLayout 6 | import com.coorchice.ban.R 7 | import com.coorchice.ban.model.base.toWebActivity 8 | import com.coorchice.ban.network.DataModel.WechatNews 9 | import kotlinx.android.synthetic.main.item_view_wechat_news_list.view.* 10 | 11 | /** 12 | * Project Name:Ban 13 | * Author:CoorChice 14 | * Date:2017/6/12 15 | * Notes: 16 | */ 17 | class WechatNewsListItemView(context:Context):RelativeLayout(context){ 18 | 19 | init { 20 | LayoutInflater.from(context).inflate(R.layout.item_view_wechat_news_list,this,true) 21 | initView() 22 | } 23 | 24 | private fun initView() { 25 | 26 | } 27 | 28 | fun setData(data:WechatNews?, position:Int){ 29 | tv_title.text = data?.title 30 | tv_source.text = data?.source 31 | pic.setImageURI(data?.firstImg) 32 | setOnClickListener { 33 | toWebActivity(context, data?.url, data?.title) 34 | } 35 | } 36 | 37 | 38 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/wechat/model/WechatNewsModel.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.wechat.model 2 | 3 | import com.coorchice.ban.model.base.IWeChatNewsModel 4 | import com.coorchice.ban.model.base.OnResponseListener 5 | import com.coorchice.ban.network.DataModel.WechatNewsResponse 6 | import com.coorchice.ban.network.Net 7 | import com.coorchice.ban.network.OnFailureCallback 8 | import com.coorchice.ban.network.OnSuccessCallback 9 | 10 | /** 11 | * Project Name:Ban 12 | * Author:CoorChice 13 | * Date:2017/6/12 14 | * Notes: 15 | */ 16 | class WechatNewsModel : IWeChatNewsModel { 17 | 18 | override fun requestWechatNewsData(pno: Int, ps: Int, onResponseListener: OnResponseListener) { 19 | Net.getWechatNewsData(pno, ps, 20 | object:OnSuccessCallback{ 21 | override fun onSuccess(data: WechatNewsResponse?) { 22 | onResponseListener.onSuccess(data) 23 | } 24 | 25 | }, 26 | object :OnFailureCallback{ 27 | override fun onFailure(message: String?) { 28 | onResponseListener.onFailure(message) 29 | } 30 | 31 | } 32 | ) 33 | } 34 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/wechat/presenter/WechatNewsFragmentPresenter.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.wechat.presenter 2 | 3 | import com.coorchice.ban.model.base.IWechatNewsFragment 4 | import com.coorchice.ban.model.base.OnResponseListener 5 | import com.coorchice.ban.model.wechat.model.WechatNewsModel 6 | import com.coorchice.ban.network.DataModel.WechatNews 7 | import com.coorchice.ban.network.DataModel.WechatNewsResponse 8 | import com.coorchice.ban.utils.loge 9 | 10 | /** 11 | * Project Name:Ban 12 | * Author:CoorChice 13 | * Date:2017/6/12 14 | * Notes: 15 | */ 16 | class WechatNewsFragmentPresenter(var view: IWechatNewsFragment) { 17 | 18 | val wechatNewsModel = WechatNewsModel() 19 | val datas = mutableListOf() 20 | val ps: Int = 20 21 | var pno: Int = 0 22 | var total: Int = 1 23 | 24 | fun requestWechatNewsData(refresh: Boolean) { 25 | pno++ 26 | if (refresh) { 27 | pno = 1 28 | datas.clear() 29 | } 30 | if (pno <= total) { 31 | wechatNewsModel.requestWechatNewsData(pno, ps, 32 | object : OnResponseListener { 33 | override fun onSuccess(data: WechatNewsResponse?) { 34 | total = data?.totalPage as Int 35 | datas.addAll(data?.list) 36 | val newData = mutableListOf() 37 | newData.addAll(datas) 38 | view.updateWechatNewsData(newData) 39 | } 40 | 41 | override fun onFailure(message: String?) { 42 | loge(message ?: "无错误信息") 43 | view.onSpecialSituation(message) 44 | } 45 | }) 46 | } else { 47 | view.onSpecialSituation("没有了!") 48 | loge("没有了!") 49 | } 50 | } 51 | 52 | 53 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/wechat/view/fragment/WechatNewsFragment.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.wechat.view.fragment 2 | 3 | import android.graphics.Rect 4 | import android.os.Bundle 5 | import android.support.v7.widget.DefaultItemAnimator 6 | import android.support.v7.widget.LinearLayoutManager 7 | import android.support.v7.widget.RecyclerView 8 | import android.view.Gravity 9 | import android.view.View 10 | import android.view.ViewGroup 11 | import android.widget.ImageView 12 | import android.widget.TextView 13 | import com.coorchice.ban.R 14 | import com.coorchice.ban.model.base.BaseFragment 15 | import com.coorchice.ban.model.base.IWechatNewsFragment 16 | import com.coorchice.ban.model.wechat.adapter.WechatNewsListAdapter 17 | import com.coorchice.ban.model.wechat.presenter.WechatNewsFragmentPresenter 18 | import com.coorchice.ban.network.DataModel.WechatNews 19 | import com.coorchice.ban.utils.loge 20 | import com.coorchice.library.SuperTextView 21 | import com.github.nuptboyzhb.lib.SuperSwipeRefreshLayout 22 | import org.jetbrains.anko.dip 23 | import org.jetbrains.anko.find 24 | import org.jetbrains.anko.sp 25 | import org.jetbrains.anko.textColor 26 | 27 | /** 28 | * Project Name:Ban 29 | * Author:CoorChice 30 | * Date:2017/6/12 31 | * Notes: 32 | */ 33 | class WechatNewsFragment : BaseFragment(), IWechatNewsFragment { 34 | 35 | private var wechatNewsList: RecyclerView? = null 36 | private var layoutRefresh: SuperSwipeRefreshLayout? = null 37 | private var tvTitle: TextView? = null 38 | 39 | private var wechatNewsListAdapter: WechatNewsListAdapter? = null 40 | 41 | val presenter = WechatNewsFragmentPresenter(this) 42 | 43 | companion object { 44 | fun getInstance(): WechatNewsFragment { 45 | val bundle = Bundle() 46 | val fragment = WechatNewsFragment() 47 | fragment.arguments = bundle 48 | return fragment 49 | } 50 | } 51 | 52 | override fun getContentViewResId(): Int { 53 | return R.layout.fragment_wechat_news 54 | } 55 | 56 | override fun initData() { 57 | presenter.requestWechatNewsData(true) 58 | } 59 | 60 | override fun initView() { 61 | showEmpty(true) 62 | findView() 63 | initLayoutRefresh() 64 | initWechatNewsList() 65 | 66 | } 67 | 68 | private fun findView() { 69 | tvTitle = rootView?.find(R.id.tv_title) 70 | tvTitle?.text = resources.getString(R.string.btn_model_2) 71 | rootView?.find(R.id.btn_back)?.visibility = View.INVISIBLE 72 | layoutRefresh = rootView?.find(R.id.layout_refresh) 73 | wechatNewsList = rootView?.find(R.id.rv_wechat_news_list) 74 | } 75 | 76 | private fun initLayoutRefresh() { 77 | setLoadView() 78 | layoutRefresh?.setOnPullRefreshListener(object : SuperSwipeRefreshLayout.OnPullRefreshListener { 79 | override fun onPullEnable(p0: Boolean) { 80 | loge("refresh -> onPullEnable") 81 | } 82 | 83 | override fun onPullDistance(p0: Int) { 84 | loge("refresh -> onPullDistance") 85 | 86 | } 87 | 88 | override fun onRefresh() { 89 | loge("refresh -> onRefresh") 90 | presenter.requestWechatNewsData(true) 91 | } 92 | }) 93 | 94 | layoutRefresh?.setOnPushLoadMoreListener(object : SuperSwipeRefreshLayout.OnPushLoadMoreListener { 95 | override fun onPushDistance(p0: Int) { 96 | loge("loadmore -> onPushDistance") 97 | } 98 | 99 | override fun onPushEnable(p0: Boolean) { 100 | loge("loadmore -> onPushEnable") 101 | 102 | } 103 | 104 | override fun onLoadMore() { 105 | loge("loadmore -> onLoadMore") 106 | presenter.requestWechatNewsData(false) 107 | } 108 | 109 | }) 110 | 111 | } 112 | 113 | private fun setLoadView() { 114 | var refreshFooterView = SuperTextView(activity) 115 | refreshFooterView.gravity = Gravity.CENTER 116 | refreshFooterView.text = "奋力加载中..." 117 | refreshFooterView.textColor = resources.getColor(R.color.md_black_1000) 118 | refreshFooterView.textSize = 12f 119 | val lp = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) 120 | refreshFooterView.layoutParams = lp 121 | layoutRefresh?.setFooterView(refreshFooterView) 122 | } 123 | 124 | private fun initWechatNewsList() { 125 | wechatNewsList?.layoutManager = LinearLayoutManager(activity) 126 | wechatNewsList?.itemAnimator = DefaultItemAnimator() 127 | wechatNewsList?.addItemDecoration(object : RecyclerView.ItemDecoration() { 128 | override fun getItemOffsets(outRect: Rect?, view: View?, parent: RecyclerView?, state: RecyclerView.State?) { 129 | var position = parent?.layoutManager?.getPosition(view) 130 | if (position == parent?.adapter?.itemCount?.minus(1)) { 131 | outRect?.bottom = dip(16) 132 | } 133 | } 134 | }) 135 | wechatNewsListAdapter = WechatNewsListAdapter(activity, emptyList()) 136 | wechatNewsList?.adapter = wechatNewsListAdapter 137 | } 138 | 139 | override fun addListener() { 140 | tvTitle?.setOnClickListener{ 141 | wechatNewsList?.smoothScrollToPosition(0) 142 | } 143 | } 144 | 145 | override fun updateWechatNewsData(data: List?) { 146 | showEmpty(false) 147 | if (layoutRefresh?.isRefreshing == true) { 148 | layoutRefresh?.isRefreshing = false 149 | } 150 | layoutRefresh?.setLoadMore(false) 151 | wechatNewsListAdapter?.updateData(data) 152 | } 153 | 154 | override fun onSpecialSituation(message: String?) { 155 | if (layoutRefresh?.isRefreshing == true) { 156 | layoutRefresh?.isRefreshing = false 157 | } 158 | layoutRefresh?.setLoadMore(false) 159 | } 160 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/model/welcome/view/WelcomeActivity.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.model.welcome.view 2 | 3 | import android.os.CountDownTimer 4 | import android.view.View 5 | import android.view.WindowManager 6 | import android.view.animation.LinearInterpolator 7 | import com.coorchice.ban.R 8 | import com.coorchice.ban.model.base.BaseActivity 9 | import com.coorchice.ban.model.base.toMainActivity 10 | import com.coorchice.ban.utils.AppUtils 11 | import com.coorchice.ban.utils.alphaAnim 12 | import kotlinx.android.synthetic.main.activity_welcome.* 13 | 14 | class WelcomeActivity : BaseActivity() { 15 | 16 | var timer: CountDownTimer? = null 17 | 18 | override fun getContentViewResId() = R.layout.activity_welcome 19 | 20 | override fun initData() { 21 | timer = object : CountDownTimer(3000, 1000) { 22 | 23 | override fun onTick(millisUntilFinished: Long) { 24 | tv_count_down.text = "00:0${millisUntilFinished / 1000}" 25 | } 26 | 27 | override fun onFinish() { 28 | tv_count_down.visibility = View.GONE 29 | btn_enter.visibility = View.VISIBLE 30 | alphaAnim(btn_enter, 0.2f, 1f, 800, LinearInterpolator()).start() 31 | } 32 | }.start() 33 | } 34 | 35 | override fun initView() { 36 | window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN) 37 | tv_count_down.text = "00:03" 38 | sd_pic.setImageURI(AppUtils.getResUriString(R.drawable.welcome)) 39 | } 40 | 41 | override fun addListener() { 42 | btn_enter.setOnClickListener { 43 | toMainActivity(this) 44 | } 45 | } 46 | 47 | override fun onDestroy() { 48 | timer?.cancel() 49 | super.onDestroy() 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/network/ApiAvatardata.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.network 2 | 3 | import com.coorchice.ban.network.DataModel.ConstellationInfo 4 | import com.coorchice.ban.network.DataModel.JokePicture 5 | import com.coorchice.ban.network.DataModel.JokeWord 6 | import retrofit2.Call 7 | import retrofit2.http.GET 8 | import retrofit2.http.Query 9 | 10 | /** 11 | * Project Name:Ban 12 | * Author:CoorChice 13 | * Date:2017/6/10 14 | * Notes: 15 | */ 16 | interface ApiAvatardata { 17 | 18 | @GET("Joke/NewstJoke") 19 | abstract fun getJokeWordData(@Query("key") key: String, 20 | @Query("page") page: Int, 21 | @Query("rows") rows: Int): Call?>> 22 | 23 | @GET("Joke/NewstImg") 24 | abstract fun getJokePictureData(@Query("key") key: String, 25 | @Query("page") page: Int, 26 | @Query("rows") rows: Int): Call?>> 27 | 28 | 29 | @GET("Constellation/Query") 30 | abstract fun getConstellationInfo(@Query("key") key: String, 31 | @Query("consName") consName: String, 32 | @Query("type") type: String): Call> 33 | 34 | 35 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/network/ApiJuhe.java: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.network; 2 | 3 | import com.coorchice.ban.network.DataModel.NewsResponse; 4 | import com.coorchice.ban.network.DataModel.WechatNewsResponse; 5 | 6 | import retrofit2.Call; 7 | import retrofit2.http.GET; 8 | import retrofit2.http.Query; 9 | 10 | /** 11 | * Project Name:Ban 12 | * Author:CoorChice 13 | * Date:2017/6/10 14 | * Notes: 15 | */ 16 | 17 | public interface ApiJuhe { 18 | 19 | @GET("toutiao/index") 20 | Call> getNewsData(@Query("key") String key, 21 | @Query("type") String type); 22 | 23 | @GET("weixin/query") 24 | Call> getWechatNewsData(@Query("key") String key, 25 | @Query("pno") int pno, @Query("ps") int ps); 26 | 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/network/BaseResponse.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.network 2 | 3 | /** 4 | * Project Name:Ban 5 | * Author:CoorChice 6 | * Date:2017/6/10 7 | * Notes: 8 | */ 9 | class BaseResponse(var error_code: Int, var reason: String, var result: T?) 10 | 11 | class BaseResponse2(var error_code: Int, var reason: String, var result1: T?) -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/network/DataModel/ConstellationDataModel.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.network.DataModel 2 | 3 | /** 4 | * Project Name:Ban 5 | * Author:CoorChice 6 | * Date:2017/6/26 7 | * Notes: 8 | */ 9 | data class ConstellationInfo(var resultcode: String?, 10 | var errorCode: String?, 11 | var name: String?, 12 | var datetime: String?, 13 | var date: String?, 14 | var all: String?, 15 | var color: String?, 16 | var health: String?, 17 | var love: String?, 18 | var money: String?, 19 | var number: String?, 20 | var QFriend: String?, 21 | var summary: String?, 22 | var work: String?) -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/network/DataModel/JokeWordDataModel.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.network.DataModel 2 | 3 | /** 4 | * Project Name:Ban 5 | * Author:CoorChice 6 | * Date:2017/6/25 7 | * Notes: 8 | */ 9 | data class JokeWord(var content: String?, var hashId: String?, var unixtime: Long?, var updatetime: String?) 10 | 11 | data class JokePicture(var content: String?, var hashId: String?, var unixtime: Long?, var updatetime: String?, var url: String?) -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/network/DataModel/NewsDataModel.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.network.DataModel 2 | 3 | import java.io.Serializable 4 | 5 | /** 6 | * Project Name:Ban 7 | * Author:CoorChice 8 | * Date:2017/6/10 9 | * Notes: 10 | */ 11 | data class NewsResponse(var stat: String, var data: List) : Serializable 12 | 13 | /** 14 | * uniquekey : ac785f3e552174dcfd9e6f39d0e34851 15 | * title : “文化和自然遗产日”上的多彩活动 16 | * date : 2017-06-10 15:47 17 | * category : 头条 18 | * author_name : 新华社 19 | * url : http://mini.eastday.com/mobile/170610154749674.html 20 | * thumbnail_pic_s : http://01.imgmini.eastday.com/mobile/20170610/20170610154749_ba360d808776f31c89ddc6ef07a30f2c_3_mwpm_03200403.jpeg 21 | * thumbnail_pic_s02 : http://01.imgmini.eastday.com/mobile/20170610/20170610154749_08142394310026ce3403c923bdcbffa6_1_mwpm_03200403.jpeg 22 | * thumbnail_pic_s03 : http://01.imgmini.eastday.com/mobile/20170610/20170610154749_d59cbc2d5129e00c1292e1c5af7082bb_6_mwpm_03200403.jpeg 23 | */ 24 | 25 | data class News(var uniquekey: String, 26 | var title: String, 27 | var date: String, 28 | var category: String, 29 | var author_name: String, 30 | var url: String, 31 | var thumbnail_pic_s: String, 32 | var thumbnail_pic_s02: String, 33 | var thumbnail_pic_s03: String) : Serializable 34 | 35 | 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/network/DataModel/WechatNewsDataModel.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.network.DataModel 2 | 3 | /** 4 | * Project Name:Ban 5 | * Author:CoorChice 6 | * Date:2017/6/12 7 | * Notes: 8 | */ 9 | /* 10 | "list": [] 11 | "totalPage": 16, 12 | "ps": 20, 13 | "pno": 1 14 | */ 15 | data class WechatNewsResponse(var list: List, 16 | var totalPage : Int, 17 | var ps : Int, 18 | var pno : Int) 19 | /* 20 | { 21 | "id": "wechat_20150401071581", 22 | "title": "号外:集宁到乌兰花的班车出事了!!!!!", 23 | "source": "内蒙那点事儿", 24 | "firstImg": "http://zxpic.gtimg.com/infonew/0/wechat_pics_-214279.jpg/168", 25 | "mark": "", 26 | "url": "http://v.juhe.cn/weixin/redirect?wid=wechat_20150401071581" 27 | }*/ 28 | data class WechatNews(var id : String, 29 | var title : String, 30 | var source : String, 31 | var firstImg : String, 32 | var mark : String, 33 | var url : String) -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/network/Net.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.network 2 | 3 | import com.chenbing.oneweather.Utils.NetworkUtils 4 | import com.coorchice.ban.BanApplication 5 | import com.coorchice.ban.network.DataModel.* 6 | import com.coorchice.ban.utils.AppUtils 7 | import com.coorchice.ban.utils.loge 8 | import com.coorchice.ban.utils.logv 9 | import com.google.gson.Gson 10 | import okhttp3.Interceptor 11 | import okhttp3.OkHttpClient 12 | import okhttp3.Request 13 | import retrofit2.Call 14 | import retrofit2.Callback 15 | import retrofit2.Response 16 | import retrofit2.Retrofit 17 | import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory 18 | import retrofit2.converter.gson.GsonConverterFactory 19 | 20 | /** 21 | * Project Name:Ban 22 | * Author:CoorChice 23 | * Date:2017/6/10 24 | * Notes: 25 | */ 26 | 27 | object Net { 28 | val BASE_URL_AVATARDATA = "http://api.avatardata.cn/" 29 | val BASE_URL_JUHE = "http://v.juhe.cn/" 30 | 31 | val API_AVATARDATA = getRetrofit(BASE_URL_AVATARDATA).create(ApiAvatardata::class.java) 32 | val API_JUHE = getRetrofit(BASE_URL_JUHE).create(ApiJuhe::class.java) 33 | 34 | private fun getRetrofit(baseUrl: String): Retrofit { 35 | return Retrofit.Builder() 36 | .baseUrl(baseUrl) 37 | .client(getOkHttpClient()) 38 | .addConverterFactory(GsonConverterFactory.create(Gson())) 39 | .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) 40 | .build() 41 | } 42 | 43 | private fun getOkHttpClient(): OkHttpClient { 44 | val networkInterceptor = { chain: Interceptor.Chain -> 45 | chain.proceed( 46 | addRequestHeader( 47 | chain.request() 48 | ) 49 | ) 50 | } 51 | return OkHttpClient.Builder() 52 | .addNetworkInterceptor(networkInterceptor) 53 | .retryOnConnectionFailure(true) 54 | .build() 55 | } 56 | 57 | private fun addRequestHeader(request: Request): Request { 58 | val rq = request.newBuilder() 59 | val imei = AppUtils.getImei(BanApplication.appContext!!) 60 | if (imei != null) { 61 | rq.addHeader("imei", imei!!) 62 | logv("imei: " + imei!!) 63 | } 64 | 65 | val imsi = AppUtils.getImsi(BanApplication.appContext!!) 66 | if (imsi != null) { 67 | rq.addHeader("imsi", imsi!!) 68 | logv("imsi: " + imsi!!) 69 | } 70 | 71 | val networkType = NetworkUtils.getCurrentNetworkType(BanApplication.appContext!!) 72 | if (networkType != null) { 73 | rq.addHeader("net", networkType!!) 74 | loge("net: " + networkType!!) 75 | } 76 | 77 | val sdk = AppUtils.sdkVersion.toString() 78 | rq.addHeader("cv", sdk) 79 | loge("cv: " + sdk) 80 | 81 | val os = "Android" 82 | rq.addHeader("os", os) 83 | loge("os: " + os) 84 | 85 | val tc = AppUtils.channelName 86 | rq.addHeader("tc", tc) 87 | loge("tc: " + tc) 88 | 89 | val dt = AppUtils.modelVersion 90 | rq.addHeader("dt", dt) 91 | loge("dt: " + dt) 92 | return rq.build() 93 | } 94 | 95 | private fun request(call: Call>, 96 | onSuccessCallback: OnSuccessCallback, 97 | onFailureCallback: OnFailureCallback) { 98 | call.enqueue(object : Callback> { 99 | override fun onResponse(call: Call>?, response: Response>?) { 100 | onSuccessCallback.onSuccess(response?.body()?.result) 101 | } 102 | 103 | override fun onFailure(call: Call>?, t: Throwable?) { 104 | onFailureCallback.onFailure(t?.message) 105 | } 106 | }) 107 | } 108 | 109 | private fun request2(call: Call>, 110 | onSuccessCallback: OnSuccessCallback, 111 | onFailureCallback: OnFailureCallback) { 112 | call.enqueue(object : Callback> { 113 | override fun onResponse(call: Call>?, response: Response>?) { 114 | onSuccessCallback.onSuccess(response?.body()?.result1) 115 | } 116 | 117 | override fun onFailure(call: Call>?, t: Throwable?) { 118 | onFailureCallback.onFailure(t?.message) 119 | } 120 | }) 121 | } 122 | 123 | 124 | val KEY_NEWS_DATA = "ca8284abeb7ce27ef05965abad467ff9" 125 | fun getNewsData(type: String, 126 | onSuccessCallback: OnSuccessCallback, 127 | onFailureCallback: OnFailureCallback) { 128 | request(API_JUHE.getNewsData(KEY_NEWS_DATA, type), onSuccessCallback, onFailureCallback) 129 | } 130 | 131 | val KEY_WECHAT_NEWS_DATA = "4b162a0fe0809fd8f8bdc8a763e314b3" 132 | fun getWechatNewsData(pno: Int, 133 | ps: Int, 134 | onSuccessCallback: OnSuccessCallback, 135 | onFailureCallback: OnFailureCallback) { 136 | request(API_JUHE.getWechatNewsData(KEY_WECHAT_NEWS_DATA, pno, ps), onSuccessCallback, onFailureCallback) 137 | } 138 | 139 | val KEY_JOKE_DATA = "bdd5c63bdcd0479cb3c77c6a86743f73" 140 | fun getJokeWordData(page: Int, 141 | rows: Int, 142 | onSuccessCallback: OnSuccessCallback?>, 143 | onFailureCallback: OnFailureCallback?>) { 144 | request(API_AVATARDATA.getJokeWordData(KEY_JOKE_DATA, page, rows), onSuccessCallback, onFailureCallback) 145 | } 146 | fun getJokePictureData(page: Int, 147 | rows: Int, 148 | onSuccessCallback: OnSuccessCallback?>, 149 | onFailureCallback: OnFailureCallback?>) { 150 | request(API_AVATARDATA.getJokePictureData(KEY_JOKE_DATA, page, rows), onSuccessCallback, onFailureCallback) 151 | } 152 | 153 | val KEY_CONSTELLATION_DATA = "b8ac42a9e73e40d693dde39c3b32160a" 154 | fun getConstellationInfo(consName: String, 155 | type: String, 156 | onSuccessCallback: OnSuccessCallback, 157 | onFailureCallback: OnFailureCallback) { 158 | request2(API_AVATARDATA.getConstellationInfo(KEY_CONSTELLATION_DATA, consName, type), onSuccessCallback, onFailureCallback) 159 | } 160 | 161 | 162 | 163 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/network/ResponseCallback.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.network 2 | 3 | /** 4 | * Project Name:Ban 5 | * Author:CoorChice 6 | * Date:2017/6/10 7 | * Notes: 8 | */ 9 | interface OnSuccessCallback { 10 | fun onSuccess(data: T?) 11 | } 12 | 13 | interface OnFailureCallback { 14 | fun onFailure(message: String?) 15 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/utils/Animation.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.utils 2 | 3 | import android.animation.AnimatorSet 4 | import android.animation.ObjectAnimator 5 | import android.animation.TimeInterpolator 6 | import android.util.Property 7 | import android.view.View 8 | import android.view.animation.AccelerateDecelerateInterpolator 9 | import kotlinx.android.synthetic.main.fragment_constellation_detail_today.* 10 | 11 | /** 12 | * Project Name:Ban 13 | * Author:CoorChice 14 | * Date:2017/6/12 15 | * Notes: 16 | */ 17 | 18 | fun Pop(view: View) { 19 | val animatorSet = AnimatorSet() 20 | animatorSet.playSequentially(listOf( 21 | ScaleAnimation(view, 1.1f, 50, AccelerateDecelerateInterpolator()), 22 | ScaleAnimation(view, 1f, 50, AccelerateDecelerateInterpolator()), 23 | ScaleAnimation(view, 1.2f, 70, AccelerateDecelerateInterpolator()), 24 | ScaleAnimation(view, 0.85f, 50, AccelerateDecelerateInterpolator()), 25 | ScaleAnimation(view, 1f, 50, AccelerateDecelerateInterpolator()))) 26 | animatorSet.start() 27 | } 28 | 29 | fun ScaleAnimation(view: View?, scale: Float, duration: Long, interpolator: TimeInterpolator): AnimatorSet { 30 | val set = AnimatorSet() 31 | if (view != null){ 32 | var scaleX = ObjectAnimator.ofFloat(view, View.SCALE_X, scale) 33 | var scaleY = ObjectAnimator.ofFloat(view, View.SCALE_Y, scale) 34 | set.duration = duration 35 | set.interpolator = interpolator 36 | set.playTogether(scaleX, scaleY) 37 | } 38 | return set 39 | } 40 | 41 | fun ScaleAnimation(view: View?, scale: Float, duration: Long, interpolator: TimeInterpolator, repeat: Boolean): AnimatorSet { 42 | val set = AnimatorSet() 43 | if (view != null) { 44 | var scaleX = ObjectAnimator.ofFloat(view, View.SCALE_X, scale) 45 | var scaleY = ObjectAnimator.ofFloat(view, View.SCALE_Y, scale) 46 | if (repeat) { 47 | scaleX.repeatCount = -1 48 | scaleX.repeatMode = ObjectAnimator.REVERSE 49 | scaleY.repeatCount = -1 50 | scaleY.repeatMode = ObjectAnimator.REVERSE 51 | } 52 | set.duration = duration 53 | set.interpolator = interpolator 54 | set.playTogether(scaleX, scaleY) 55 | } 56 | return set 57 | } 58 | 59 | fun playScaleAnimation(view: View?, scale: Float, duration: Long, interpolator: TimeInterpolator): AnimatorSet { 60 | val set = AnimatorSet() 61 | if (view != null) { 62 | var scaleX = ObjectAnimator.ofFloat(view, View.SCALE_X, scale) 63 | var scaleY = ObjectAnimator.ofFloat(view, View.SCALE_Y, scale) 64 | set.duration = duration 65 | set.interpolator = interpolator 66 | set.playTogether(scaleX, scaleY) 67 | set.start() 68 | } 69 | return set 70 | } 71 | 72 | fun ScaleAnimation(view: View?, fromScale: Float, toScale: Float, duration: Long, interpolator: TimeInterpolator): AnimatorSet { 73 | val set = AnimatorSet() 74 | if (view != null) { 75 | var scaleX = ObjectAnimator.ofFloat(view, View.SCALE_X, fromScale, toScale) 76 | var scaleY = ObjectAnimator.ofFloat(view, View.SCALE_Y, fromScale, toScale) 77 | set.duration = duration 78 | set.interpolator = interpolator 79 | set.playTogether(scaleX, scaleY) 80 | } 81 | return set 82 | } 83 | 84 | 85 | fun floatJumpAnim(view: View?): AnimatorSet { 86 | val set = AnimatorSet() 87 | if (view != null) { 88 | var scaleX = ObjectAnimator.ofFloat(view, View.SCALE_X, 0.9f, 1.1f) 89 | scaleX.repeatMode = ObjectAnimator.REVERSE 90 | scaleX.repeatCount = -1 91 | var scaleY = ObjectAnimator.ofFloat(view, View.SCALE_Y, 0.9f, 1.1f) 92 | scaleY.repeatMode = ObjectAnimator.REVERSE 93 | scaleY.repeatCount = -1 94 | var alphaAnim = ObjectAnimator.ofFloat(view, View.ALPHA, 0.8f, 1f) 95 | alphaAnim.repeatMode = ObjectAnimator.REVERSE 96 | alphaAnim.repeatCount = -1 97 | set.duration = 2 * 1000 98 | set.interpolator = AccelerateDecelerateInterpolator() 99 | set.playTogether(scaleX, scaleY, alphaAnim) 100 | set.start() 101 | } 102 | return set 103 | } 104 | 105 | fun rotateAnim(view: View?, from: Float, to: Float, duration: Long, interpolator: TimeInterpolator, repeat: Boolean): AnimatorSet { 106 | val set = AnimatorSet() 107 | if (view != null) { 108 | var anim = ObjectAnimator.ofFloat(view, View.ROTATION, from, to) 109 | if (repeat) { 110 | anim.repeatMode = ObjectAnimator.RESTART 111 | anim.repeatCount = -1 112 | } 113 | set.duration = duration 114 | set.interpolator = interpolator 115 | set.playTogether(anim) 116 | set.start() 117 | } 118 | return set 119 | } 120 | 121 | fun alphaAnim(view: View?, from: Float, to: Float, duration: Long, interpolator: TimeInterpolator): AnimatorSet { 122 | val set = AnimatorSet() 123 | if (view != null) { 124 | var alphaAnim = ObjectAnimator.ofFloat(view, View.ALPHA, from, to) 125 | set.duration = duration 126 | set.interpolator = interpolator 127 | set.play(alphaAnim) 128 | } 129 | return set 130 | } 131 | 132 | fun translationYAnim(view: View?, from: Float, to: Float, duration: Long, interpolator: TimeInterpolator, repeat: Boolean): AnimatorSet { 133 | val set = AnimatorSet() 134 | if (view != null) { 135 | var translationAnim = ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, from, to) 136 | if (repeat) { 137 | translationAnim.repeatMode = ObjectAnimator.REVERSE 138 | translationAnim.repeatCount = -1 139 | } 140 | set.duration = duration 141 | set.interpolator = interpolator 142 | set.play(translationAnim) 143 | } 144 | return set 145 | } 146 | 147 | fun playTranslationYAnim(view: View?, from: Float, to: Float, duration: Long, interpolator: TimeInterpolator, repeat: Boolean): AnimatorSet { 148 | var translationYAnim = translationYAnim(view, from, to, duration, interpolator, repeat) 149 | translationYAnim.start() 150 | return translationYAnim 151 | } 152 | 153 | fun translationXAnim(view: View?, from: Float, to: Float, duration: Long, interpolator: TimeInterpolator, repeat: Boolean): AnimatorSet { 154 | val set = AnimatorSet() 155 | if (view != null) { 156 | var translationAnim = ObjectAnimator.ofFloat(view, View.TRANSLATION_X, from, to) 157 | if (repeat) { 158 | translationAnim.repeatMode = ObjectAnimator.REVERSE 159 | translationAnim.repeatCount = -1 160 | } 161 | set.duration = duration 162 | set.interpolator = interpolator 163 | set.play(translationAnim) 164 | } 165 | return set 166 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/utils/CrashHandler.kt: -------------------------------------------------------------------------------- 1 | package com.chenbing.oneweather.Utils 2 | 3 | import java.io.BufferedWriter 4 | import java.io.File 5 | import java.io.FileWriter 6 | import java.io.IOException 7 | import java.io.PrintWriter 8 | import java.lang.Thread.UncaughtExceptionHandler 9 | import java.text.SimpleDateFormat 10 | 11 | import android.content.Context 12 | import android.content.pm.PackageInfo 13 | import android.content.pm.PackageManager 14 | import android.os.Build 15 | import android.os.Process 16 | 17 | /** 18 | * Project Name:IceWeather 19 | * Author:IceChen 20 | * Date:2016/11/9 21 | * Notes: 22 | */ 23 | 24 | class CrashHandler 25 | /** 26 | * 防止被重复创建 27 | */ 28 | private constructor() : UncaughtExceptionHandler { 29 | private var mDefualtCrashHandler: UncaughtExceptionHandler? = null 30 | private var mContext: Context? = null 31 | 32 | fun init(context: Context) { 33 | mContext = context.applicationContext // 确保获得的是系统级的Context 34 | mDefualtCrashHandler = Thread.getDefaultUncaughtExceptionHandler() // 获取系统默认的异常处理器 35 | Thread.setDefaultUncaughtExceptionHandler(this) // 把当前实例设置为系统默认异常处理器 36 | } 37 | 38 | 39 | /** 40 | * 这个方法是我们重写的重点,当系统出现未捕获异常时,就会调用这个方法 41 | 42 | * @param t 出现未捕获异常的线程 43 | * * 44 | * @param e 未捕获的异常 45 | */ 46 | override fun uncaughtException(t: Thread, e: Throwable) { 47 | try { 48 | saveExceptionToFile(e) 49 | } catch (ex: Exception) { 50 | ex.printStackTrace() 51 | } 52 | 53 | if (mDefualtCrashHandler != null) { 54 | //如果系统有默认异常处理就使用它处理 55 | mDefualtCrashHandler!!.uncaughtException(t, e) 56 | } else { 57 | //否则我们自行结束程序 58 | Process.killProcess(Process.myPid()) 59 | } 60 | 61 | 62 | } 63 | 64 | @Throws(IOException::class) 65 | private fun saveExceptionToFile(e: Throwable) { 66 | if (FileUtil.ExistSDCard()) { 67 | val currentTime = System.currentTimeMillis() 68 | val crashTime = SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(currentTime) 69 | val file = File(FileUtil.appCrashDir + "crash" + crashTime + ".txt") 70 | file.createNewFile() 71 | try { 72 | val pw = PrintWriter(BufferedWriter(FileWriter(file))) 73 | pw.println(crashTime) 74 | printPhoneInfo(pw) 75 | pw.println() 76 | e.printStackTrace(pw) //输出错误信息 77 | pw.close() 78 | } catch (ex: Exception) { 79 | ex.printStackTrace() 80 | } 81 | 82 | } 83 | } 84 | 85 | /** 86 | * 输出手机信息 87 | */ 88 | @Throws(PackageManager.NameNotFoundException::class) 89 | private fun printPhoneInfo(pw: PrintWriter) { 90 | val pm = mContext!!.packageManager 91 | val pi = pm.getPackageInfo(mContext!!.packageName, PackageManager.GET_ACTIVITIES) 92 | pw.print("App version: ") 93 | pw.print(pi.versionName) 94 | pw.print("_") 95 | pw.println(pi.versionCode) 96 | 97 | //android版本号 98 | pw.print("OS Version: ") 99 | pw.print(Build.VERSION.RELEASE) 100 | pw.print("_") 101 | pw.println(Build.VERSION.SDK_INT) 102 | 103 | //制造商 104 | pw.print("Vendor: ") 105 | pw.println(Build.MANUFACTURER) 106 | 107 | //手机型号 108 | pw.print("Model: ") 109 | pw.println(Build.MODEL) 110 | 111 | //cpu架构 112 | pw.print("CPU ABI: ") 113 | pw.println(Build.CPU_ABI) 114 | } 115 | 116 | companion object { 117 | 118 | val instance = CrashHandler() 119 | } 120 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/utils/DateUtils.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.utils 2 | 3 | import java.text.SimpleDateFormat 4 | import java.util.* 5 | 6 | /** 7 | * Project Name:Ban 8 | * Author:CoorChice 9 | * Date:2017/6/27 10 | * Notes: 11 | */ 12 | fun getWeekOfDate(date: Date): String { 13 | val weekDays = arrayOf("星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六") 14 | val cal = Calendar.getInstance() 15 | cal.time = date 16 | var w = cal.get(Calendar.DAY_OF_WEEK) - 1 17 | if (w < 0) w = 0 18 | return weekDays[w] 19 | } 20 | 21 | fun getWeekOfCurrent(): String { 22 | return getWeekOfDate(Date()) 23 | } 24 | 25 | fun formatDate(date: Date, format: String): String { 26 | return SimpleDateFormat(format).format(date) 27 | } 28 | 29 | fun formatCurrentDate(format: String): String { 30 | return SimpleDateFormat(format).format(Date()) 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/utils/FileUtil.kt: -------------------------------------------------------------------------------- 1 | package com.chenbing.oneweather.Utils 2 | 3 | import java.io.File 4 | import java.io.FileInputStream 5 | import java.io.FileNotFoundException 6 | import java.io.FileOutputStream 7 | import java.io.IOException 8 | import java.io.ObjectInputStream 9 | import java.io.ObjectOutputStream 10 | import java.text.SimpleDateFormat 11 | import java.util.Date 12 | 13 | import android.os.Environment 14 | import com.coorchice.ban.utils.loge 15 | 16 | /** 17 | * Project Name:AnimDveDemo 18 | * Author:IceChen 19 | * Date:16/8/24 20 | * Notes: 21 | */ 22 | object FileUtil { 23 | private val APP_FILE_DIR = GetSDCard() + "/OneWeather/" 24 | private val APP_CACHE_DIR = APP_FILE_DIR + "cache/" 25 | private val APP_PHOTO_DIR = APP_FILE_DIR + "photo/" 26 | private val APP_OBJECT_DIR = APP_CACHE_DIR + "object/" 27 | private val APP_CRASH_DIR = APP_FILE_DIR + "crash/" 28 | 29 | fun GetAppFileDir(): String { 30 | val file = File(APP_FILE_DIR) 31 | if (!file.exists()) { 32 | file.mkdirs() 33 | } 34 | return APP_FILE_DIR 35 | } 36 | 37 | fun GetAppCacheDir(): String { 38 | val file = File(APP_CACHE_DIR) 39 | if (!file.exists()) { 40 | file.mkdirs() 41 | } 42 | return APP_CACHE_DIR 43 | } 44 | 45 | fun GetAppPhotoDir(): String { 46 | val file = File(APP_PHOTO_DIR) 47 | if (!file.exists()) { 48 | file.mkdirs() 49 | } 50 | return APP_PHOTO_DIR 51 | } 52 | 53 | fun GetAppObjectDir(): String { 54 | val file = File(APP_OBJECT_DIR) 55 | if (!file.exists()) { 56 | file.mkdirs() 57 | } 58 | return APP_OBJECT_DIR 59 | } 60 | 61 | val appCrashDir: String 62 | get() { 63 | val file = File(APP_OBJECT_DIR) 64 | if (!file.exists()) { 65 | file.mkdirs() 66 | } 67 | return APP_CRASH_DIR 68 | } 69 | 70 | fun SaveObject(path: String, `object`: Any) { 71 | var fos: FileOutputStream? = null 72 | var oos: ObjectOutputStream? = null 73 | val file = File(path) 74 | try { 75 | loge(file.absolutePath) 76 | fos = FileOutputStream(file) 77 | oos = ObjectOutputStream(fos) 78 | oos.writeObject(`object`) 79 | } catch (e: IOException) { 80 | e.printStackTrace() 81 | } finally { 82 | try { 83 | if (oos != null) { 84 | oos.close() 85 | } 86 | if (fos != null) { 87 | fos.close() 88 | } 89 | } catch (e: IOException) { 90 | e.printStackTrace() 91 | } 92 | 93 | } 94 | } 95 | 96 | @Throws(FileNotFoundException::class) 97 | fun RestoreObject(path: String, clazz: Class): T? { 98 | var fis: FileInputStream? = null 99 | var ois: ObjectInputStream? = null 100 | var t: T? = null 101 | val file = File(path) 102 | if (!file.exists()) { 103 | throw FileNotFoundException("请求文件不存在,请检查路径是否正确。") 104 | } 105 | try { 106 | loge(file.absolutePath) 107 | fis = FileInputStream(file) 108 | ois = ObjectInputStream(fis) 109 | t = ois.readObject() as T 110 | } catch (e: ClassNotFoundException) { 111 | e.printStackTrace() 112 | } catch (e: IOException) { 113 | e.printStackTrace() 114 | } finally { 115 | try { 116 | if (ois != null) { 117 | ois.close() 118 | } 119 | if (fis != null) { 120 | fis.close() 121 | } 122 | } catch (e: IOException) { 123 | e.printStackTrace() 124 | } 125 | 126 | return t 127 | } 128 | } 129 | 130 | fun ScanDirectory(path: String): String { 131 | val file = File(path) 132 | val files = file.listFiles() 133 | val filesName = StringBuffer() 134 | val format = "index:%d\nfileName:%s\nfileSize:%s\n最后修改时间:%s\n--------------\n" 135 | var count = 0 136 | val dateFormat = SimpleDateFormat("yyyy/MM/dd hh:mm:ss") 137 | for (tempFile in files) { 138 | count++ 139 | if (tempFile.isFile) { 140 | val fileLength = tempFile.length() 141 | val fileSize: String 142 | if (fileLength >= 1024) { 143 | fileSize = ((fileLength / 1024).toString() + "K").toString() 144 | } else 145 | fileSize = (fileLength.toString() + "B").toString() 146 | 147 | val lastModify = tempFile.lastModified() 148 | val lastModifyString = dateFormat.format(Date(lastModify)) 149 | 150 | filesName.append(String.format(format, count, tempFile.name, fileSize, 151 | lastModifyString)) 152 | } 153 | } 154 | filesName.append(String.format("共计文件数:%d\n", count)) 155 | return filesName.toString() 156 | } 157 | 158 | 159 | fun ExistSDCard(): Boolean { 160 | return Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED || !Environment.isExternalStorageRemovable() 161 | } 162 | 163 | /** 164 | * 尝试获取SDCard的路径 165 | 166 | * @return 如果SDCard存在返回其路径,如果不存在返回"" 167 | */ 168 | fun GetSDCard(): String { 169 | if (ExistSDCard()) { 170 | return Environment.getExternalStorageDirectory().absolutePath 171 | } else { 172 | return "" 173 | } 174 | } 175 | 176 | 177 | } 178 | -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/utils/LogUtil.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.utils 2 | 3 | import android.util.Log 4 | import com.coorchice.ban.BuildConfig 5 | 6 | /** 7 | * Project Name:Ban 8 | * Author:CoorChice 9 | * Date:2017/6/10 10 | * Notes: 11 | */ 12 | val allow = BuildConfig.DEBUG 13 | 14 | private fun getLogPrefix(): String { 15 | val stackTraceElement = Thread.currentThread().stackTrace[4] 16 | var className = stackTraceElement.className 17 | className = className.substring(className.lastIndexOf(".") + 1) 18 | return "$className.${stackTraceElement.methodName}(L:${stackTraceElement.lineNumber})" 19 | } 20 | 21 | fun logv(content: String) { 22 | if (allow) Log.v(getLogPrefix(), content) 23 | } 24 | 25 | fun logi(content: String) { 26 | if (allow) Log.i(getLogPrefix(), content) 27 | } 28 | 29 | fun logw(content: String) { 30 | if (allow) Log.w(getLogPrefix(), content) 31 | } 32 | 33 | fun loge(content: String) { 34 | if (allow) Log.e(getLogPrefix(), content) 35 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/utils/SpCacher.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.utils 2 | 3 | import android.content.Context 4 | import android.content.SharedPreferences 5 | import com.coorchice.ban.BanApplication 6 | import com.coorchice.ban.model.constellation.entry.Constellation 7 | 8 | /** 9 | * Project Name:Ban 10 | * Author:CoorChice 11 | * Date:2017/6/29 12 | * Notes: 13 | */ 14 | object SpCacher { 15 | 16 | val SP_NAME = "sp_cache" 17 | val KEY_CONSTELLATION = "key_constellation" 18 | 19 | private var sp: SharedPreferences? = null 20 | 21 | init { 22 | if (sp == null) { 23 | sp = BanApplication.appContext?.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE) 24 | } 25 | } 26 | 27 | fun saveConstellation(data: Constellation) { 28 | val editor = sp?.edit() 29 | editor?.putString(KEY_CONSTELLATION, data.name) 30 | editor?.apply() 31 | } 32 | 33 | fun getConstellation(): Constellation? { 34 | var constellation = sp?.getString(KEY_CONSTELLATION, null) 35 | if (constellation != null) { 36 | return Constellation.valueOf(constellation) 37 | } else { 38 | return null 39 | } 40 | } 41 | 42 | 43 | } -------------------------------------------------------------------------------- /app/src/main/java/com/coorchice/ban/utils/ViewExtension.kt: -------------------------------------------------------------------------------- 1 | package com.coorchice.ban.utils 2 | 3 | import android.animation.AnimatorSet 4 | import android.animation.ObjectAnimator 5 | import android.view.View 6 | 7 | /** 8 | * Project Name:Ban 9 | * Author:CoorChice 10 | * Date:2017/7/3 11 | * Notes: 12 | */ 13 | fun View.setLocation(newX: Float, newY: Float) { 14 | val set = AnimatorSet() 15 | val xAnim = ObjectAnimator.ofFloat(this, View.X, x, newX) 16 | val yAnim = ObjectAnimator.ofFloat(this, View.Y, y, newY) 17 | set.playTogether(xAnim, yAnim) 18 | set.duration = 0 19 | set.start() 20 | } 21 | 22 | fun View.setLocationSmooth(newX: Float, newY: Float, smoothDuration: Long) { 23 | val set = AnimatorSet() 24 | val xAnim = ObjectAnimator.ofFloat(this, View.X, x, newX) 25 | val yAnim = ObjectAnimator.ofFloat(this, View.Y, y, newY) 26 | set.playTogether(xAnim, yAnim) 27 | set.duration = smoothDuration 28 | set.start() 29 | } 30 | 31 | fun View.offsetXY(offsetX: Float, offsetY: Float) { 32 | setLocation(x + offsetX, y + offsetY) 33 | } 34 | 35 | fun View.offsetXYSmooth(offsetX: Float, offsetY: Float, smoothDuration: Long) { 36 | setLocationSmooth(x + offsetX, y + offsetY, smoothDuration) 37 | } 38 | 39 | val View.locationX: Float 40 | get() { 41 | val location = IntArray(2) 42 | getLocationInWindow(location) 43 | return location[0].toFloat() 44 | } 45 | 46 | val View.locationY: Float 47 | get() { 48 | val location = IntArray(2) 49 | getLocationInWindow(location) 50 | return location[1].toFloat() 51 | } 52 | 53 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/app_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable-hdpi/app_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/app_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable-xhdpi/app_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/coorchice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable-xhdpi/coorchice.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/app_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable-xxhdpi/app_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/app_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable-xxxhdpi/app_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/aquarius.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/aquarius.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/aquarius_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/aquarius_bg.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/aries.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/aries.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/aries_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/aries_bg.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/back.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/cancer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/cancer.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/cancer_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/cancer_bg.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/capricorn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/capricorn.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/capricorn_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/capricorn_bg.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/color_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/color_12.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/constellation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/constellation.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/constellation_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/constellation_bg.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/constellation_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/constellation_select.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/curiosity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/curiosity.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/dream.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/dream.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/dream_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/dream_select.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/entertainment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/entertainment.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/gemini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/gemini.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/gemini_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/gemini_bg.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/inland.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/inland.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/international.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/international.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/joke.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/joke.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/joke_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/joke_select.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/libra.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/libra.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/libra_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/libra_bg.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/like0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/like0.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/like1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/like1.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/lion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/lion.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/lion_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/lion_bg.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/news.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/news.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/news_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/news_select.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/no_data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/no_data.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/pe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/pe.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/pisces.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/pisces.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/pisces_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/pisces_bg.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/progress_bar_all.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 11 | 12 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 23 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/progress_bar_health.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 11 | 12 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 23 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/progress_bar_love.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 11 | 12 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 23 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/progress_bar_money.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 11 | 12 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 23 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/progress_bar_work.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 11 | 12 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 23 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/sagittarius.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/sagittarius.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/sagittarius_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/sagittarius_bg.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/scorpio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/scorpio.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/scorpio_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/scorpio_bg.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/select_constellation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/select_constellation.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/taurus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/taurus.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/taurus_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/taurus_bg.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/technology.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/technology.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/test.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/test.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/virgo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/virgo.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/virgo_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/virgo_bg.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/wechat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/wechat.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wechat_left.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/wechat_left.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wechat_right.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/wechat_right.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wechat_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/wechat_select.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/welcome.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/app/src/main/res/drawable/welcome.jpg -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 16 | 17 | 24 | 25 | 36 | 37 | 55 | 56 | 74 | 75 | 93 | 94 | 112 | 113 | 131 | 132 | 133 | 134 | 135 | 142 | 143 | 144 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_web.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_welcome.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 17 | 18 | 36 | 37 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_base.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_constellation.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | 11 | 14 | 15 | 21 | 22 | 29 | 30 | 35 | 36 | 43 | 44 | 51 | 52 | 57 | 58 | 68 | 69 | 81 | 82 | 100 | 101 | 102 | 103 | 104 | 115 | 116 | 117 | 118 | 124 | 125 | 126 | 127 | 132 | 133 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_joke.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 12 | 13 | 19 | 20 | 35 | 36 | 52 | 53 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_joke_picture.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 16 | 17 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_joke_word.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 16 | 17 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_news.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 15 | 25 | 26 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_news_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_wechat_news.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 18 | 19 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_view_joke_picture_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | 26 | 27 | 34 | 35 | 43 | 44 | 53 | 54 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_view_joke_word_list_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_view_joke_word_list_right.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_view_news_list_more_pic.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 23 | 24 | 35 | 36 | 45 | 46 | 55 | 56 | 64 | 65 | 66 | 77 | 78 | 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_view_news_list_single_pic.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 26 | 27 | 40 | 41 | 49 | 50 | 61 | 62 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_view_news_navigator_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 20 | 21 | 30 | 31 | 40 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_view_wechat_news_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 17 | 18 | 24 | 25 | 33 | 34 | 43 | 44 | 59 | 60 | 61 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_empty.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 16 | 17 | 25 | 26 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_header_bar.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 20 | 21 | 36 | 37 | 48 | 49 | 56 | -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_week_constellation.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 19 | 20 | 33 | 34 | 43 | 44 | 57 | 58 | 67 | 68 | 81 | 82 | 92 | 93 | 106 | 107 | 116 | 117 | 129 | 130 | -------------------------------------------------------------------------------- /app/src/main/res/layout/line_0_3_grey_50.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 16dp 7 | 8dp 8 | 4dp 9 | 2dp 10 | 11 | 12 | 24sp 13 | 15sp 14 | 20sp 15 | 18sp 16 | 13sp 17 | 12sp 18 | 16dp 19 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 新闻头条 4 | 微信精选 5 | 轻松一刻 6 | 星座运势 7 | 梦境解析 8 | 9 | 10 | 综合运势 11 | 爱情运势 12 | 事业运势 13 | 财富运势 14 | 健康运势 15 | 幸运颜色 16 | 幸运数字 17 | 速配星座 18 | 暂无数据,点击刷新 19 | WelcomeActivity 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 |