├── .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 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/copyright/CoorChiceCopyright.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
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 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | 
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 | 
77 |
78 |
79 |
80 | ## 微信精选
81 | 每日微信精选文章让你看到微信中不一样的世界。
82 |
83 | 
84 |
85 | ## 轻松一刻
86 | 随身的图文笑话,让你走到哪都是最有幽默感的那一个。
87 |
88 | 
89 |
90 | ## 星座运势
91 | 让你每天都可以了解自己的星座动态。
92 |
93 | 
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 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext.kotlin_version = '1.1.2-4'
5 | repositories {
6 | maven { url 'https://maven.google.com' }
7 | jcenter()
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.0.0-alpha3'
11 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
12 |
13 | // NOTE: Do not place your application dependencies here; they belong
14 | // in the individual module build.gradle files
15 | }
16 | }
17 |
18 | allprojects {
19 | repositories {
20 | jcenter()
21 | // maven { url 'https://maven.google.com' }
22 | mavenCentral()
23 | maven { url 'https://jitpack.io' }
24 | maven {
25 | url "http://dl.bintray.com/nuptboyzhb/maven"
26 | }
27 | }
28 | }
29 |
30 | task clean(type: Delete) {
31 | delete rootProject.buildDir
32 | }
33 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenBingX/Ban/866ed352249d6fbe32fad882d220ceaf4a12095c/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 09 11:47:00 CST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.0-milestone-1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------