├── .gitignore
├── LICENSE
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
├── release
│ └── WanAndroid.apk
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── githubly
│ │ └── wanandroid
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── assets
│ │ ├── chapters
│ │ ├── projects
│ │ └── web
│ │ │ └── about.html
│ ├── java
│ │ └── com
│ │ │ └── githubly
│ │ │ └── wanandroid
│ │ │ ├── App.kt
│ │ │ ├── MainActivity.kt
│ │ │ ├── activity
│ │ │ ├── CollectListActivity.kt
│ │ │ ├── LoginActivity.kt
│ │ │ ├── SplashActivity.kt
│ │ │ ├── WebActivity.kt
│ │ │ └── base
│ │ │ │ └── BaseActivity.kt
│ │ │ ├── adapter
│ │ │ ├── HomeAdapter.kt
│ │ │ ├── HomeViewPagerAdapter.kt
│ │ │ ├── ProjectArticleAdapter.kt
│ │ │ └── WXArticleAdapter.kt
│ │ │ ├── contract
│ │ │ ├── IArticlePageContract.kt
│ │ │ ├── ICollectListContract.kt
│ │ │ ├── IContentContract.kt
│ │ │ ├── IHomeContract.kt
│ │ │ ├── ILoginContract.kt
│ │ │ ├── ILogoutContract.kt
│ │ │ └── IProjectPageContract.kt
│ │ │ ├── fragment
│ │ │ ├── ArticleFragment.kt
│ │ │ ├── ArticlePageFragment.kt
│ │ │ ├── HomeFragment.kt
│ │ │ ├── MyFragment.kt
│ │ │ ├── ProjectFragment.kt
│ │ │ ├── ProjectPageFragment.kt
│ │ │ └── base
│ │ │ │ └── BaseFragment.kt
│ │ │ ├── model
│ │ │ ├── ArticleItem.kt
│ │ │ ├── Banner.kt
│ │ │ ├── BaseListData.kt
│ │ │ ├── BaseResult.kt
│ │ │ ├── Chapter.kt
│ │ │ └── User.kt
│ │ │ ├── net
│ │ │ ├── ApiCallBack.kt
│ │ │ ├── ApiHelper.kt
│ │ │ ├── ApiService.kt
│ │ │ ├── ReadCookiesInterceptor.kt
│ │ │ └── SaveCookiesInterceptor.kt
│ │ │ ├── presenter
│ │ │ ├── ArticlePagePresenter.kt
│ │ │ ├── CollectListPresenter.kt
│ │ │ ├── ContentPresenter.kt
│ │ │ ├── HomePresenter.kt
│ │ │ ├── LoginPresenter.kt
│ │ │ ├── LogoutPresenter.kt
│ │ │ ├── ProjectPagePresenter.kt
│ │ │ └── base
│ │ │ │ ├── BasePresenter.kt
│ │ │ │ └── IView.kt
│ │ │ ├── utils
│ │ │ ├── AppUtils.kt
│ │ │ ├── BuglyFileProvider.kt
│ │ │ ├── ContentUtil.kt
│ │ │ ├── DialogUtil.kt
│ │ │ ├── FileUtils.kt
│ │ │ ├── UserInfoHelper.kt
│ │ │ └── ViewUtil.kt
│ │ │ └── widget
│ │ │ ├── HackyViewPager.kt
│ │ │ ├── LoadingStateView.kt
│ │ │ ├── OtherBottomDialog.kt
│ │ │ └── ScrollTextView.kt
│ └── res
│ │ ├── color
│ │ ├── color_main_page_bottom_tab.xml
│ │ └── selector_back.xml
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ ├── color_cursor.xml
│ │ ├── ic_launcher_background.xml
│ │ ├── line_et_bg.xml
│ │ ├── line_et_focus.xml
│ │ ├── line_et_normal.xml
│ │ ├── progress_horizontal.xml
│ │ ├── selector_banner_point.xml
│ │ ├── selector_tab_article.xml
│ │ ├── selector_tab_category.xml
│ │ ├── selector_tab_home.xml
│ │ ├── selector_tab_my.xml
│ │ ├── shape_head_blue.xml
│ │ ├── shape_head_green.xml
│ │ ├── shape_head_orange.xml
│ │ ├── shape_head_red.xml
│ │ ├── shape_login_btn.xml
│ │ ├── shape_other_dialog.xml
│ │ ├── shape_other_item.xml
│ │ ├── shape_project_collect.xml
│ │ ├── shape_round_3dp_ebebeb.xml
│ │ ├── shape_update_bg.xml
│ │ ├── shape_user_head.xml
│ │ └── splash.xml
│ │ ├── font
│ │ └── font_title.ttf
│ │ ├── layout
│ │ ├── activity_collect_list.xml
│ │ ├── activity_login.xml
│ │ ├── activity_main.xml
│ │ ├── activity_splash.xml
│ │ ├── activity_web.xml
│ │ ├── dialog_other_bottom.xml
│ │ ├── fragment_article.xml
│ │ ├── fragment_article_page.xml
│ │ ├── fragment_home.xml
│ │ ├── fragment_my.xml
│ │ ├── fragment_project.xml
│ │ ├── fragment_project_page.xml
│ │ ├── item_home_article.xml
│ │ ├── item_project.xml
│ │ ├── item_wx_article.xml
│ │ ├── layout_home_banner.xml
│ │ ├── layout_login.xml
│ │ ├── layout_page_state.xml
│ │ ├── upgrade_dialog.xml
│ │ └── upgrade_tips_dialog.xml
│ │ ├── mipmap-xhdpi
│ │ ├── ic_about.png
│ │ ├── ic_android.png
│ │ ├── ic_arrow.png
│ │ ├── ic_back_def.png
│ │ ├── ic_banner_point.png
│ │ ├── ic_banner_point_selected.png
│ │ ├── ic_browser.png
│ │ ├── ic_clear.png
│ │ ├── ic_close.png
│ │ ├── ic_collect.png
│ │ ├── ic_collect_tag.png
│ │ ├── ic_copy_url.png
│ │ ├── ic_empty.png
│ │ ├── ic_empty_banner.png
│ │ ├── ic_head_default.png
│ │ ├── ic_heart.png
│ │ ├── ic_knowledge_system.png
│ │ ├── ic_launcher.png
│ │ ├── ic_login_bg.jpg
│ │ ├── ic_other.png
│ │ ├── ic_search_article.png
│ │ ├── ic_share.png
│ │ ├── ic_tag.png
│ │ ├── ic_todo.png
│ │ └── ic_update.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_article.png
│ │ ├── ic_article_fill.png
│ │ ├── ic_category.png
│ │ ├── ic_category_fill.png
│ │ ├── ic_home.png
│ │ ├── ic_home_fill.png
│ │ ├── ic_launcher.png
│ │ ├── ic_me.png
│ │ └── ic_me_fill.png
│ │ └── values
│ │ ├── attrs.xml
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── githubly
│ └── wanandroid
│ └── ExampleUnitTest.kt
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── screenshot
├── 1.png
├── 10.png
├── 11.png
├── 12.jpg
├── 2.png
├── 3.png
├── 4.png
├── 5.png
├── 6.png
├── 7.png
├── 8.png
├── 9.png
└── QRCode.png
├── settings.gradle
└── wanAndroid.jks
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches/build_file_checksums.ser
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | .DS_Store
9 | /build
10 | /captures
11 | .externalNativeBuild
12 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | apply plugin: 'kotlin-android'
4 |
5 | apply plugin: 'kotlin-android-extensions'
6 |
7 | apply plugin: 'kotlin-kapt'
8 |
9 | android {
10 | compileSdkVersion 28
11 | defaultConfig {
12 | applicationId "com.githubly.wanandroid"
13 | minSdkVersion 21
14 | targetSdkVersion 28
15 | versionCode 5
16 | versionName "1.0.1.0"
17 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
18 | ndk {
19 | //设置支持的SO库架构
20 | abiFilters 'armeabi' //, 'x86', 'armeabi-v7a', 'x86_64', 'arm64-v8a'
21 | }
22 | }
23 | signingConfigs {
24 | wanAndroid {
25 | keyAlias ALIAS_NAME
26 | keyPassword ALIAS_PWD
27 | storeFile file(KEY_PATH)
28 | storePassword KEY_PWD
29 | v2SigningEnabled false
30 | }
31 | }
32 | buildTypes {
33 | release {
34 | minifyEnabled true
35 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
36 | zipAlignEnabled true
37 | debuggable false
38 | signingConfig signingConfigs.wanAndroid
39 | // 移除无用的resource文件
40 | shrinkResources true
41 | buildConfigField("String", "Environment", "\"online\"")
42 | buildConfigField("String", "BuglyID", BUGLY_ID)
43 | }
44 |
45 | debug {
46 | minifyEnabled false
47 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
48 | debuggable true
49 | signingConfig signingConfigs.wanAndroid
50 | // 移除无用的resource文件
51 | shrinkResources false
52 | buildConfigField("String", "Environment", "\"test\"")
53 | buildConfigField("String", "BuglyID", BUGLY_ID)
54 | }
55 |
56 | applicationVariants.all { variant ->
57 | variant.outputs.all { output ->
58 | def fileName
59 | fileName = "WanAndroid_${variant.versionName}.apk"
60 | output.outputFileName = fileName
61 | }
62 | }
63 | }
64 | }
65 |
66 | dependencies {
67 | implementation fileTree(include: ['*.jar'], dir: 'libs')
68 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
69 | implementation "org.jetbrains.anko:anko:$anko_version"
70 | implementation 'com.android.support:appcompat-v7:28.0.0'
71 | implementation 'com.android.support.constraint:constraint-layout:1.1.3'
72 | implementation 'com.android.support:support-v4:28.0.0'
73 | testImplementation 'junit:junit:4.12'
74 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
75 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
76 | implementation 'com.squareup.retrofit2:retrofit:2.3.0'
77 | implementation 'com.squareup.okhttp3:okhttp:3.10.0'
78 | implementation 'com.squareup.okio:okio:1.14.0'
79 | implementation 'com.google.code.gson:gson:2.8.5'
80 | implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
81 | implementation 'com.squareup.okhttp3:logging-interceptor:3.9.0'
82 | implementation 'com.gyf.barlibrary:barlibrary:2.3.0'
83 | implementation 'cn.bingoogolapple:bga-swipebacklayout:1.1.9@aar'
84 | implementation 'cn.bingoogolapple:bga-banner:2.2.4@aar'
85 | implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.34'
86 | implementation 'com.android.support:design:28.0.0'
87 | implementation 'com.github.bumptech.glide:glide:4.8.0'
88 | implementation 'com.yqritc:recyclerview-flexibledivider:1.4.0'
89 | implementation 'com.flyco.tablayout:FlycoTabLayout_Lib:2.1.2@aar'
90 | implementation 'de.hdodenhof:circleimageview:2.2.0'
91 | implementation 'org.greenrobot:eventbus:3.1.1'
92 | implementation 'com.yanzhenjie:loading:1.0.2'
93 | implementation 'com.tencent.bugly:crashreport_upgrade:1.3.4'
94 | implementation 'com.tencent.bugly:nativecrashreport:3.3.1'
95 | implementation('com.github.hotchemi:permissionsdispatcher:3.3.1') { exclude module: 'support-v13' }
96 | kapt 'com.github.hotchemi:permissionsdispatcher-processor:3.3.1'
97 | }
98 | kotlin {
99 | experimental {
100 | coroutines 'enable'
101 | }
102 | }
--------------------------------------------------------------------------------
/app/release/WanAndroid.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/release/WanAndroid.apk
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/githubly/wanandroid/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid
2 |
3 | import android.support.test.InstrumentationRegistry
4 | import android.support.test.runner.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getTargetContext()
22 | assertEquals("com.githubly.wanandroid", appContext.packageName)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
35 |
38 |
41 |
44 |
48 |
49 |
55 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/app/src/main/assets/chapters:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "children": [],
4 | "courseId": 13,
5 | "id": 408,
6 | "name": "鸿洋",
7 | "order": 190000,
8 | "parentChapterId": 407,
9 | "userControlSetTop": false,
10 | "visible": 1
11 | },
12 | {
13 | "children": [],
14 | "courseId": 13,
15 | "id": 409,
16 | "name": "郭霖",
17 | "order": 190001,
18 | "parentChapterId": 407,
19 | "userControlSetTop": false,
20 | "visible": 1
21 | },
22 | {
23 | "children": [],
24 | "courseId": 13,
25 | "id": 410,
26 | "name": "玉刚说",
27 | "order": 190002,
28 | "parentChapterId": 407,
29 | "userControlSetTop": false,
30 | "visible": 1
31 | },
32 | {
33 | "children": [],
34 | "courseId": 13,
35 | "id": 411,
36 | "name": "承香墨影",
37 | "order": 190003,
38 | "parentChapterId": 407,
39 | "userControlSetTop": false,
40 | "visible": 1
41 | },
42 | {
43 | "children": [],
44 | "courseId": 13,
45 | "id": 413,
46 | "name": "Android群英传",
47 | "order": 190004,
48 | "parentChapterId": 407,
49 | "userControlSetTop": false,
50 | "visible": 1
51 | },
52 | {
53 | "children": [],
54 | "courseId": 13,
55 | "id": 414,
56 | "name": "code小生",
57 | "order": 190005,
58 | "parentChapterId": 407,
59 | "userControlSetTop": false,
60 | "visible": 1
61 | },
62 | {
63 | "children": [],
64 | "courseId": 13,
65 | "id": 415,
66 | "name": "谷歌开发者",
67 | "order": 190006,
68 | "parentChapterId": 407,
69 | "userControlSetTop": false,
70 | "visible": 1
71 | },
72 | {
73 | "children": [],
74 | "courseId": 13,
75 | "id": 416,
76 | "name": "奇卓社",
77 | "order": 190007,
78 | "parentChapterId": 407,
79 | "userControlSetTop": false,
80 | "visible": 1
81 | },
82 | {
83 | "children": [],
84 | "courseId": 13,
85 | "id": 417,
86 | "name": "美团技术团队",
87 | "order": 190008,
88 | "parentChapterId": 407,
89 | "userControlSetTop": false,
90 | "visible": 1
91 | }
92 | ]
--------------------------------------------------------------------------------
/app/src/main/assets/web/about.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 | 关于WanAndroid
8 |
9 |
34 |
35 |
36 |
37 |
38 |
39 |
网站内容
40 |
本网站每天新增20~30篇优质文章,并加入到现有分类中,力求整理出一份优质而又详尽的知识体系,闲暇时间不妨上来学习下知识;
41 | 除此以外,并为大家提供平时开发过程中常用的工具以及常用的网址导航。
42 |
当然这只是我们目前的功能,未来我们将提供更多更加便捷的功能...
43 |
如果您有任何好的建议:
44 |
45 | - —关于网站排版
46 | - —关于新增常用网址以及工具
47 | - —未来你希望增加的功能等
48 |
49 |
可以在 hongyangAndroid/xueandroid 项目中以issue的形式提出,我将及时跟进。
50 |
51 |
如果您希望长期关注本站,可以加入我们的QQ群:591683946
52 |
关于网站作者
53 |
我是鸿洋,长期在CSDN上编写高质量的博客:
54 | blog.csdn.net/lmj623565791
55 | 并维护着一个微信公众号[hongyangAndroid],欢迎关注一下表示对我的支持:
56 |
"每天早晨7点30分,为你推荐优秀技术博文,提升从上班路上的闲暇时间开始~"
57 |
关于本App
58 |
这是基于鸿洋大神开放的Api做的练手App
59 | https://github.com/leiyun1993/WanAndroid
60 | 非常高兴能再这里遇到你,希望能给个Star支持一下,如果愿意帮忙试用,也希望能在github中以issue提出你的宝贵意见和建议,谢谢~
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/App.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid
2 |
3 | import android.app.Application
4 | import cn.bingoogolapple.swipebacklayout.BGASwipeBackHelper
5 | import com.githubly.wanandroid.model.User
6 | import com.githubly.wanandroid.utils.UserInfoHelper
7 | import com.tencent.bugly.Bugly
8 | import com.tencent.bugly.beta.Beta
9 | import kotlin.properties.Delegates
10 |
11 | /**
12 | * 类名:App
13 | * 作者:Yun.Lei
14 | * 功能:
15 | * 创建日期:2018-10-19 10:05
16 | * 修改人:
17 | * 修改时间:
18 | * 修改备注:
19 | */
20 | class App : Application() {
21 |
22 | companion object {
23 | var instance: App by Delegates.notNull() //实例用它
24 | var mAppContext: Application by Delegates.notNull() //applicationContext用它
25 | }
26 |
27 | var user: User? = null
28 | set(value) {
29 | field = value
30 | if (value != null) {
31 | UserInfoHelper.saveUser(value)
32 | } else {
33 | UserInfoHelper.clearUser()
34 | }
35 | }
36 | get() {
37 | if (field == null)
38 | field = UserInfoHelper.getUser()
39 | return field
40 | }
41 |
42 | var isLogin: Boolean = false
43 | get() {
44 | field = user != null
45 | return field
46 | }
47 |
48 | override fun onCreate() {
49 | super.onCreate()
50 | instance = this
51 | mAppContext = this
52 | UserInfoHelper.init(this)
53 | BGASwipeBackHelper.init(this, null)
54 | initUpdate()
55 | }
56 |
57 | private fun initUpdate() {
58 | Beta.enableHotfix = false
59 | Beta.enableNotification = true
60 | Beta.autoCheckUpgrade = true
61 | Beta.largeIconId = R.mipmap.ic_launcher
62 | Beta.smallIconId = R.mipmap.ic_launcher
63 | Beta.upgradeDialogLayoutId = R.layout.upgrade_dialog
64 | Beta.tipsDialogLayoutId = R.layout.upgrade_tips_dialog
65 | Beta.canShowUpgradeActs.add(MainActivity::class.java)
66 | Bugly.init(applicationContext, BuildConfig.BuglyID, BuildConfig.DEBUG)
67 | }
68 |
69 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid
2 |
3 | import android.support.v4.app.Fragment
4 | import android.support.v4.view.ViewPager
5 | import android.view.View
6 | import com.githubly.wanandroid.activity.base.BaseActivity
7 | import com.githubly.wanandroid.adapter.HomeViewPagerAdapter
8 | import com.githubly.wanandroid.fragment.ArticleFragment
9 | import com.githubly.wanandroid.fragment.HomeFragment
10 | import com.githubly.wanandroid.fragment.MyFragment
11 | import com.githubly.wanandroid.fragment.ProjectFragment
12 | import com.githubly.wanandroid.presenter.base.BasePresenter
13 | import kotlinx.android.synthetic.main.activity_main.*
14 | import org.jetbrains.anko.toast
15 |
16 | /**
17 | * MainActivity
18 | */
19 | class MainActivity : BaseActivity>(), View.OnClickListener, ViewPager.OnPageChangeListener {
20 | private val fragments = mutableListOf()
21 | private var bottomViews = mutableListOf()
22 | override val inflateId: Int
23 | get() = R.layout.activity_main
24 |
25 |
26 | override fun initView() {
27 | fragments.add(HomeFragment())
28 | fragments.add(ArticleFragment())
29 | fragments.add(ProjectFragment())
30 | fragments.add(MyFragment())
31 |
32 | homeViewPager.adapter = HomeViewPagerAdapter(fragments, supportFragmentManager)
33 | homeViewPager.offscreenPageLimit = 4
34 | homeViewPager.addOnPageChangeListener(this)
35 | bottomViews.add(rl_home)
36 | bottomViews.add(rl_article)
37 | bottomViews.add(rl_category)
38 | bottomViews.add(rl_my)
39 |
40 | for (view in bottomViews) {
41 | view.setOnClickListener(this)
42 | }
43 | setBottomBarSelect(0)
44 | }
45 |
46 | override fun initData() {
47 |
48 | }
49 |
50 | override fun initPresenter(): BasePresenter<*>? = null
51 |
52 | override fun isSupportSwipeBack(): Boolean {
53 | return false
54 | }
55 |
56 | override fun onClick(v: View?) {
57 | for (bottomView in bottomViews) {
58 | if (v == bottomView) {
59 | homeViewPager.setCurrentItem(bottomViews.indexOf(bottomView), false)
60 | setBottomBarSelect(bottomViews.indexOf(bottomView))
61 | }
62 | }
63 | }
64 |
65 | private fun setBottomBarSelect(index: Int) {
66 | for (view in bottomViews) {
67 | view.isSelected = false
68 | }
69 | bottomViews[index].isSelected = true
70 | }
71 |
72 | override fun onPageScrollStateChanged(p0: Int) {
73 |
74 | }
75 |
76 | override fun onPageScrolled(p0: Int, p1: Float, p2: Int) {
77 | }
78 |
79 | override fun onPageSelected(p0: Int) {
80 | setBottomBarSelect(p0)
81 | }
82 |
83 | private var lastClickTime = 0L
84 | override fun onBackPressed() {
85 | val currentTimeMillis = System.currentTimeMillis()
86 | if (currentTimeMillis - lastClickTime > 3000) {
87 | toast("再点就退出了...")
88 | lastClickTime = currentTimeMillis
89 | } else {
90 | super.onBackPressed()
91 | }
92 | }
93 |
94 | }
95 |
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/activity/CollectListActivity.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.activity
2 |
3 | import android.app.Activity
4 | import android.support.v7.widget.LinearLayoutManager
5 | import com.githubly.wanandroid.R
6 | import com.githubly.wanandroid.activity.base.BaseActivity
7 | import com.githubly.wanandroid.adapter.HomeAdapter
8 | import com.githubly.wanandroid.contract.ICollectListContract
9 | import com.githubly.wanandroid.model.ArticleItem
10 | import com.githubly.wanandroid.model.BaseListData
11 | import com.githubly.wanandroid.model.EventRemoveCollectPageArticle
12 | import com.githubly.wanandroid.presenter.CollectListPresenter
13 | import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration
14 | import kotlinx.android.synthetic.main.activity_collect_list.*
15 | import org.greenrobot.eventbus.EventBus
16 | import org.greenrobot.eventbus.Subscribe
17 | import org.greenrobot.eventbus.ThreadMode
18 | import org.jetbrains.anko.act
19 | import org.jetbrains.anko.dip
20 | import org.jetbrains.anko.startActivity
21 | import org.jetbrains.anko.toast
22 |
23 | /**
24 | * CollectListActivity
25 | */
26 | class CollectListActivity : BaseActivity(), ICollectListContract.View {
27 |
28 | companion object {
29 | fun active(act: Activity) {
30 | act.startActivity()
31 | }
32 | }
33 |
34 | private var page = 1
35 | private val mAdapter by lazy { HomeAdapter() }
36 | override val inflateId: Int
37 | get() = R.layout.activity_collect_list
38 |
39 | override fun initView() {
40 | EventBus.getDefault().register(this)
41 | btnBack.setOnClickListener { onBackPressed() }
42 | recyclerView.adapter = mAdapter
43 | recyclerView.layoutManager = LinearLayoutManager(this)
44 | recyclerView.addItemDecoration(
45 | HorizontalDividerItemDecoration.Builder(this).color(act.resources.getColor(R.color.backgroundColor)).size(
46 | dip(8)
47 | ).build()
48 | )
49 | mAdapter.setOnLoadMoreListener({
50 | page++
51 | mPresenter?.getCollectList(page)
52 | }, recyclerView)
53 | mAdapter.setPreLoadNumber(2)
54 | refreshLayout.setOnRefreshListener {
55 | initData()
56 | }
57 | mAdapter.emptyView = mLoadingStateView
58 | mAdapter.setOnItemClickListener { _, _, position ->
59 | mAdapter.data[position]?.apply {
60 | WebActivity.active(act, link, id, author, title, true, if (originId > 0) originId else -1)
61 | }
62 | }
63 | }
64 |
65 | override fun initData() {
66 | mLoadingStateView.loading()
67 | page = 1
68 | mPresenter?.getCollectList(page)
69 | }
70 |
71 | override fun initPresenter(): CollectListPresenter? = CollectListPresenter(this)
72 |
73 | override fun onListSuccess(data: BaseListData) {
74 | if (data.curPage == 1) {
75 | mAdapter.setNewData(data.datas)
76 | refreshLayout.isRefreshing = false
77 | } else {
78 | mAdapter.addData(data.datas)
79 | mAdapter.loadMoreComplete()
80 | }
81 | page = data.curPage
82 | if (data.over) {
83 | mAdapter.loadMoreEnd()
84 | }
85 | mAdapter.setEnableLoadMore(!data.over)
86 | mLoadingStateView.success()
87 | }
88 |
89 | override fun onListFailed(msg: String) {
90 | if (page == 1) {
91 | mAdapter.setNewData(mutableListOf())
92 | mLoadingStateView.failed(msg)
93 | refreshLayout.isRefreshing = false
94 | } else {
95 | toast(msg)
96 | mAdapter.loadMoreComplete()
97 | }
98 | }
99 |
100 | @Subscribe(threadMode = ThreadMode.MAIN)
101 | fun onEventCollectRemove(event: EventRemoveCollectPageArticle) {
102 | val id = event.id
103 | val item = mAdapter.data.find { it.id == id }
104 | if (item != null) {
105 | val index = mAdapter.data.indexOf(item)
106 | mAdapter.remove(index)
107 | if (mAdapter.data.size <= 0) {
108 | mLoadingStateView.failed("暂无收藏数据!")
109 | }
110 | }
111 | }
112 |
113 | override fun onDestroy() {
114 | super.onDestroy()
115 | EventBus.getDefault().unregister(this)
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/activity/LoginActivity.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.activity
2 |
3 | import android.app.Activity
4 | import android.view.View
5 | import com.githubly.wanandroid.App
6 | import com.githubly.wanandroid.R
7 | import com.githubly.wanandroid.activity.base.BaseActivity
8 | import com.githubly.wanandroid.contract.ILoginContract
9 | import com.githubly.wanandroid.model.User
10 | import com.githubly.wanandroid.presenter.LoginPresenter
11 | import com.githubly.wanandroid.utils.hideSoftInput
12 | import kotlinx.android.synthetic.main.activity_login.*
13 | import kotlinx.android.synthetic.main.layout_login.*
14 | import org.greenrobot.eventbus.EventBus
15 | import org.jetbrains.anko.startActivity
16 | import org.jetbrains.anko.toast
17 |
18 | /**
19 | * LoginActivity
20 | */
21 | class LoginActivity : BaseActivity(), ILoginContract.View {
22 |
23 |
24 | companion object {
25 | fun active(act: Activity) {
26 | act.startActivity()
27 | }
28 | }
29 |
30 | private var isSelectLogin: Boolean = true
31 |
32 | override val inflateId: Int
33 | get() = R.layout.activity_login
34 |
35 | override fun initView() {
36 | btnBack.setOnClickListener {
37 | onBackPressed()
38 | }
39 | loginTag.setColorFilter(resources.getColor(R.color.black_1))
40 | registerTag.setColorFilter(resources.getColor(R.color.black_1))
41 | loginBtn.setOnClickListener {
42 | showLoginOrRegister(true)
43 | }
44 | registerBtn.setOnClickListener {
45 | showLoginOrRegister(false)
46 | }
47 | btnGoLogin.setOnClickListener {
48 | login()
49 | }
50 | btnGoRegister.setOnClickListener {
51 | register()
52 | }
53 | }
54 |
55 | override fun initData() {
56 |
57 | }
58 |
59 | override fun initPresenter(): LoginPresenter? = LoginPresenter(this)
60 |
61 | private fun login() {
62 | val userName = loginNameTV.text.toString()
63 | val password = loginPasswordTv.text.toString()
64 | if (userName.isBlank()) {
65 | toast("请输入用户名")
66 | return
67 | }
68 | if (password.isBlank()) {
69 | toast("请输入密码")
70 | return
71 | }
72 | hideSoftInput()
73 | showLoading()
74 | mPresenter?.login(userName, password)
75 | }
76 |
77 | private fun register() {
78 | val userName = registerNameTv.text.toString()
79 | val password = registerPwdTv.text.toString()
80 | val rePassword = registerRePwdTv.text.toString()
81 | if (userName.isBlank()) {
82 | toast("请输入用户名")
83 | return
84 | }
85 | if (password.isBlank()) {
86 | toast("请输入密码")
87 | return
88 | }
89 | if (rePassword.isBlank()) {
90 | toast("请输入密码")
91 | return
92 | }
93 | if (password != rePassword) {
94 | toast("密码不一致,请确认")
95 | return
96 | }
97 | hideSoftInput()
98 | showLoading()
99 | mPresenter?.register(userName, password, rePassword)
100 | }
101 |
102 | private fun showLoginOrRegister(isLogin: Boolean) {
103 | isSelectLogin = isLogin
104 | loginTag.visibility = if (isLogin) View.VISIBLE else View.INVISIBLE
105 | registerTag.visibility = if (!isLogin) View.VISIBLE else View.INVISIBLE
106 | loginLayout.visibility = if (isLogin) View.VISIBLE else View.INVISIBLE
107 | registerLayout.visibility = if (!isLogin) View.VISIBLE else View.INVISIBLE
108 | }
109 |
110 | override fun onLoginSuccess(user: User) {
111 | dismissLoading()
112 | App.instance.user = user
113 | EventBus.getDefault().post(user)
114 | finish()
115 | }
116 |
117 | override fun onLoginFailed(msg: String) {
118 | dismissLoading()
119 | toast(msg)
120 | }
121 |
122 | override fun onRegisterSuccess(user: User) {
123 | dismissLoading()
124 | toast("注册并成功登录")
125 | App.instance.user = user
126 | EventBus.getDefault().post(user)
127 | finish()
128 | }
129 |
130 | override fun onRegisterFailed(msg: String) {
131 | dismissLoading()
132 | toast(msg)
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/activity/SplashActivity.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.activity
2 |
3 | import android.Manifest
4 | import android.annotation.SuppressLint
5 | import android.content.Intent
6 | import android.support.v7.app.AlertDialog
7 | import com.githubly.wanandroid.MainActivity
8 | import com.githubly.wanandroid.R
9 | import com.githubly.wanandroid.activity.base.BaseActivity
10 | import com.githubly.wanandroid.presenter.base.BasePresenter
11 | import com.githubly.wanandroid.utils.AppUtils
12 | import com.githubly.wanandroid.utils.toAppDetail
13 | import com.gyf.barlibrary.ImmersionBar
14 | import kotlinx.android.synthetic.main.activity_splash.*
15 | import org.jetbrains.anko.startActivity
16 | import permissions.dispatcher.NeedsPermission
17 | import permissions.dispatcher.OnNeverAskAgain
18 | import permissions.dispatcher.OnPermissionDenied
19 | import permissions.dispatcher.RuntimePermissions
20 |
21 | /**
22 | * SplashActivity
23 | */
24 | @RuntimePermissions
25 | class SplashActivity : BaseActivity>() {
26 |
27 | override val inflateId: Int
28 | get() = R.layout.activity_splash
29 |
30 | override fun setStatusBar() {
31 | mBaseImmersionBar = ImmersionBar.with(this)
32 | mBaseImmersionBar?.apply {
33 | statusBarColor(R.color.transparent)
34 | statusBarDarkFont(true, 0.2f)
35 | init()
36 | }
37 | }
38 |
39 | @SuppressLint("SetTextI18n")
40 | override fun initView() {
41 | versionTv.text = "v${AppUtils.getVersionName(this)}"
42 | }
43 |
44 |
45 | override fun initData() {
46 | goMainWithPermissionCheck()
47 | }
48 |
49 | @NeedsPermission(
50 | Manifest.permission.READ_EXTERNAL_STORAGE,
51 | Manifest.permission.WRITE_EXTERNAL_STORAGE
52 | )
53 | fun goMain() {
54 | versionTv.postDelayed({
55 | startActivity()
56 | finish()
57 | }, 1000)
58 | }
59 |
60 | override fun initPresenter(): BasePresenter<*>? = null
61 |
62 | @OnPermissionDenied(
63 | Manifest.permission.READ_EXTERNAL_STORAGE,
64 | Manifest.permission.WRITE_EXTERNAL_STORAGE
65 | )
66 | fun permissionDenied() {
67 | showPermissionDeniedDialog()
68 | }
69 |
70 | @OnNeverAskAgain(
71 | Manifest.permission.READ_EXTERNAL_STORAGE,
72 | Manifest.permission.WRITE_EXTERNAL_STORAGE
73 | )
74 | fun neverAskAgain() {
75 | showPermissionDeniedDialog()
76 | }
77 |
78 | private fun showPermissionDeniedDialog() {
79 | AlertDialog.Builder(this).apply {
80 | setTitle("温馨提示")
81 | setMessage("你拒绝了权限请求,会影响应用更新等功能的正常使用!")
82 | setPositiveButton("去设置") { _, _ ->
83 | toAppDetail(0x99)
84 | dismissLoading()
85 | }
86 | setNegativeButton("取消") { _, _ ->
87 | goMain()
88 | dismissLoading()
89 | }
90 | setCancelable(false)
91 | setFinishOnTouchOutside(false)
92 | }.create().show()
93 | }
94 |
95 | override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) {
96 | super.onRequestPermissionsResult(requestCode, permissions, grantResults)
97 | onRequestPermissionsResult(requestCode, grantResults)
98 | }
99 |
100 | override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
101 | super.onActivityResult(requestCode, resultCode, data)
102 | if (requestCode == 99) {
103 | goMain()
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/activity/base/BaseActivity.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.activity.base
2 |
3 | import android.os.Bundle
4 | import android.support.v7.app.AppCompatActivity
5 | import cn.bingoogolapple.swipebacklayout.BGASwipeBackHelper
6 | import com.githubly.wanandroid.R
7 | import com.githubly.wanandroid.presenter.base.BasePresenter
8 | import com.githubly.wanandroid.utils.ILoading
9 | import com.githubly.wanandroid.widget.LoadingStateView
10 | import com.gyf.barlibrary.ImmersionBar
11 | import com.yanzhenjie.loading.dialog.LoadingDialog
12 |
13 | /**
14 | * 类名:BaseActivity
15 | * 作者:Yun.Lei
16 | * 功能:
17 | * 创建日期:2018-10-18 19:11
18 | * 修改人:
19 | * 修改时间:
20 | * 修改备注:
21 | */
22 | abstract class BaseActivity> : AppCompatActivity(), BGASwipeBackHelper.Delegate, ILoading {
23 |
24 | protected var mBaseImmersionBar: ImmersionBar? = null
25 | protected var mSwipeBackHelper: BGASwipeBackHelper? = null
26 | /**
27 | * 当前页面需要加载的layoutId,等价setContentView
28 | */
29 | abstract val inflateId: Int
30 |
31 | /**
32 | * 初始化视图操作在这里执行,执行时机为onCreate之后
33 | */
34 | abstract fun initView(): Unit
35 |
36 | /**
37 | * 数据初始化在这里执行,执行时机为initView之后
38 | */
39 | abstract fun initData(): Unit
40 |
41 | //kotlin 懒加载,在第一次使用Presenter时初始化,这种设计是针对一个View只针对一个Presenter。
42 | //多个Presenter的情况此处不应该使用泛型
43 | protected val mPresenter: P? by lazy { initPresenter() }
44 |
45 | abstract fun initPresenter(): P?
46 |
47 | private val mWaitDialog by lazy { LoadingDialog(this) }
48 |
49 | protected val mLoadingStateView by lazy { LoadingStateView(this) }
50 |
51 | override fun onCreate(savedInstanceState: Bundle?) {
52 | initSwipeBackFinish()
53 | super.onCreate(savedInstanceState)
54 | setContentView(inflateId)
55 | initView()
56 | initData()
57 | setStatusBar()
58 | }
59 |
60 | open fun setStatusBar() {
61 | mBaseImmersionBar = ImmersionBar.with(this)
62 | mBaseImmersionBar?.apply {
63 | statusBarColor(R.color.white)
64 | fitsSystemWindows(true)
65 | statusBarDarkFont(true, 0.2f)
66 | keyboardEnable(true)
67 | init()
68 | }
69 | }
70 |
71 | private fun initSwipeBackFinish() {
72 | mSwipeBackHelper = BGASwipeBackHelper(this, this)
73 | }
74 |
75 | override fun onSwipeBackLayoutExecuted() {
76 | mSwipeBackHelper?.swipeBackward()
77 | }
78 |
79 | override fun onSwipeBackLayoutSlide(slideOffset: Float) {
80 | }
81 |
82 | override fun onSwipeBackLayoutCancel() {
83 | }
84 |
85 | override fun isSupportSwipeBack(): Boolean = true
86 |
87 | override fun onBackPressed() {
88 | if (mSwipeBackHelper?.isSliding == true) {
89 | return
90 | }
91 | super.onBackPressed()
92 | }
93 |
94 | override fun onDestroy() {
95 | super.onDestroy()
96 | mBaseImmersionBar?.destroy()
97 | dismissLoading()
98 | }
99 |
100 | override fun showLoading(msg: String) {
101 | mWaitDialog.setMessage(msg)
102 | mWaitDialog.setCancelable(false)
103 | mWaitDialog.setCanceledOnTouchOutside(false)
104 | if (!mWaitDialog.isShowing) {
105 | mWaitDialog.show()
106 | }
107 | }
108 |
109 | override fun dismissLoading() {
110 | if (mWaitDialog.isShowing) {
111 | mWaitDialog.dismiss()
112 | }
113 | }
114 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/adapter/HomeAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.adapter
2 |
3 | import com.chad.library.adapter.base.BaseQuickAdapter
4 | import com.chad.library.adapter.base.BaseViewHolder
5 | import com.githubly.wanandroid.R
6 | import com.githubly.wanandroid.model.ArticleItem
7 | import kotlinx.android.synthetic.main.item_home_article.view.*
8 | import java.util.*
9 |
10 | /**
11 | * 类名:HomeAdapter
12 | * 作者:Yun.Lei
13 | * 功能:
14 | * 创建日期:2018-10-19 11:11
15 | * 修改人:
16 | * 修改时间:
17 | * 修改备注:
18 | */
19 | class HomeAdapter : BaseQuickAdapter(R.layout.item_home_article) {
20 |
21 | private val colorRess = mutableListOf(
22 | R.drawable.shape_head_red,
23 | R.drawable.shape_head_blue,
24 | R.drawable.shape_head_orange,
25 | R.drawable.shape_head_green)
26 |
27 | override fun convert(helper: BaseViewHolder?, item: ArticleItem?) {
28 | val itemView = helper?.itemView
29 | itemView?.apply {
30 | item?.let {
31 | nameHeadTV.text = getStrFirstChat(it.author)
32 | nameHeadTV.setBackgroundResource(getRandomColor())
33 | nameTv.text = it.author
34 | titleTv.text = it.title
35 | descTv.text = if (it.desc.isNullOrBlank()) {
36 | it.link
37 | } else {
38 | it.desc
39 | }
40 | timeTv.text = it.niceDate
41 | typeTv.text = getType(it)
42 | heartIV.setColorFilter(context.resources.getColor(if (it.collect) {
43 | R.color.red
44 | } else {
45 | R.color.gray_1
46 | }))
47 | }
48 | }
49 | }
50 |
51 | private fun getType(item: ArticleItem): String {
52 | return if (item.superChapterName.isNullOrBlank()) {
53 | item.chapterName
54 | } else {
55 | "${item.chapterName} / ${item.superChapterName}"
56 | }
57 | }
58 |
59 | private fun getRandomColor(): Int {
60 | val index = Random().nextInt(4)
61 | return colorRess[index]
62 | }
63 |
64 | private fun getStrFirstChat(str: String): String {
65 | return str.substring(0, 1)
66 | }
67 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/adapter/HomeViewPagerAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.adapter
2 |
3 | import android.support.v4.app.Fragment
4 | import android.support.v4.app.FragmentManager
5 | import android.support.v4.app.FragmentPagerAdapter
6 |
7 | /**
8 | * 类名:HomeViewPagerAdapter
9 | * 作者:Yun.Lei
10 | * 功能:
11 | * 创建日期:2017-10-17 15:05
12 | * 修改人:
13 | * 修改时间:
14 | * 修改备注:
15 | */
16 | class HomeViewPagerAdapter(private val fragments: MutableList, fm: FragmentManager) : FragmentPagerAdapter(fm) {
17 | override fun getItem(position: Int): Fragment = fragments[position]
18 |
19 | override fun getCount(): Int = fragments.size
20 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/adapter/ProjectArticleAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.adapter
2 |
3 | import android.view.View
4 | import com.chad.library.adapter.base.BaseQuickAdapter
5 | import com.chad.library.adapter.base.BaseViewHolder
6 | import com.githubly.wanandroid.R
7 | import com.githubly.wanandroid.model.ArticleItem
8 | import com.githubly.wanandroid.utils.loadImage
9 | import kotlinx.android.synthetic.main.item_project.view.*
10 |
11 | /**
12 | * 类名:ProjectArticleAdapter
13 | * 作者:Yun.Lei
14 | * 功能:
15 | * 创建日期:2018-10-19 11:11
16 | * 修改人:
17 | * 修改时间:
18 | * 修改备注:
19 | */
20 | class ProjectArticleAdapter : BaseQuickAdapter(R.layout.item_project) {
21 |
22 | private val colorRess = mutableListOf(
23 | R.drawable.shape_head_red,
24 | R.drawable.shape_head_blue,
25 | R.drawable.shape_head_orange,
26 | R.drawable.shape_head_green)
27 |
28 | override fun convert(helper: BaseViewHolder?, item: ArticleItem?) {
29 | val itemView = helper?.itemView
30 | itemView?.apply {
31 | item?.let {
32 | nameHeadTV.text = getStrFirstChat(it.author)
33 | nameHeadTV.setBackgroundResource(getRandomColor(it.chapterId))
34 | nameTv.text = it.author
35 | titleTV.text = it.title
36 | timeTv.text = it.niceDate
37 | envelopePicIV.loadImage(it.envelopePic)
38 | collectTagTv.visibility = if (it.collect) {
39 | View.VISIBLE
40 | } else {
41 | View.GONE
42 | }
43 | }
44 | }
45 | }
46 |
47 | private fun getRandomColor(userID: Int): Int {
48 | return colorRess[userID % 4]
49 | }
50 |
51 | private fun getStrFirstChat(str: String): String {
52 | return str.substring(0, 1)
53 | }
54 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/adapter/WXArticleAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.adapter
2 |
3 | import com.chad.library.adapter.base.BaseQuickAdapter
4 | import com.chad.library.adapter.base.BaseViewHolder
5 | import com.githubly.wanandroid.R
6 | import com.githubly.wanandroid.model.ArticleItem
7 | import kotlinx.android.synthetic.main.item_wx_article.view.*
8 |
9 | /**
10 | * 类名:WXArticleAdapter
11 | * 作者:Yun.Lei
12 | * 功能:
13 | * 创建日期:2018-10-19 11:11
14 | * 修改人:
15 | * 修改时间:
16 | * 修改备注:
17 | */
18 | class WXArticleAdapter : BaseQuickAdapter(R.layout.item_wx_article) {
19 |
20 | var userID: Int = 0
21 | private val colorRess = mutableListOf(
22 | R.drawable.shape_head_red,
23 | R.drawable.shape_head_blue,
24 | R.drawable.shape_head_orange,
25 | R.drawable.shape_head_green)
26 |
27 | override fun convert(helper: BaseViewHolder?, item: ArticleItem?) {
28 | val itemView = helper?.itemView
29 | itemView?.apply {
30 | item?.let {
31 | nameHeadTV.text = getStrFirstChat(it.author)
32 | nameHeadTV.setBackgroundResource(getRandomColor())
33 | nameTv.text = it.author
34 | titleTv.text = it.title
35 | timeTv.text = it.niceDate
36 | heartIV.setColorFilter(context.resources.getColor(if (it.collect) {
37 | R.color.red
38 | } else {
39 | R.color.gray_1
40 | }))
41 | }
42 | }
43 | }
44 |
45 | private fun getRandomColor(): Int {
46 | return colorRess[userID % 4]
47 | }
48 |
49 | private fun getStrFirstChat(str: String): String {
50 | return str.substring(0, 1)
51 | }
52 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/contract/IArticlePageContract.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.contract
2 |
3 | import com.githubly.wanandroid.model.ArticleItem
4 | import com.githubly.wanandroid.model.BaseListData
5 | import com.githubly.wanandroid.presenter.base.IView
6 |
7 | /**
8 | * 类名:IArticlePageContract
9 | * 作者:Yun.Lei
10 | * 功能:
11 | * 创建日期:2018-10-19 17:11
12 | * 修改人:
13 | * 修改时间:
14 | * 修改备注:
15 | */
16 | interface IArticlePageContract {
17 |
18 | interface Presenter{
19 | fun getWXArticle(userID:Int,page:Int)
20 | }
21 |
22 | interface View:IView{
23 | fun onArticleSuccess(data: BaseListData)
24 | fun onArticleFailed(msg: String)
25 | }
26 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/contract/ICollectListContract.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.contract
2 |
3 | import com.githubly.wanandroid.model.ArticleItem
4 | import com.githubly.wanandroid.model.BaseListData
5 | import com.githubly.wanandroid.presenter.base.IView
6 |
7 | /**
8 | * 类名:ICollectListContract
9 | * 作者:Yun.Lei
10 | * 功能:
11 | * 创建日期:2018-10-22 17:46
12 | * 修改人:
13 | * 修改时间:
14 | * 修改备注:
15 | */
16 | interface ICollectListContract {
17 |
18 | interface Presenter{
19 | fun getCollectList(page:Int)
20 | }
21 |
22 | interface View:IView{
23 | fun onListSuccess(data: BaseListData)
24 | fun onListFailed(msg:String)
25 | }
26 |
27 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/contract/IContentContract.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.contract
2 |
3 | import com.githubly.wanandroid.presenter.base.IView
4 |
5 | /**
6 | * 类名:IContentContract
7 | * 作者:Yun.Lei
8 | * 功能:
9 | * 创建日期:2018-10-23 16:13
10 | * 修改人:
11 | * 修改时间:
12 | * 修改备注:
13 | */
14 | interface IContentContract {
15 |
16 | interface Presenter {
17 | fun articleCollect(id: Int)
18 | fun articleUncollect(id: Int)
19 | fun articleUncollectPage(id: Int,originId:Int)
20 | }
21 |
22 | interface View : IView {
23 | fun onCollectSuccess()
24 | fun onCollectFailed(msg: String)
25 | fun onUncollectSuccess()
26 | fun onUncollectFailed(msg: String)
27 | fun onUncollectPageSuccess()
28 | fun onUncollectPageFailed(msg: String)
29 | }
30 |
31 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/contract/IHomeContract.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.contract
2 |
3 | import com.githubly.wanandroid.model.ArticleItem
4 | import com.githubly.wanandroid.model.Banner
5 | import com.githubly.wanandroid.model.BaseListData
6 | import com.githubly.wanandroid.presenter.base.IView
7 |
8 | /**
9 | * 类名:IHomeContract
10 | * 作者:Yun.Lei
11 | * 功能:
12 | * 创建日期:2018-10-19 11:33
13 | * 修改人:
14 | * 修改时间:
15 | * 修改备注:
16 | */
17 | interface IHomeContract {
18 |
19 | interface Presenter {
20 | fun getBanner()
21 | fun getHomeArticle(page:Int)
22 | }
23 |
24 | interface View : IView {
25 | fun onBannerSuccess(banners: MutableList)
26 | fun onBannerFailed(msg: String)
27 | fun onArticleSuccess(data:BaseListData)
28 | fun onArticleFailed(msg: String)
29 | }
30 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/contract/ILoginContract.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.contract
2 |
3 | import com.githubly.wanandroid.model.User
4 | import com.githubly.wanandroid.presenter.base.IView
5 |
6 | /**
7 | * 类名:ILoginContract
8 | * 作者:Yun.Lei
9 | * 功能:
10 | * 创建日期:2018-10-22 14:43
11 | * 修改人:
12 | * 修改时间:
13 | * 修改备注:
14 | */
15 | interface ILoginContract {
16 |
17 | interface Presenter {
18 | fun login(userName: String, password: String)
19 | fun register(userName: String, password: String, rePassword: String)
20 | }
21 |
22 | interface View : IView {
23 | fun onLoginSuccess(user: User)
24 | fun onLoginFailed(msg: String)
25 |
26 | fun onRegisterSuccess(user: User)
27 | fun onRegisterFailed(msg: String)
28 | }
29 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/contract/ILogoutContract.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.contract
2 |
3 | import com.githubly.wanandroid.presenter.base.IView
4 |
5 | /**
6 | * 类名:ILogoutContract
7 | * 作者:Yun.Lei
8 | * 功能:
9 | * 创建日期:2018-10-22 16:39
10 | * 修改人:
11 | * 修改时间:
12 | * 修改备注:
13 | */
14 | interface ILogoutContract {
15 |
16 | interface Presenter{
17 |
18 | fun logout()
19 | }
20 |
21 | interface View:IView{
22 | fun onLogoutSuccess()
23 | fun onLogoutFailed(msg:String)
24 | }
25 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/contract/IProjectPageContract.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.contract
2 |
3 | import com.githubly.wanandroid.model.ArticleItem
4 | import com.githubly.wanandroid.model.BaseListData
5 | import com.githubly.wanandroid.presenter.base.IView
6 |
7 | /**
8 | * 类名:IProjectPageContract
9 | * 作者:Yun.Lei
10 | * 功能:
11 | * 创建日期:2018-10-19 17:11
12 | * 修改人:
13 | * 修改时间:
14 | * 修改备注:
15 | */
16 | interface IProjectPageContract {
17 |
18 | interface Presenter{
19 | fun getProjectArticle(userID:Int,page:Int)
20 | }
21 |
22 | interface View:IView{
23 | fun onArticleSuccess(data: BaseListData)
24 | fun onArticleFailed(msg: String)
25 | }
26 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/fragment/ArticleFragment.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.fragment
2 |
3 | import android.support.v4.app.Fragment
4 | import android.support.v4.app.FragmentManager
5 | import android.support.v4.app.FragmentPagerAdapter
6 | import com.githubly.wanandroid.R
7 | import com.githubly.wanandroid.fragment.base.BaseFragment
8 | import com.githubly.wanandroid.model.Chapter
9 | import com.githubly.wanandroid.presenter.base.BasePresenter
10 | import com.githubly.wanandroid.utils.FileUtils
11 | import com.google.gson.Gson
12 | import com.google.gson.reflect.TypeToken
13 | import kotlinx.android.synthetic.main.fragment_article.*
14 | import org.jetbrains.anko.support.v4.act
15 |
16 | /**
17 | * 类名:ArticleFragment
18 | * 作者:Yun.Lei
19 | * 功能:
20 | * 创建日期:2018-10-19 16:12
21 | * 修改人:
22 | * 修改时间:
23 | * 修改备注:
24 | */
25 | class ArticleFragment : BaseFragment>() {
26 |
27 | private lateinit var chapterList: MutableList
28 |
29 | override val inflateId: Int
30 | get() = R.layout.fragment_article
31 |
32 | override fun initView() {
33 |
34 | }
35 |
36 | override fun initData() {
37 | val readFileFromAssets = FileUtils.getFromAssets(act, "chapters")
38 | chapterList = Gson().fromJson(readFileFromAssets, object : TypeToken>() {}.type)
39 | viewPager.adapter = ArticlePagerAdapter(chapterList, childFragmentManager)
40 | tabLayout.setViewPager(viewPager)
41 | }
42 |
43 | override fun initPresenter(): BasePresenter<*>? = null
44 | }
45 |
46 | class ArticlePagerAdapter(private val chapterList: MutableList, fm: FragmentManager) :
47 | FragmentPagerAdapter(fm) {
48 |
49 | override fun getItem(position: Int): Fragment = ArticlePageFragment.getNewInstance(chapterList[position].id)
50 |
51 | override fun getCount(): Int = chapterList.size
52 |
53 | override fun getPageTitle(position: Int): CharSequence? = chapterList[position].name
54 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/fragment/ArticlePageFragment.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.fragment
2 |
3 | import android.os.Bundle
4 | import android.support.v7.widget.LinearLayoutManager
5 | import com.githubly.wanandroid.R
6 | import com.githubly.wanandroid.activity.WebActivity
7 | import com.githubly.wanandroid.adapter.WXArticleAdapter
8 | import com.githubly.wanandroid.contract.IArticlePageContract
9 | import com.githubly.wanandroid.fragment.base.BaseFragment
10 | import com.githubly.wanandroid.model.ArticleItem
11 | import com.githubly.wanandroid.model.BaseListData
12 | import com.githubly.wanandroid.model.EventArticleCollectChange
13 | import com.githubly.wanandroid.model.EventRemoveCollectPageArticle
14 | import com.githubly.wanandroid.presenter.ArticlePagePresenter
15 | import kotlinx.android.synthetic.main.fragment_article_page.*
16 | import org.greenrobot.eventbus.EventBus
17 | import org.greenrobot.eventbus.Subscribe
18 | import org.greenrobot.eventbus.ThreadMode
19 | import org.jetbrains.anko.support.v4.act
20 | import org.jetbrains.anko.support.v4.toast
21 | import org.jetbrains.anko.support.v4.withArguments
22 |
23 | /**
24 | * 类名:ArticlePageFragment
25 | * 作者:Yun.Lei
26 | * 功能:
27 | * 创建日期:2018-10-19 16:42
28 | * 修改人:
29 | * 修改时间:
30 | * 修改备注:
31 | */
32 | class ArticlePageFragment : BaseFragment(), IArticlePageContract.View {
33 |
34 |
35 | companion object {
36 | fun getNewInstance(userId: Int): ArticlePageFragment {
37 | val frag = ArticlePageFragment()
38 | frag.withArguments("userId" to userId)
39 | return frag
40 | }
41 | }
42 |
43 | private val mAdapter by lazy { WXArticleAdapter() }
44 | private var page = 1
45 | private var userId = 408
46 | override val inflateId: Int
47 | get() = R.layout.fragment_article_page
48 |
49 | override fun onCreate(savedInstanceState: Bundle?) {
50 | super.onCreate(savedInstanceState)
51 | userId = arguments?.getInt("userId") ?: 408
52 | EventBus.getDefault().register(this)
53 | }
54 |
55 | override fun initView() {
56 | mAdapter.userID = userId
57 | recyclerView.adapter = mAdapter
58 | recyclerView.layoutManager = LinearLayoutManager(activity)
59 | /*recyclerView.addItemDecoration(
60 | HorizontalDividerItemDecoration.Builder(activity).color(act.resources.getColor(R.color.backgroundColor)).size(
61 | dip(8)
62 | ).build()
63 | )*/
64 | mAdapter.setOnLoadMoreListener({
65 | page++
66 | mPresenter?.getWXArticle(userId, page)
67 | }, recyclerView)
68 | mAdapter.setPreLoadNumber(2)
69 | refreshLayout.setOnRefreshListener {
70 | initData()
71 | }
72 | mAdapter.emptyView = mLoadingStateView
73 | mLoadingStateView.setOnReloadClickListener {
74 | initData()
75 | }
76 | mAdapter.setOnItemClickListener { _, _, position ->
77 | mAdapter.data[position]?.apply {
78 | WebActivity.active(act, link, id, author, title, collect)
79 | }
80 | }
81 | }
82 |
83 | override fun initPresenter(): ArticlePagePresenter? = ArticlePagePresenter(this)
84 |
85 | override fun initData() {
86 | mLoadingStateView.loading()
87 | page = 1
88 | mPresenter?.getWXArticle(userId, page)
89 | }
90 |
91 |
92 | override fun onArticleSuccess(data: BaseListData) {
93 | if (data.curPage == 1) {
94 | mAdapter.setNewData(data.datas)
95 | refreshLayout.isRefreshing = false
96 | } else {
97 | mAdapter.addData(data.datas)
98 | mAdapter.loadMoreComplete()
99 | }
100 | page = data.curPage
101 | if (data.over) {
102 | mAdapter.loadMoreEnd()
103 | }
104 | mAdapter.setEnableLoadMore(!data.over)
105 | mLoadingStateView.success()
106 | }
107 |
108 | override fun onArticleFailed(msg: String) {
109 | if (page == 1) {
110 | mAdapter.setNewData(mutableListOf())
111 | mLoadingStateView.failed(msg)
112 | refreshLayout.isRefreshing = false
113 | } else {
114 | toast(msg)
115 | mAdapter.loadMoreComplete()
116 | }
117 | }
118 |
119 | @Subscribe(threadMode = ThreadMode.MAIN)
120 | fun onEventArticleCollectChange(event: EventArticleCollectChange) {
121 | val id = event.id
122 | val item = mAdapter.data.find { it.id == id }
123 | if (item != null) {
124 | item.collect = event.collect
125 | mAdapter.notifyDataSetChanged()
126 | }
127 | }
128 |
129 | @Subscribe(threadMode = ThreadMode.MAIN)
130 | fun onEventCollectRemove(event: EventRemoveCollectPageArticle) {
131 | val id = event.id
132 | onEventArticleCollectChange(EventArticleCollectChange(id, false))
133 | }
134 |
135 | override fun onDestroy() {
136 | super.onDestroy()
137 | EventBus.getDefault().unregister(this)
138 | }
139 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/fragment/HomeFragment.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.fragment
2 |
3 |
4 | import android.os.Bundle
5 | import android.support.v7.widget.LinearLayoutManager
6 | import android.view.View
7 | import android.widget.ImageView
8 | import cn.bingoogolapple.bgabanner.BGABanner
9 | import com.githubly.wanandroid.R
10 | import com.githubly.wanandroid.activity.WebActivity
11 | import com.githubly.wanandroid.adapter.HomeAdapter
12 | import com.githubly.wanandroid.contract.IHomeContract
13 | import com.githubly.wanandroid.fragment.base.BaseFragment
14 | import com.githubly.wanandroid.model.*
15 | import com.githubly.wanandroid.presenter.HomePresenter
16 | import com.githubly.wanandroid.utils.loadImage
17 | import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration
18 | import kotlinx.android.synthetic.main.fragment_home.*
19 | import kotlinx.android.synthetic.main.layout_home_banner.view.*
20 | import org.greenrobot.eventbus.EventBus
21 | import org.greenrobot.eventbus.Subscribe
22 | import org.greenrobot.eventbus.ThreadMode
23 | import org.jetbrains.anko.support.v4.act
24 | import org.jetbrains.anko.support.v4.dip
25 | import org.jetbrains.anko.support.v4.toast
26 |
27 | /**
28 | * HomeFragment
29 | *
30 | */
31 | class HomeFragment : BaseFragment(), IHomeContract.View {
32 |
33 |
34 | private val mAdapter by lazy { HomeAdapter() }
35 | private lateinit var mBannerView: BGABanner
36 | private var page = 1
37 |
38 | override val inflateId: Int
39 | get() = R.layout.fragment_home
40 |
41 | override fun onCreate(savedInstanceState: Bundle?) {
42 | super.onCreate(savedInstanceState)
43 | EventBus.getDefault().register(this)
44 | }
45 |
46 | override fun initView() {
47 | val bannerView = View.inflate(activity, R.layout.layout_home_banner, null)
48 | mBannerView = bannerView.bannerView
49 | recyclerView.adapter = mAdapter
50 | recyclerView.layoutManager = LinearLayoutManager(activity)
51 | recyclerView.addItemDecoration(
52 | HorizontalDividerItemDecoration.Builder(activity).color(act.resources.getColor(R.color.backgroundColor)).size(
53 | dip(8)
54 | ).visibilityProvider { position, parent ->
55 | position == 0
56 | }.build()
57 | )
58 | mAdapter.addHeaderView(bannerView)
59 | mBannerView.setAdapter { banner, itemView, model, position ->
60 | val imageView: ImageView = itemView as ImageView
61 | val bannerItem = model as Banner
62 | imageView.loadImage(bannerItem.imagePath)
63 | }
64 | mAdapter.setOnLoadMoreListener({
65 | page++
66 | mPresenter?.getHomeArticle(page)
67 | }, recyclerView)
68 | mAdapter.setPreLoadNumber(2)
69 | refreshLayout.setOnRefreshListener {
70 | initData()
71 | }
72 | mAdapter.setOnItemClickListener { adapter, view, position ->
73 | mAdapter.data[position]?.apply {
74 | WebActivity.active(act, link, id, author, title, collect)
75 | }
76 | }
77 | mAdapter.emptyView = mLoadingStateView
78 | mLoadingStateView.setOnReloadClickListener {
79 | initData()
80 | }
81 | mBannerView.setDelegate { _, _, model, _ ->
82 | val bannerItem = model as Banner
83 | bannerItem.apply {
84 | WebActivity.active(act, url, -1, "wanAndroid", title, collect = false)
85 | }
86 | }
87 | }
88 |
89 | override fun initPresenter(): HomePresenter? = HomePresenter(this)
90 |
91 | override fun initData() {
92 | mLoadingStateView.loading()
93 | page = 1
94 | mPresenter?.getBanner()
95 | mPresenter?.getHomeArticle(page)
96 | }
97 |
98 | override fun onBannerSuccess(banners: MutableList) {
99 | val tips = mutableListOf()
100 | banners.forEach {
101 | tips.add(it.title)
102 | }
103 | mBannerView.setData(banners, tips)
104 | }
105 |
106 | override fun onBannerFailed(msg: String) {
107 |
108 | }
109 |
110 | override fun onArticleSuccess(data: BaseListData) {
111 | if (data.curPage == 1) {
112 | mAdapter.setNewData(data.datas)
113 | refreshLayout.isRefreshing = false
114 | } else {
115 | mAdapter.addData(data.datas)
116 | mAdapter.loadMoreComplete()
117 | }
118 | page = data.curPage
119 | if (data.over) {
120 | mAdapter.loadMoreEnd()
121 | }
122 | mAdapter.setEnableLoadMore(!data.over)
123 | mLoadingStateView.success()
124 | }
125 |
126 | override fun onArticleFailed(msg: String) {
127 | if (page == 1) {
128 | mAdapter.setNewData(mutableListOf())
129 | mLoadingStateView.failed(msg)
130 | refreshLayout.isRefreshing = false
131 | } else {
132 | toast(msg)
133 | mAdapter.loadMoreComplete()
134 | }
135 | }
136 |
137 | @Subscribe(threadMode = ThreadMode.MAIN)
138 | fun onEventArticleCollectChange(event: EventArticleCollectChange) {
139 | val id = event.id
140 | val item = mAdapter.data.find { it.id == id }
141 | if (item != null) {
142 | item.collect = event.collect
143 | mAdapter.notifyDataSetChanged()
144 | }
145 | }
146 |
147 | @Subscribe(threadMode = ThreadMode.MAIN)
148 | fun onEventCollectRemove(event: EventRemoveCollectPageArticle) {
149 | val id = event.id
150 | onEventArticleCollectChange(EventArticleCollectChange(id, false))
151 | }
152 |
153 | override fun onDestroy() {
154 | super.onDestroy()
155 | EventBus.getDefault().unregister(this)
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/fragment/MyFragment.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.fragment
2 |
3 | import android.os.Bundle
4 | import android.view.View
5 | import com.githubly.wanandroid.App
6 | import com.githubly.wanandroid.R
7 | import com.githubly.wanandroid.activity.CollectListActivity
8 | import com.githubly.wanandroid.activity.LoginActivity
9 | import com.githubly.wanandroid.activity.WebActivity
10 | import com.githubly.wanandroid.contract.ILogoutContract
11 | import com.githubly.wanandroid.fragment.base.BaseFragment
12 | import com.githubly.wanandroid.model.User
13 | import com.githubly.wanandroid.presenter.LogoutPresenter
14 | import com.tencent.bugly.beta.Beta
15 | import kotlinx.android.synthetic.main.fragment_my.*
16 | import org.greenrobot.eventbus.EventBus
17 | import org.greenrobot.eventbus.Subscribe
18 | import org.greenrobot.eventbus.ThreadMode
19 | import org.jetbrains.anko.support.v4.act
20 | import org.jetbrains.anko.support.v4.toast
21 |
22 | /**
23 | * 类名:MyFragment
24 | * 作者:Yun.Lei
25 | * 功能:
26 | * 创建日期:2018-10-22 11:01
27 | * 修改人:
28 | * 修改时间:
29 | * 修改备注:
30 | */
31 | class MyFragment : BaseFragment(), ILogoutContract.View {
32 |
33 | override val inflateId: Int
34 | get() = R.layout.fragment_my
35 |
36 | override fun onCreate(savedInstanceState: Bundle?) {
37 | super.onCreate(savedInstanceState)
38 | EventBus.getDefault().register(this)
39 | }
40 |
41 | override fun initView() {
42 | btnLogin.setOnClickListener {
43 | LoginActivity.active(act)
44 | }
45 | btnLogout.setOnClickListener {
46 | showLoading()
47 | mPresenter?.logout()
48 | }
49 | btnCollectList.setOnClickListener {
50 | if (App.instance.isLogin) {
51 | CollectListActivity.active(activity!!)
52 | } else {
53 | LoginActivity.active(act)
54 | }
55 | }
56 | btnAbout.setOnClickListener {
57 | val link = "file:///android_asset/web/about.html"
58 | WebActivity.active(act, link, -1, "wanAndroid", "", false)
59 | }
60 | btnTodo.setOnClickListener {
61 | toast("待完成...")
62 | }
63 | btnKnowSystem.setOnClickListener {
64 | toast("待完成...")
65 | }
66 | btnUpdate.setOnClickListener {
67 | Beta.checkUpgrade()
68 | }
69 | }
70 |
71 | override fun initData() {
72 | setUserInfo()
73 | }
74 |
75 | override fun initPresenter(): LogoutPresenter? = LogoutPresenter(this)
76 |
77 | @Subscribe(threadMode = ThreadMode.MAIN)
78 | fun onEventLoginSuccess(userEvent: User) {
79 | setUserInfo()
80 | }
81 |
82 | private fun setUserInfo() {
83 | val user = App.instance.user
84 | user?.let {
85 | nameImgTv.text = it.username.substring(0, 1)
86 | nameTv.text = it.username
87 | btnLogin.visibility = View.GONE
88 | nameTv.visibility = View.VISIBLE
89 | btnLogout.visibility = View.VISIBLE
90 | logoutLine.visibility = View.VISIBLE
91 | } ?: setLogout()
92 | }
93 |
94 | private fun setLogout() {
95 | nameImgTv.text = ""
96 | nameTv.text = ""
97 | btnLogin.visibility = View.VISIBLE
98 | nameTv.visibility = View.GONE
99 | btnLogout.visibility = View.GONE
100 | logoutLine.visibility = View.GONE
101 | }
102 |
103 | override fun onDestroy() {
104 | super.onDestroy()
105 | EventBus.getDefault().unregister(this)
106 | }
107 |
108 | override fun onLogoutSuccess() {
109 | dismissLoading()
110 | App.instance.user = null
111 | setLogout()
112 | }
113 |
114 | override fun onLogoutFailed(msg: String) {
115 | dismissLoading()
116 | toast(msg)
117 | }
118 |
119 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/fragment/ProjectFragment.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.fragment
2 |
3 | import android.support.v4.app.Fragment
4 | import android.support.v4.app.FragmentManager
5 | import android.support.v4.app.FragmentPagerAdapter
6 | import com.githubly.wanandroid.R
7 | import com.githubly.wanandroid.fragment.base.BaseFragment
8 | import com.githubly.wanandroid.model.Chapter
9 | import com.githubly.wanandroid.presenter.base.BasePresenter
10 | import com.githubly.wanandroid.utils.FileUtils
11 | import com.google.gson.Gson
12 | import com.google.gson.reflect.TypeToken
13 | import kotlinx.android.synthetic.main.fragment_project.*
14 | import org.jetbrains.anko.support.v4.act
15 |
16 | /**
17 | * 类名:ArticleFragment
18 | * 作者:Yun.Lei
19 | * 功能:
20 | * 创建日期:2018-10-19 16:12
21 | * 修改人:
22 | * 修改时间:
23 | * 修改备注:
24 | */
25 | class ProjectFragment : BaseFragment>() {
26 |
27 | private lateinit var chapterList: MutableList
28 |
29 | override val inflateId: Int
30 | get() = R.layout.fragment_project
31 |
32 | override fun initView() {
33 |
34 | }
35 |
36 | override fun initData() {
37 | val readFileFromAssets = FileUtils.getFromAssets(act, "projects")
38 | chapterList = Gson().fromJson(readFileFromAssets, object : TypeToken>() {}.type)
39 | viewPager.adapter = ProjectFragmentPagerAdapter(chapterList, childFragmentManager)
40 | tabLayout.setViewPager(viewPager)
41 | }
42 |
43 | override fun initPresenter(): BasePresenter<*>? = null
44 | }
45 |
46 | class ProjectFragmentPagerAdapter(private val chapterList: MutableList, fm: FragmentManager) :
47 | FragmentPagerAdapter(fm) {
48 |
49 | override fun getItem(position: Int): Fragment = ProjectPageFragment.getNewInstance(chapterList[position].id)
50 |
51 | override fun getCount(): Int = chapterList.size
52 |
53 | override fun getPageTitle(position: Int): CharSequence? = chapterList[position].name
54 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/fragment/ProjectPageFragment.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.fragment
2 |
3 | import android.os.Bundle
4 | import android.support.v7.widget.StaggeredGridLayoutManager
5 | import com.githubly.wanandroid.R
6 | import com.githubly.wanandroid.activity.WebActivity
7 | import com.githubly.wanandroid.adapter.ProjectArticleAdapter
8 | import com.githubly.wanandroid.contract.IProjectPageContract
9 | import com.githubly.wanandroid.fragment.base.BaseFragment
10 | import com.githubly.wanandroid.model.ArticleItem
11 | import com.githubly.wanandroid.model.BaseListData
12 | import com.githubly.wanandroid.model.EventArticleCollectChange
13 | import com.githubly.wanandroid.model.EventRemoveCollectPageArticle
14 | import com.githubly.wanandroid.presenter.ProjectPagePresenter
15 | import kotlinx.android.synthetic.main.fragment_project_page.*
16 | import org.greenrobot.eventbus.EventBus
17 | import org.greenrobot.eventbus.Subscribe
18 | import org.greenrobot.eventbus.ThreadMode
19 | import org.jetbrains.anko.support.v4.act
20 | import org.jetbrains.anko.support.v4.toast
21 | import org.jetbrains.anko.support.v4.withArguments
22 |
23 | /**
24 | * 类名:ProjectPageFragment
25 | * 作者:Yun.Lei
26 | * 功能:
27 | * 创建日期:2018-10-19 16:42
28 | * 修改人:
29 | * 修改时间:
30 | * 修改备注:
31 | */
32 | class ProjectPageFragment : BaseFragment(), IProjectPageContract.View {
33 |
34 |
35 | companion object {
36 | fun getNewInstance(userId: Int): ProjectPageFragment {
37 | val frag = ProjectPageFragment()
38 | frag.withArguments("userId" to userId)
39 | return frag
40 | }
41 | }
42 |
43 | private val mAdapter by lazy { ProjectArticleAdapter() }
44 | private var page = 1
45 | private var userId = 99999
46 | override val inflateId: Int
47 | get() = R.layout.fragment_project_page
48 |
49 | override fun onCreate(savedInstanceState: Bundle?) {
50 | super.onCreate(savedInstanceState)
51 | EventBus.getDefault().register(this)
52 | userId = arguments?.getInt("userId") ?: 99999
53 | }
54 |
55 | override fun initView() {
56 | recyclerView.adapter = mAdapter
57 | recyclerView.layoutManager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
58 | /*recyclerView.addItemDecoration(
59 | HorizontalDividerItemDecoration.Builder(activity).color(act.resources.getColor(R.color.backgroundColor)).size(
60 | dip(8)
61 | ).build()
62 | )*/
63 | mAdapter.setOnLoadMoreListener({
64 | page++
65 | mPresenter?.getProjectArticle(userId, page)
66 | }, recyclerView)
67 | mAdapter.setPreLoadNumber(2)
68 | refreshLayout.setOnRefreshListener {
69 | initData()
70 | }
71 | mAdapter.emptyView = mLoadingStateView
72 | mLoadingStateView.setOnReloadClickListener {
73 | initData()
74 | }
75 | mAdapter.setOnItemClickListener { _, _, position ->
76 | mAdapter.data[position]?.apply {
77 | WebActivity.active(act, link, id, author, title, collect)
78 | }
79 | }
80 | }
81 |
82 | override fun initPresenter(): ProjectPagePresenter? = ProjectPagePresenter(this)
83 |
84 | override fun initData() {
85 | mLoadingStateView.loading()
86 | page = 1
87 | mPresenter?.getProjectArticle(userId, page)
88 | }
89 |
90 |
91 | override fun onArticleSuccess(data: BaseListData) {
92 | if (data.curPage == 1) {
93 | mAdapter.setNewData(data.datas)
94 | refreshLayout.isRefreshing = false
95 | } else {
96 | mAdapter.addData(data.datas)
97 | mAdapter.loadMoreComplete()
98 | }
99 | page = data.curPage
100 | if (data.over) {
101 | mAdapter.loadMoreEnd()
102 | }
103 | mAdapter.setEnableLoadMore(!data.over)
104 | mLoadingStateView.success()
105 | }
106 |
107 | override fun onArticleFailed(msg: String) {
108 | if (page == 1) {
109 | mAdapter.setNewData(mutableListOf())
110 | mLoadingStateView.failed(msg)
111 | refreshLayout.isRefreshing = false
112 | } else {
113 | toast(msg)
114 | mAdapter.loadMoreComplete()
115 | }
116 | }
117 |
118 | @Subscribe(threadMode = ThreadMode.MAIN)
119 | fun onEventArticleCollectChange(event: EventArticleCollectChange) {
120 | val id = event.id
121 | val item = mAdapter.data.find { it.id == id }
122 | if (item != null) {
123 | item.collect = event.collect
124 | mAdapter.notifyDataSetChanged()
125 | }
126 | }
127 |
128 | @Subscribe(threadMode = ThreadMode.MAIN)
129 | fun onEventCollectRemove(event: EventRemoveCollectPageArticle) {
130 | val id = event.id
131 | onEventArticleCollectChange(EventArticleCollectChange(id, false))
132 | }
133 |
134 | override fun onDestroy() {
135 | super.onDestroy()
136 | EventBus.getDefault().unregister(this)
137 | }
138 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/fragment/base/BaseFragment.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.fragment.base
2 |
3 | import android.os.Bundle
4 | import android.support.v4.app.Fragment
5 | import android.view.LayoutInflater
6 | import android.view.View
7 | import android.view.ViewGroup
8 | import com.githubly.wanandroid.presenter.base.BasePresenter
9 | import com.githubly.wanandroid.utils.ILoading
10 | import com.githubly.wanandroid.widget.LoadingStateView
11 | import com.yanzhenjie.loading.dialog.LoadingDialog
12 | import org.jetbrains.anko.support.v4.act
13 |
14 | /**
15 | * 类名:BaseFragment
16 | * 作者:Yun.Lei
17 | * 功能:
18 | * 创建日期:2018-10-18 19:34
19 | * 修改人:
20 | * 修改时间:
21 | * 修改备注:
22 | */
23 | abstract class BaseFragment> : Fragment(), ILoading {
24 | /**
25 | * 当前页面需要加载的layoutId,等价setContentView
26 | */
27 | abstract val inflateId: Int
28 |
29 | /**
30 | * 初始化视图操作在这里执行,执行时机为onCreate之后
31 | */
32 | abstract fun initView(): Unit
33 |
34 | /**
35 | * 数据初始化在这里执行,执行时机为initView之后
36 | */
37 | abstract fun initData(): Unit
38 |
39 | //kotlin 懒加载,在第一次使用Presenter时初始化,这种设计师针对一个View只针对一个Presenter。
40 | //多个Presenter的情况此处不应该使用泛型
41 | protected val mPresenter: P? by lazy { initPresenter() }
42 |
43 | abstract fun initPresenter(): P?
44 |
45 | private val mWaitDialog by lazy { LoadingDialog(act) }
46 |
47 | protected val mLoadingStateView by lazy { LoadingStateView(act) }
48 |
49 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
50 | return inflater.inflate(inflateId, container, false)
51 | }
52 |
53 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
54 | super.onViewCreated(view, savedInstanceState)
55 | initView()
56 | initData()
57 | }
58 |
59 | override fun onDestroyView() {
60 | super.onDestroyView()
61 | //view和presenter解绑
62 | mPresenter?.onDestroy()
63 | dismissLoading()
64 | }
65 |
66 | override fun showLoading(msg: String) {
67 | mWaitDialog.setMessage(msg)
68 | if (!mWaitDialog.isShowing) {
69 | mWaitDialog.show()
70 | }
71 | }
72 |
73 | override fun dismissLoading() {
74 | if (mWaitDialog.isShowing) {
75 | mWaitDialog.dismiss()
76 | }
77 | }
78 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/model/ArticleItem.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.model
2 |
3 | import com.google.gson.annotations.SerializedName
4 |
5 |
6 | /**
7 | * 类名:ArticleItem
8 | * 作者:Yun.Lei
9 | * 功能:
10 | * 创建日期:2018-10-18 17:57
11 | * 修改人:
12 | * 修改时间:
13 | * 修改备注:
14 | */
15 |
16 | data class ArticleItem(
17 | @SerializedName("apkLink") var apkLink: String = "",
18 | @SerializedName("author") var author: String = "",
19 | @SerializedName("chapterId") var chapterId: Int = 0,
20 | @SerializedName("chapterName") var chapterName: String = "",
21 | @SerializedName("collect") var collect: Boolean = false,
22 | @SerializedName("courseId") var courseId: Int = 0,
23 | @SerializedName("desc") var desc: String = "",
24 | @SerializedName("envelopePic") var envelopePic: String = "",
25 | @SerializedName("fresh") var fresh: Boolean = false,
26 | @SerializedName("id") var id: Int = 0,
27 | @SerializedName("link") var link: String = "",
28 | @SerializedName("niceDate") var niceDate: String = "",
29 | @SerializedName("origin") var origin: String = "",
30 | @SerializedName("projectLink") var projectLink: String = "",
31 | @SerializedName("publishTime") var publishTime: Long = 0,
32 | @SerializedName("superChapterId") var superChapterId: Int = 0,
33 | @SerializedName("superChapterName") var superChapterName: String = "",
34 | @SerializedName("tags") var tags: MutableList = mutableListOf(),
35 | @SerializedName("title") var title: String = "",
36 | @SerializedName("type") var type: Int = 0,
37 | @SerializedName("userId") var userId: Int = 0,
38 | @SerializedName("visible") var visible: Int = 0,
39 | @SerializedName("zan") var zan: Int = 0,
40 | @SerializedName("originId") var originId: Int = 0
41 | )
42 |
43 | data class WChatArticleTag(
44 | @SerializedName("name") var name: String = "",
45 | @SerializedName("url") var url: String = ""
46 | )
47 |
48 | data class EventRemoveCollectPageArticle(var id: Int)
49 |
50 | data class EventArticleCollectChange(var id: Int,var collect: Boolean)
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/model/Banner.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.model
2 | import com.google.gson.annotations.SerializedName
3 |
4 |
5 | /**
6 | * 类名:Banner
7 | * 作者:Yun.Lei
8 | * 功能:
9 | * 创建日期:2018-10-19 11:30
10 | * 修改人:
11 | * 修改时间:
12 | * 修改备注:
13 | */
14 |
15 | data class Banner(
16 | @SerializedName("desc") var desc: String = "",
17 | @SerializedName("id") var id: Int = 0,
18 | @SerializedName("imagePath") var imagePath: String = "",
19 | @SerializedName("isVisible") var isVisible: Int = 0,
20 | @SerializedName("order") var order: Int = 0,
21 | @SerializedName("title") var title: String = "",
22 | @SerializedName("type") var type: Int = 0,
23 | @SerializedName("url") var url: String = ""
24 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/model/BaseListData.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.model
2 |
3 | /**
4 | * 类名:BaseListData
5 | * 作者:Yun.Lei
6 | * 功能:
7 | * 创建日期:2018-10-18 17:54
8 | * 修改人:
9 | * 修改时间:
10 | * 修改备注:
11 | */
12 | class BaseListData {
13 | val curPage: Int = 0
14 | val datas: MutableList = mutableListOf()
15 | val offset: Int = 0
16 | val over: Boolean = true
17 | val pageCount: Int = 0
18 | val size: Int = 0
19 | val total: Int = 0
20 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/model/BaseResult.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.model
2 |
3 | /**
4 | * 类名:BaseResult
5 | * 作者:Yun.Lei
6 | * 功能:
7 | * 创建日期:2018-10-18 17:16
8 | * 修改人:
9 | * 修改时间:
10 | * 修改备注:
11 | */
12 | class BaseResult {
13 | var data: T? = null
14 | var errorCode: Int = -1
15 | var errorMsg: String = ""
16 |
17 | val isSuccess: Boolean
18 | get() = errorCode == 0
19 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/model/Chapter.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.model
2 | import com.google.gson.annotations.SerializedName
3 |
4 |
5 | /**
6 | * 类名:Chapter
7 | * 作者:Yun.Lei
8 | * 功能:
9 | * 创建日期:2018-10-19 16:33
10 | * 修改人:
11 | * 修改时间:
12 | * 修改备注:
13 | */
14 |
15 | data class Chapter(
16 | @SerializedName("children") var children: List = listOf(),
17 | @SerializedName("courseId") var courseId: Int = 0,
18 | @SerializedName("id") var id: Int = 0,
19 | @SerializedName("name") var name: String = "",
20 | @SerializedName("order") var order: Int = 0,
21 | @SerializedName("parentChapterId") var parentChapterId: Int = 0,
22 | @SerializedName("userControlSetTop") var userControlSetTop: Boolean = false,
23 | @SerializedName("visible") var visible: Int = 0
24 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/model/User.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.model
2 | import android.os.Parcel
3 | import android.os.Parcelable
4 | import com.google.gson.annotations.SerializedName
5 |
6 |
7 | /**
8 | * 类名:User
9 | * 作者:Yun.Lei
10 | * 功能:
11 | * 创建日期:2018-10-22 12:51
12 | * 修改人:
13 | * 修改时间:
14 | * 修改备注:
15 | */
16 |
17 | data class User(
18 | @SerializedName("email") var email: String = "",
19 | @SerializedName("icon") var icon: String = "",
20 | @SerializedName("id") var id: Int = 0,
21 | @SerializedName("password") var password: String = "",
22 | @SerializedName("token") var token: String = "",
23 | @SerializedName("type") var type: Int = 0,
24 | @SerializedName("username") var username: String = ""
25 | ) : Parcelable {
26 | constructor(parcel: Parcel) : this(
27 | parcel.readString(),
28 | parcel.readString(),
29 | parcel.readInt(),
30 | parcel.readString(),
31 | parcel.readString(),
32 | parcel.readInt(),
33 | parcel.readString()) {
34 | }
35 |
36 | override fun writeToParcel(parcel: Parcel, flags: Int) {
37 | parcel.writeString(email)
38 | parcel.writeString(icon)
39 | parcel.writeInt(id)
40 | parcel.writeString(password)
41 | parcel.writeString(token)
42 | parcel.writeInt(type)
43 | parcel.writeString(username)
44 | }
45 |
46 | override fun describeContents(): Int {
47 | return 0
48 | }
49 |
50 | companion object CREATOR : Parcelable.Creator {
51 | override fun createFromParcel(parcel: Parcel): User {
52 | return User(parcel)
53 | }
54 |
55 | override fun newArray(size: Int): Array {
56 | return arrayOfNulls(size)
57 | }
58 | }
59 |
60 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/net/ApiCallBack.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.net
2 |
3 | import com.githubly.wanandroid.App
4 | import com.githubly.wanandroid.model.BaseResult
5 | import retrofit2.Call
6 | import retrofit2.Callback
7 | import retrofit2.Response
8 | import java.net.ConnectException
9 | import java.net.SocketTimeoutException
10 | import java.net.UnknownHostException
11 |
12 | /**
13 | * 类名:ApiCallBack
14 | * 作者:Yun.Lei
15 | * 功能:
16 | * 创建日期:2018-10-18 17:14
17 | * 修改人:
18 | * 修改时间:
19 | * 修改备注:
20 | */
21 | class ApiCallBack(val result: BaseResult.() -> Unit) : Callback> {
22 |
23 | override fun onResponse(call: Call>, response: Response>) {
24 | val code = response.code()
25 | if (code in 200..299) {
26 | val errorCode = response.body()?.errorCode
27 | if (errorCode == -1001) { //需要重新登录
28 | App.instance.user = null
29 | } else {
30 | response.body()!!.result()
31 | }
32 | } else {
33 | onFailure(call, RuntimeException("response error,detail = " + response.raw().toString()))
34 | }
35 | }
36 |
37 | override fun onFailure(call: Call>, throwable: Throwable) {
38 | val error = when (throwable) {
39 | is SocketTimeoutException -> "网络不给力!"
40 | is ConnectException -> "当前的网络不通!"
41 | is UnknownHostException -> "当前的网络不通!"
42 | else -> "当前服务异常!"
43 | //可进一步细分错误类型
44 | }
45 | BaseResult().apply {
46 | errorCode = -1
47 | errorMsg = error
48 | }.result()
49 | }
50 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/net/ApiHelper.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.net
2 |
3 | import com.githubly.wanandroid.BuildConfig
4 | import okhttp3.OkHttpClient
5 | import okhttp3.logging.HttpLoggingInterceptor
6 | import retrofit2.Retrofit
7 | import retrofit2.converter.gson.GsonConverterFactory
8 | import java.util.concurrent.TimeUnit
9 |
10 | /**
11 | * 类名:ApiHelper
12 | * 作者:Yun.Lei
13 | * 功能:
14 | * 创建日期:2018-10-18 16:19
15 | * 修改人:
16 | * 修改时间:
17 | * 修改备注:
18 | */
19 | object ApiHelper {
20 |
21 | val api: ApiService
22 |
23 | init {
24 | val builder = OkHttpClient.Builder()
25 | builder.apply {
26 | connectTimeout(10, TimeUnit.SECONDS)
27 | readTimeout(10, TimeUnit.SECONDS)
28 | writeTimeout(10, TimeUnit.SECONDS)
29 | retryOnConnectionFailure(true)
30 | addInterceptor(HttpLoggingInterceptor().apply {
31 | level = if (BuildConfig.DEBUG)
32 | HttpLoggingInterceptor.Level.BODY
33 | else
34 | HttpLoggingInterceptor.Level.NONE
35 | })
36 | addInterceptor(ReadCookiesInterceptor())
37 | addInterceptor(SaveCookiesInterceptor())
38 | }
39 | val retrofitBuilder = Retrofit.Builder()
40 | .baseUrl("http://wanandroid.com")
41 | .addConverterFactory(GsonConverterFactory.create())
42 | .client(builder.build())
43 | val retrofit = retrofitBuilder.build()
44 | api = retrofit.create(ApiService::class.java)
45 | }
46 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/net/ApiService.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.net
2 |
3 | import com.githubly.wanandroid.model.*
4 | import retrofit2.Call
5 | import retrofit2.http.*
6 |
7 | /**
8 | * 类名:ApiService
9 | * 作者:Yun.Lei
10 | * 功能:
11 | * 创建日期:2018-10-18 16:59
12 | * 修改人:
13 | * 修改时间:
14 | * 修改备注:
15 | */
16 | interface ApiService {
17 |
18 | //获取最新项目
19 | @GET("/article/listproject/{page}/json")
20 | fun getLatestProjects(@Path("page") page: Int): Call>>
21 |
22 |
23 | //获取项目
24 | @GET("/project/list/{page}/json")
25 | fun getProjects(@Path("page") page: Int, @Query("cid") cid: Int): Call>>
26 |
27 | //首页banner
28 | @GET("/banner/json")
29 | fun getBanner(): Call>>
30 |
31 | //首页文章列表
32 | @GET("/article/list/{page}/json")
33 | fun getHomeArticles(@Path("page") page: Int): Call>>
34 |
35 | //查看某个公众号历史数据
36 | @GET("/wxarticle/list/{userID}/{page}/json")
37 | fun getWXArticle(@Path("userID") userID: Int, @Path("page") page: Int): Call>>
38 |
39 | //登录
40 | @FormUrlEncoded
41 | @POST("/user/login")
42 | fun login(@Field("username") username: String, @Field("password") password: String): Call>
43 |
44 | //注册
45 | @FormUrlEncoded
46 | @POST("/user/register")
47 | fun register(@Field("username") username: String,
48 | @Field("password") password: String,
49 | @Field("repassword") repassword: String): Call>
50 |
51 | //退出登录
52 | @GET("/user/logout/json")
53 | fun logout(): Call>
54 |
55 | //收藏文章列表
56 | @GET("/lg/collect/list/{page}/json")
57 | fun getCollectList(@Path("page") page: Int): Call>>
58 |
59 | //收藏文章
60 | @POST("/lg/collect/{id}/json")
61 | fun collect(@Path("id") id: Int): Call>
62 |
63 | //取消收藏文章
64 | @POST("/lg/uncollect_originId/{id}/json")
65 | fun uncollect(@Path("id") id: Int): Call>
66 |
67 | //取消收藏文章--收藏页面
68 | @FormUrlEncoded
69 | @POST("/lg/uncollect/{id}/json")
70 | fun unCollectPage(@Path("id") id: Int, @Field("originId") originId: Int): Call>
71 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/net/ReadCookiesInterceptor.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.net
2 |
3 | import com.githubly.wanandroid.utils.UserInfoHelper
4 | import okhttp3.Interceptor
5 | import okhttp3.Response
6 | import java.io.IOException
7 |
8 | /**
9 | * 读取cookie并设置
10 | */
11 | class ReadCookiesInterceptor : Interceptor {
12 |
13 | @Throws(IOException::class)
14 | override fun intercept(chain: Interceptor.Chain): Response {
15 | val builder = chain.request().newBuilder()
16 | val preferences = UserInfoHelper.getCookie()
17 | preferences?.let {
18 | for (cookie in preferences) {
19 | builder.addHeader("Cookie", cookie)
20 | }
21 | }
22 | return chain.proceed(builder.build())
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/net/SaveCookiesInterceptor.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.net
2 |
3 | import com.githubly.wanandroid.utils.UserInfoHelper
4 | import okhttp3.Interceptor
5 | import okhttp3.Response
6 | import java.io.IOException
7 | import java.util.*
8 |
9 | /**
10 | * 保存Cookie
11 | */
12 | class SaveCookiesInterceptor : Interceptor {
13 | @Throws(IOException::class)
14 | override fun intercept(chain: Interceptor.Chain): Response {
15 | val originalResponse = chain.proceed(chain.request())
16 | if (!originalResponse.headers("Set-Cookie").isEmpty()) {
17 | val cookies = HashSet()
18 | for (header in originalResponse.headers("Set-Cookie")) {
19 | cookies.add(header)
20 | }
21 | UserInfoHelper.saveCookie(cookies)
22 | }
23 | return originalResponse
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/presenter/ArticlePagePresenter.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.presenter
2 |
3 | import com.githubly.wanandroid.contract.IArticlePageContract
4 | import com.githubly.wanandroid.net.ApiCallBack
5 | import com.githubly.wanandroid.net.ApiHelper
6 | import com.githubly.wanandroid.presenter.base.BasePresenter
7 |
8 | /**
9 | * 类名:ArticlePagePresenter
10 | * 作者:Yun.Lei
11 | * 功能:
12 | * 创建日期:2018-10-19 17:12
13 | * 修改人:
14 | * 修改时间:
15 | * 修改备注:
16 | */
17 | class ArticlePagePresenter(view: IArticlePageContract.View) : BasePresenter(view), IArticlePageContract.Presenter {
18 |
19 | override fun getWXArticle(userID: Int, page: Int) {
20 | ApiHelper.api.getWXArticle(userID, page).enqueue(ApiCallBack {
21 | if (isSuccess) {
22 | mView?.onArticleSuccess(data!!)
23 | } else {
24 | mView?.onArticleFailed(errorMsg)
25 | }
26 | })
27 | }
28 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/presenter/CollectListPresenter.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.presenter
2 |
3 | import com.githubly.wanandroid.contract.ICollectListContract
4 | import com.githubly.wanandroid.net.ApiCallBack
5 | import com.githubly.wanandroid.net.ApiHelper
6 | import com.githubly.wanandroid.presenter.base.BasePresenter
7 |
8 | /**
9 | * 类名:CollectListPresenter
10 | * 作者:Yun.Lei
11 | * 功能:
12 | * 创建日期:2018-10-22 17:48
13 | * 修改人:
14 | * 修改时间:
15 | * 修改备注:
16 | */
17 | class CollectListPresenter(view: ICollectListContract.View) : BasePresenter(view), ICollectListContract.Presenter {
18 | override fun getCollectList(page: Int) {
19 | ApiHelper.api.getCollectList(page - 1).enqueue(ApiCallBack {
20 | if (isSuccess) {
21 | data?.datas?.forEach {
22 | it.collect = true
23 | }
24 | if (data?.datas?.isEmpty() == true) {
25 | mView?.onListFailed("暂无收藏数据!")
26 | } else {
27 | mView?.onListSuccess(data!!)
28 | }
29 | } else {
30 | mView?.onListFailed(errorMsg)
31 | }
32 | })
33 | }
34 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/presenter/ContentPresenter.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.presenter
2 |
3 | import com.githubly.wanandroid.contract.IContentContract
4 | import com.githubly.wanandroid.net.ApiCallBack
5 | import com.githubly.wanandroid.net.ApiHelper
6 | import com.githubly.wanandroid.presenter.base.BasePresenter
7 |
8 | /**
9 | * 类名:ContentPresenter
10 | * 作者:Yun.Lei
11 | * 功能:
12 | * 创建日期:2018-10-23 16:16
13 | * 修改人:
14 | * 修改时间:
15 | * 修改备注:
16 | */
17 | class ContentPresenter(view: IContentContract.View) :
18 | BasePresenter(view), IContentContract.Presenter {
19 | override fun articleCollect(id: Int) {
20 | ApiHelper.api.collect(id).enqueue(ApiCallBack {
21 | if (isSuccess) {
22 | mView?.onCollectSuccess()
23 | } else {
24 | mView?.onCollectFailed(errorMsg)
25 | }
26 | })
27 | }
28 |
29 | override fun articleUncollect(id: Int) {
30 | ApiHelper.api.uncollect(id).enqueue(ApiCallBack{
31 | if (isSuccess) {
32 | mView?.onUncollectSuccess()
33 | } else {
34 | mView?.onUncollectFailed(errorMsg)
35 | }
36 | })
37 | }
38 |
39 | override fun articleUncollectPage(id: Int,originId:Int) {
40 | ApiHelper.api.unCollectPage(id,originId).enqueue(ApiCallBack{
41 | if (isSuccess) {
42 | mView?.onUncollectPageSuccess()
43 | } else {
44 | mView?.onUncollectPageFailed(errorMsg)
45 | }
46 | })
47 | }
48 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/presenter/HomePresenter.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.presenter
2 |
3 | import com.githubly.wanandroid.contract.IHomeContract
4 | import com.githubly.wanandroid.net.ApiCallBack
5 | import com.githubly.wanandroid.net.ApiHelper
6 | import com.githubly.wanandroid.presenter.base.BasePresenter
7 |
8 | /**
9 | * 类名:HomePresenter
10 | * 作者:Yun.Lei
11 | * 功能:
12 | * 创建日期:2018-10-19 11:32
13 | * 修改人:
14 | * 修改时间:
15 | * 修改备注:
16 | */
17 | class HomePresenter(view: IHomeContract.View) :
18 | BasePresenter(view), IHomeContract.Presenter {
19 | override fun getHomeArticle(page: Int) {
20 | //page 从1开始 接口Index 从0开始
21 | ApiHelper.api.getHomeArticles(page-1).enqueue(ApiCallBack {
22 | if (isSuccess) {
23 | mView?.onArticleSuccess(data!!)
24 | } else {
25 | mView?.onArticleFailed(errorMsg)
26 | }
27 | })
28 | }
29 |
30 | override fun getBanner() {
31 | ApiHelper.api.getBanner().enqueue(ApiCallBack {
32 | if (isSuccess) {
33 | mView?.onBannerSuccess(data ?: mutableListOf())
34 | } else {
35 | mView?.onBannerFailed(errorMsg)
36 | }
37 | })
38 | }
39 |
40 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/presenter/LoginPresenter.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.presenter
2 |
3 | import com.githubly.wanandroid.contract.ILoginContract
4 | import com.githubly.wanandroid.net.ApiCallBack
5 | import com.githubly.wanandroid.net.ApiHelper
6 | import com.githubly.wanandroid.presenter.base.BasePresenter
7 |
8 | /**
9 | * 类名:LoginPresenter
10 | * 作者:Yun.Lei
11 | * 功能:
12 | * 创建日期:2018-10-22 14:44
13 | * 修改人:
14 | * 修改时间:
15 | * 修改备注:
16 | */
17 | class LoginPresenter(view: ILoginContract.View) :
18 | BasePresenter(view), ILoginContract.Presenter {
19 | override fun register(userName: String, password: String, rePassword: String) {
20 | ApiHelper.api.register(userName, password, rePassword).enqueue(ApiCallBack {
21 | if (isSuccess) {
22 | mView?.onRegisterSuccess(data!!)
23 | } else {
24 | mView?.onRegisterFailed(errorMsg)
25 | }
26 | })
27 | }
28 |
29 | override fun login(userName: String, password: String) {
30 | ApiHelper.api.login(userName, password).enqueue(ApiCallBack {
31 | if (isSuccess) {
32 | mView?.onLoginSuccess(data!!)
33 | } else {
34 | mView?.onLoginFailed(errorMsg)
35 | }
36 |
37 | })
38 | }
39 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/presenter/LogoutPresenter.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.presenter
2 |
3 | import com.githubly.wanandroid.contract.ILogoutContract
4 | import com.githubly.wanandroid.net.ApiCallBack
5 | import com.githubly.wanandroid.net.ApiHelper
6 | import com.githubly.wanandroid.presenter.base.BasePresenter
7 |
8 | /**
9 | * 类名:LogoutPresenter
10 | * 作者:Yun.Lei
11 | * 功能:
12 | * 创建日期:2018-10-22 16:40
13 | * 修改人:
14 | * 修改时间:
15 | * 修改备注:
16 | */
17 | class LogoutPresenter(view: ILogoutContract.View) :
18 | BasePresenter(view),ILogoutContract.Presenter {
19 | override fun logout() {
20 | ApiHelper.api.logout().enqueue(ApiCallBack{
21 | if (isSuccess){
22 | mView?.onLogoutSuccess()
23 | }else{
24 | mView?.onLogoutFailed(errorMsg)
25 | }
26 | })
27 | }
28 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/presenter/ProjectPagePresenter.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.presenter
2 |
3 | import com.githubly.wanandroid.contract.IProjectPageContract
4 | import com.githubly.wanandroid.net.ApiCallBack
5 | import com.githubly.wanandroid.net.ApiHelper
6 | import com.githubly.wanandroid.presenter.base.BasePresenter
7 |
8 | /**
9 | * 类名:ProjectPagePresenter
10 | * 作者:Yun.Lei
11 | * 功能:
12 | * 创建日期:2018-10-19 17:12
13 | * 修改人:
14 | * 修改时间:
15 | * 修改备注:
16 | */
17 | class ProjectPagePresenter(view: IProjectPageContract.View) : BasePresenter(view), IProjectPageContract.Presenter {
18 |
19 |
20 | override fun getProjectArticle(userID: Int, page: Int) {
21 | if (userID == 99999) {
22 | //接口兼容 page 1 index = 0
23 | ApiHelper.api.getLatestProjects(page-1).enqueue(ApiCallBack {
24 | if (isSuccess) {
25 | mView?.onArticleSuccess(data!!)
26 | } else {
27 | mView?.onArticleFailed(errorMsg)
28 | }
29 | })
30 | } else {
31 | ApiHelper.api.getProjects(page, userID).enqueue(ApiCallBack {
32 | if (isSuccess) {
33 | mView?.onArticleSuccess(data!!)
34 | } else {
35 | mView?.onArticleFailed(errorMsg)
36 | }
37 | })
38 | }
39 | }
40 |
41 |
42 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/presenter/base/BasePresenter.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.presenter.base
2 |
3 | /**
4 | * 类名:BasePresenter
5 | * 作者:Yun.Lei
6 | * 功能:
7 | * 创建日期:2018-07-13 10:40
8 | * 修改人:
9 | * 修改时间:
10 | * 修改备注:
11 | */
12 | abstract class BasePresenter(view: T) {
13 | protected var mView: T? = view
14 |
15 | fun onDestroy() {
16 | mView = null
17 | }
18 |
19 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/presenter/base/IView.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.presenter.base
2 |
3 | /**
4 | * 类名:IView
5 | * 作者:Yun.Lei
6 | * 功能:
7 | * 创建日期:2018-07-13 10:39
8 | * 修改人:
9 | * 修改时间:
10 | * 修改备注:
11 | */
12 | interface IView
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/utils/AppUtils.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.utils
2 |
3 | import android.content.Context
4 |
5 | /**
6 | * 类名:AppUtils
7 | * 作者:Yun.Lei
8 | * 功能:
9 | * 创建日期:2018-10-24 10:13
10 | * 修改人:
11 | * 修改时间:
12 | * 修改备注:
13 | */
14 | object AppUtils {
15 |
16 |
17 | /**
18 | * 获取版本名称
19 | *
20 | * @param context
21 | * @return
22 | */
23 | fun getVersionName(context: Context): String {
24 | var versionName = ""
25 | try {
26 | // 获取软件版本名称
27 | versionName = context.packageManager.getPackageInfo(
28 | context.packageName, 0).versionName
29 | } catch (e: Exception) {
30 | return versionName
31 | }
32 |
33 | return versionName
34 | }
35 |
36 | /**
37 | * 获取版本号
38 | *
39 | * @param context
40 | * @return
41 | */
42 | fun getVersionCode(context: Context): Int {
43 | // 获取软件版本号
44 | var versionCode = 0L
45 | try {
46 | versionCode = context.packageManager.getPackageInfo(context.packageName, 0).longVersionCode
47 | } catch (e: Exception) {
48 | return versionCode.toInt()
49 | }
50 |
51 | return versionCode.toInt()
52 | }
53 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/utils/BuglyFileProvider.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.utils
2 |
3 | import android.support.v4.content.FileProvider
4 |
5 | /**
6 | * 类名:BuglyFileProvider
7 | * 作者:Yun.Lei
8 | * 功能:
9 | * 创建日期:2018-10-23 19:59
10 | * 修改人:
11 | * 修改时间:
12 | * 修改备注:
13 | */
14 | class BuglyFileProvider:FileProvider()
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/utils/ContentUtil.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.utils
2 |
3 | import android.app.Activity
4 | import android.content.Context
5 | import android.content.Intent
6 | import android.graphics.Point
7 | import android.net.Uri
8 | import android.provider.Settings
9 | import android.support.v4.app.Fragment
10 | import android.view.View
11 | import android.view.WindowManager
12 | import android.view.inputmethod.InputMethodManager
13 | import org.jetbrains.anko.support.v4.act
14 |
15 |
16 | /**
17 | * 类名:ContentUtil
18 | * 作者:Yun.Lei
19 | * 功能:
20 | * 创建日期:2018-10-22 19:45
21 | * 修改人:
22 | * 修改时间:
23 | * 修改备注:
24 | */
25 |
26 | fun Activity.hideSoftInput(view: View = window.peekDecorView()) {
27 | val inputManger = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
28 | inputManger.hideSoftInputFromWindow(view.windowToken, 0)
29 | }
30 |
31 | fun Activity.showSoftInput(view: View = window.peekDecorView()) {
32 | val inputManger = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
33 | inputManger.showSoftInput(view, 0)
34 | }
35 |
36 | fun Fragment.hideSoftInput(view: View? = getView()) {
37 | if (view != null) {
38 | val inputManger = act.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
39 | inputManger.hideSoftInputFromWindow(view.windowToken, 0)
40 | }
41 | }
42 |
43 | fun Fragment.showSoftInput(view: View? = getView()) {
44 | val inputManger = act.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
45 | inputManger.showSoftInput(view, 0)
46 | }
47 |
48 | fun Context.toAppDetail(){
49 | val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
50 | intent.addCategory(Intent.CATEGORY_DEFAULT)
51 | intent.data = Uri.fromParts("package", packageName, null)
52 | startActivity(intent)
53 | }
54 | fun Fragment.toAppDetail(requestCode:Int = -1){
55 | val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
56 | intent.addCategory(Intent.CATEGORY_DEFAULT)
57 | intent.data = Uri.fromParts("package", activity?.packageName, null)
58 | startActivityForResult(intent,requestCode)
59 | }
60 | fun Activity.toAppDetail(requestCode:Int = -1){
61 | val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
62 | intent.addCategory(Intent.CATEGORY_DEFAULT)
63 | intent.data = Uri.fromParts("package", packageName, null)
64 | startActivityForResult(intent,requestCode)
65 | }
66 | /**
67 | * 屏幕宽度
68 | */
69 | fun Context.screenWidth(): Int {
70 | val vm = getSystemService(Context.WINDOW_SERVICE) as WindowManager
71 | val point = Point()
72 | vm.defaultDisplay.getSize(point)
73 | return point.x
74 | }
75 |
76 | /**
77 | * 屏幕高度
78 | */
79 | fun Context.screenHeight(): Int {
80 | val vm = getSystemService(Context.WINDOW_SERVICE) as WindowManager
81 | val point = Point()
82 | vm.defaultDisplay.getSize(point)
83 | return point.y
84 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/utils/DialogUtil.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.utils
2 |
3 |
4 |
5 | /**
6 | * 类名:DialogUtil
7 | * 作者:Yun.Lei
8 | * 功能:
9 | * 创建日期:2018-10-22 17:11
10 | * 修改人:
11 | * 修改时间:
12 | * 修改备注:
13 | */
14 |
15 | interface ILoading{
16 | fun showLoading(msg:String="")
17 | fun dismissLoading()
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/utils/FileUtils.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.utils
2 |
3 | import android.content.Context
4 | import java.io.BufferedReader
5 | import java.io.IOException
6 | import java.io.InputStreamReader
7 |
8 | /**
9 | * 类名:FileUtils
10 | * 作者:Yun.Lei
11 | * 功能:
12 | * 创建日期:2018-10-19 16:29
13 | * 修改人:
14 | * 修改时间:
15 | * 修改备注:
16 | */
17 | object FileUtils {
18 |
19 | /**
20 | * 从assets读取文本内容
21 | *
22 | * @param context
23 | * @param fileName
24 | * @return
25 | */
26 | fun getFromAssets(context: Context, fileName: String): String {
27 | val result = StringBuffer()
28 | var inputReader: InputStreamReader? = null
29 | var bufReader: BufferedReader? = null
30 | try {
31 | inputReader = InputStreamReader(context.resources.assets.open(fileName), "UTF-8")
32 | bufReader = BufferedReader(inputReader)
33 | bufReader.readLines().forEach {
34 | result.append(it)
35 | }
36 |
37 | } catch (e: Exception) {
38 | e.printStackTrace()
39 | } finally {
40 | try {
41 | inputReader?.close()
42 | bufReader?.close()
43 | } catch (e: IOException) {
44 | e.printStackTrace()
45 | }
46 |
47 | }
48 | return result.toString().trim()
49 | }
50 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/utils/UserInfoHelper.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.utils
2 |
3 | import android.annotation.SuppressLint
4 | import android.content.Context
5 | import com.githubly.wanandroid.model.User
6 |
7 | @SuppressLint("StaticFieldLeak")
8 | /**
9 | * 类名:UserInfoHelper
10 | * 作者:Yun.Lei
11 | * 功能:
12 | * 创建日期:2018-10-22 12:56
13 | * 修改人:
14 | * 修改时间:
15 | * 修改备注:
16 | */
17 | object UserInfoHelper {
18 |
19 | private var ctx: Context? = null
20 |
21 | fun init(context: Context) {
22 | ctx = context.applicationContext
23 | }
24 |
25 | /**
26 | * 保存用户信息
27 | */
28 | fun saveUser(user: User) {
29 | val sp = ctx?.getSharedPreferences("user_info", Context.MODE_PRIVATE)
30 | sp?.edit()?.apply {
31 | putString("email", user.email)
32 | putString("icon", user.icon)
33 | putString("username", user.username)
34 | putString("password", user.password)
35 | putString("token", user.token)
36 | putInt("id", user.id)
37 | putInt("type", user.type)
38 | }?.apply()
39 | }
40 |
41 | /**
42 | * 获取保存的用户信息
43 | */
44 | fun getUser(): User? {
45 | val sp = ctx?.getSharedPreferences("user_info", Context.MODE_PRIVATE)
46 | val user = User(
47 | sp?.getString("email", "") ?: "",
48 | sp?.getString("icon", "") ?: "",
49 | sp?.getInt("id", -1) ?: -1,
50 | sp?.getString("password", "") ?: "",
51 | sp?.getString("token", "") ?: "",
52 | sp?.getInt("type", -1) ?: -1,
53 | sp?.getString("username", "") ?: ""
54 |
55 | )
56 | return if (user.id == -1) null else user
57 | }
58 |
59 | /**
60 | * 清除保存的用户信息
61 | */
62 | fun clearUser() {
63 | val sp = ctx?.getSharedPreferences("user_info", Context.MODE_PRIVATE)
64 | sp?.edit()?.clear()?.apply()
65 | }
66 |
67 |
68 | fun saveCookie(set:HashSet){
69 | val sp = ctx?.getSharedPreferences("user_info", Context.MODE_PRIVATE)
70 | sp?.edit()?.apply {
71 | putStringSet("cookie",set)
72 | }?.apply()
73 | }
74 |
75 | fun getCookie():HashSet?{
76 | val sp = ctx?.getSharedPreferences("user_info", Context.MODE_PRIVATE)
77 | return sp?.getStringSet("cookie", hashSetOf()) as HashSet?
78 | }
79 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/utils/ViewUtil.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.utils
2 |
3 | import android.widget.ImageView
4 | import com.bumptech.glide.Glide
5 | import com.bumptech.glide.request.RequestOptions
6 | import com.githubly.wanandroid.R
7 |
8 | /**
9 | * 类名:ImageViewUtil
10 | * 作者:Yun.Lei
11 | * 功能:
12 | * 创建日期:2018-10-19 11:44
13 | * 修改人:
14 | * 修改时间:
15 | * 修改备注:
16 | */
17 | fun ImageView?.loadImage(
18 | url: String,
19 | placeHolderRes: Int = R.mipmap.ic_empty_banner,
20 | errorRes: Int = R.mipmap.ic_empty_banner,
21 | fallbackRes: Int = R.mipmap.ic_empty_banner
22 | ) {
23 | if (this == null) return
24 | Glide.with(this)
25 | .load(url)
26 | .thumbnail(0.1f)
27 | .apply(RequestOptions().apply {
28 | placeholder(placeHolderRes)
29 | error(errorRes)
30 | fallback(fallbackRes)
31 | })
32 | .into(this)
33 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/widget/HackyViewPager.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.widget
2 |
3 | import android.content.Context
4 | import android.support.v4.view.ViewPager
5 | import android.util.AttributeSet
6 | import android.view.MotionEvent
7 | import com.githubly.wanandroid.R
8 |
9 | /**
10 | * 类名:HackyViewPager
11 | * 作者:Yun.Lei
12 | * 功能:
13 | * 创建日期:2017-10-24 17:38
14 | * 修改人:
15 | * 修改时间:
16 | * 修改备注:
17 | */
18 | class HackyViewPager : ViewPager {
19 |
20 | var isLock = false
21 |
22 | constructor(context: Context) : this(context, null)
23 | constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
24 | val a = context.obtainStyledAttributes(attrs, R.styleable.HackyViewPager, 0, 0)
25 | isLock = a.getBoolean(R.styleable.HackyViewPager_hvp_is_lock, false)
26 | a.recycle()
27 | }
28 |
29 | override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
30 | if (!isLock) {
31 | return try {
32 | super.onInterceptTouchEvent(ev)
33 | } catch (e: IllegalArgumentException) {
34 | e.printStackTrace()
35 | false
36 | }
37 |
38 | }
39 | return false
40 | }
41 |
42 | override fun onTouchEvent(event: MotionEvent): Boolean {
43 | return if (!isLock) {
44 | super.onTouchEvent(event)
45 | } else false
46 | }
47 |
48 | fun toggleLock() {
49 | isLock = !isLock
50 | }
51 |
52 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/widget/LoadingStateView.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.widget
2 |
3 | import android.content.Context
4 | import android.util.AttributeSet
5 | import android.view.View
6 | import android.widget.FrameLayout
7 | import com.githubly.wanandroid.R
8 | import kotlinx.android.synthetic.main.layout_page_state.view.*
9 |
10 | /**
11 | * 类名:LoadingStateView
12 | * 作者:Yun.Lei
13 | * 功能:
14 | * 创建日期:2018-10-22 19:07
15 | * 修改人:
16 | * 修改时间:
17 | * 修改备注:
18 | */
19 | class LoadingStateView : FrameLayout {
20 |
21 | constructor(context: Context) : super(context)
22 | constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
23 | constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
24 |
25 | private var mView: View = View.inflate(context, R.layout.layout_page_state, this)
26 |
27 |
28 | fun loading() {
29 | visibility = View.VISIBLE
30 | mView.loadingView.visibility = View.VISIBLE
31 | mView.errorView.visibility = View.GONE
32 | }
33 |
34 | fun success() {
35 | visibility = View.GONE
36 | }
37 |
38 | fun failed(msg: String = "加载失败") {
39 | visibility = View.VISIBLE
40 | mView.loadingView.visibility = View.GONE
41 | mView.errorView.visibility = View.VISIBLE
42 | mView.errorMsgTv.text = msg
43 | }
44 |
45 | fun setOnReloadClickListener(onClick:View.() -> Unit) {
46 | errorView.setOnClickListener{
47 | it.onClick()
48 | }
49 | }
50 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/widget/OtherBottomDialog.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.widget
2 |
3 | import android.app.Dialog
4 | import android.graphics.Color
5 | import android.graphics.drawable.ColorDrawable
6 | import android.os.Bundle
7 | import android.support.design.widget.BottomSheetDialogFragment
8 | import android.support.v4.app.DialogFragment
9 | import android.view.LayoutInflater
10 | import android.view.View
11 | import android.view.ViewGroup
12 | import com.githubly.wanandroid.R
13 | import kotlinx.android.synthetic.main.dialog_other_bottom.*
14 | import org.jetbrains.anko.support.v4.act
15 | import org.jetbrains.anko.support.v4.withArguments
16 |
17 | /**
18 | * 类名:OtherBottomDialog
19 | * 作者:Yun.Lei
20 | * 功能:
21 | * 创建日期:2018-10-23 15:05
22 | * 修改人:
23 | * 修改时间:
24 | * 修改备注:
25 | */
26 | const val TYPE_SHARE = 0
27 | const val TYPE_COLLECT = 1
28 | const val TYPE_COPY = 2
29 | const val TYPE_BROWSER = 3
30 |
31 | class OtherBottomDialog : BottomSheetDialogFragment() {
32 |
33 | companion object {
34 | fun getDialog(collect: Boolean): OtherBottomDialog {
35 | val dialog = OtherBottomDialog()
36 | dialog.withArguments("collect" to collect)
37 | return dialog
38 | }
39 | }
40 |
41 | var onItemClick: (type: Int) -> Unit = {}
42 | private var collect: Boolean = false
43 |
44 | override fun onCreate(savedInstanceState: Bundle?) {
45 | super.onCreate(savedInstanceState)
46 | setStyle(DialogFragment.STYLE_NO_TITLE, R.style.style_common_dialog)
47 | collect = arguments?.getBoolean("collect") ?: false
48 | }
49 |
50 | override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
51 | val dialog = super.onCreateDialog(savedInstanceState)
52 | dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
53 | return dialog
54 | }
55 |
56 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
57 | return inflater.inflate(R.layout.dialog_other_bottom, container, false)
58 | }
59 |
60 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
61 | super.onViewCreated(view, savedInstanceState)
62 | btnCancel.setOnClickListener {
63 | dismiss()
64 | }
65 | collectImageView.setColorFilter(act.resources.getColor(if (collect) R.color.red else R.color.black))
66 | collectTV.text = if (collect) "取消收藏" else "收藏"
67 | btnShare.setOnClickListener {
68 | onItemClick(TYPE_SHARE)
69 | }
70 | btnCollect.setOnClickListener {
71 | onItemClick(TYPE_COLLECT)
72 | }
73 | btnCopy.setOnClickListener {
74 | onItemClick(TYPE_COPY)
75 | }
76 | btnBrowser.setOnClickListener {
77 | onItemClick(TYPE_BROWSER)
78 | }
79 | }
80 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/githubly/wanandroid/widget/ScrollTextView.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid.widget
2 |
3 | import android.content.Context
4 | import android.text.TextUtils
5 | import android.util.AttributeSet
6 |
7 | /**
8 | * 类名:ScrollTextView
9 | * 作者:Yun.Lei
10 | * 功能:
11 | * 创建日期:2018-10-18 19:10
12 | * 修改人:
13 | * 修改时间:
14 | * 修改备注:
15 | */
16 | class ScrollTextView : android.support.v7.widget.AppCompatTextView {
17 |
18 | constructor(context: Context?) : super(context)
19 | constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
20 | constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
21 |
22 | init {
23 | ellipsize = TextUtils.TruncateAt.MARQUEE
24 | marqueeRepeatLimit = -1
25 | setSingleLine(true)
26 | }
27 |
28 | override fun isFocused(): Boolean {
29 | return true
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/res/color/color_main_page_bottom_tab.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/color/selector_back.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/color_cursor.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
10 |
12 |
14 |
16 |
18 |
20 |
22 |
24 |
26 |
28 |
30 |
32 |
34 |
36 |
38 |
40 |
42 |
44 |
46 |
48 |
50 |
52 |
54 |
56 |
58 |
60 |
62 |
64 |
66 |
68 |
70 |
72 |
74 |
75 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/line_et_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/line_et_focus.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 | -
12 |
13 |
14 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/line_et_normal.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 | -
12 |
13 |
14 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/progress_horizontal.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
6 |
7 |
8 |
9 |
10 |
11 | -
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | -
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/selector_banner_point.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/selector_tab_article.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/selector_tab_category.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/selector_tab_home.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/selector_tab_my.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_head_blue.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_head_green.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_head_orange.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_head_red.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_login_btn.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_other_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_other_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_project_collect.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_round_3dp_ebebeb.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_update_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_user_head.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/splash.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/font/font_title.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/font/font_title.ttf
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_collect_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
18 |
19 |
26 |
27 |
34 |
35 |
36 |
37 |
42 |
43 |
48 |
49 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_login.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
17 |
18 |
25 |
26 |
33 |
34 |
35 |
36 |
41 |
42 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
16 |
17 |
25 |
26 |
32 |
33 |
38 |
39 |
40 |
46 |
47 |
52 |
53 |
54 |
55 |
62 |
63 |
68 |
69 |
70 |
76 |
77 |
82 |
83 |
84 |
85 |
90 |
91 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_splash.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
19 |
20 |
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_web.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
17 |
18 |
25 |
26 |
35 |
36 |
46 |
47 |
56 |
57 |
67 |
68 |
69 |
70 |
75 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/dialog_other_bottom.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
21 |
22 |
28 |
29 |
36 |
37 |
38 |
45 |
46 |
53 |
54 |
62 |
63 |
64 |
71 |
72 |
78 |
79 |
86 |
87 |
88 |
95 |
96 |
102 |
103 |
110 |
111 |
112 |
113 |
121 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_article.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
13 |
14 |
26 |
27 |
41 |
42 |
43 |
48 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_article_page.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
11 |
12 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_home.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
13 |
14 |
25 |
26 |
27 |
31 |
32 |
37 |
38 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_project.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
13 |
14 |
26 |
27 |
41 |
42 |
43 |
48 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_project_page.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
13 |
14 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_home_article.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
23 |
24 |
25 |
36 |
37 |
49 |
50 |
64 |
65 |
80 |
81 |
90 |
91 |
104 |
105 |
112 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_project.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
15 |
16 |
20 |
21 |
27 |
28 |
39 |
40 |
47 |
48 |
58 |
59 |
60 |
71 |
72 |
81 |
82 |
83 |
92 |
93 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_wx_article.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
15 |
28 |
29 |
30 |
41 |
42 |
54 |
55 |
71 |
72 |
82 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_home_banner.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
23 |
24 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_page_state.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
12 |
13 |
20 |
21 |
25 |
26 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/upgrade_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
18 |
19 |
24 |
25 |
29 |
30 |
38 |
39 |
40 |
47 |
48 |
55 |
56 |
64 |
65 |
72 |
73 |
81 |
85 |
88 |
89 |
98 |
102 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/upgrade_tips_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
18 |
19 |
24 |
25 |
29 |
30 |
38 |
39 |
40 |
47 |
48 |
55 |
56 |
57 |
65 |
66 |
70 |
71 |
74 |
75 |
84 |
85 |
89 |
90 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_about.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xhdpi/ic_about.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_android.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xhdpi/ic_android.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xhdpi/ic_arrow.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_back_def.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xhdpi/ic_back_def.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_banner_point.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xhdpi/ic_banner_point.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_banner_point_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xhdpi/ic_banner_point_selected.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_browser.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xhdpi/ic_browser.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_clear.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xhdpi/ic_clear.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xhdpi/ic_close.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_collect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xhdpi/ic_collect.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_collect_tag.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xhdpi/ic_collect_tag.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_copy_url.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xhdpi/ic_copy_url.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_empty.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xhdpi/ic_empty.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_empty_banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xhdpi/ic_empty_banner.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_head_default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xhdpi/ic_head_default.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_heart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xhdpi/ic_heart.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_knowledge_system.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xhdpi/ic_knowledge_system.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_login_bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xhdpi/ic_login_bg.jpg
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_other.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xhdpi/ic_other.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_search_article.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xhdpi/ic_search_article.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_share.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xhdpi/ic_share.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_tag.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xhdpi/ic_tag.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_todo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xhdpi/ic_todo.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_update.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xhdpi/ic_update.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_article.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xxhdpi/ic_article.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_article_fill.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xxhdpi/ic_article_fill.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_category.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xxhdpi/ic_category.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_category_fill.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xxhdpi/ic_category_fill.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xxhdpi/ic_home.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_home_fill.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xxhdpi/ic_home_fill.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_me.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xxhdpi/ic_me.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_me_fill.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/app/src/main/res/mipmap-xxhdpi/ic_me_fill.png
--------------------------------------------------------------------------------
/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #008577
4 | #00574B
5 | #D81B60
6 | #ffffff
7 | #333333
8 | #19000000
9 | #33000000
10 | #66000000
11 | #99000000
12 | #cc000000
13 | #11333333
14 | #222222
15 | #666666
16 | #999999
17 | #cccccc
18 | #D8D8D8
19 | #f8f8f8
20 | #ff4444
21 | #54b3b3
22 | #4d92dc
23 | #ff8635
24 | @android:color/transparent
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 48dp
5 | 12sp
6 | 14sp
7 | 16sp
8 | 18sp
9 | 20sp
10 | 1px
11 | 1dp
12 | 2dp
13 | 3dp
14 | 4dp
15 | 5dp
16 | 6dp
17 | 7dp
18 | 8dp
19 | 9dp
20 | 10dp
21 | 11dp
22 | 12dp
23 | 13dp
24 | 14dp
25 | 15dp
26 | 16dp
27 | 17dp
28 | 18dp
29 | 19dp
30 | 20dp
31 | 21dp
32 | 22dp
33 | 23dp
34 | 24dp
35 | 25dp
36 | 26dp
37 | 27dp
38 | 28dp
39 | 29dp
40 | 30dp
41 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | 玩Android
3 | 我的收藏
4 | 登录/注册
5 | 首页
6 | 文章
7 | 项目
8 | 我的
9 | 分享
10 | 收藏
11 | 复制链接
12 | 浏览器打开
13 | 取消
14 | TODO工具
15 | 知识体系
16 | 更新
17 | 关于
18 | 退出登录
19 | 已收藏
20 | 搜索
21 | 登录
22 | 注册
23 | 用户名
24 | 密码
25 | 确认密码
26 | 加载失败
27 | 确定
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
18 |
19 |
33 |
34 |
47 |
48 |
51 |
52 |
55 |
56 |
--------------------------------------------------------------------------------
/app/src/test/java/com/githubly/wanandroid/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.githubly.wanandroid
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/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.2.71'
5 | ext.anko_version='0.10.7'
6 | repositories {
7 | google()
8 | jcenter()
9 | maven { url "https://jitpack.io" }
10 | maven { url 'http://oss.jfrog.org/artifactory/oss-snapshot-local/' }
11 | }
12 | dependencies {
13 | classpath 'com.android.tools.build:gradle:3.2.1'
14 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
15 | classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"
16 | // NOTE: Do not place your application dependencies here; they belong
17 | // in the individual module build.gradle files
18 | }
19 | }
20 |
21 | allprojects {
22 | repositories {
23 | google()
24 | jcenter()
25 | }
26 | }
27 |
28 | task clean(type: Delete) {
29 | delete rootProject.buildDir
30 | }
31 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # Kotlin code style for this project: "official" or "obsolete":
15 | kotlin.code.style=official
16 |
17 | ALIAS_NAME = wanandroid
18 | ALIAS_PWD = 123456
19 | KEY_PATH = ../wanAndroid.jks
20 | KEY_PWD = 123456
21 |
22 | BUGLY_ID = "aad59a037f"
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/screenshot/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/screenshot/1.png
--------------------------------------------------------------------------------
/screenshot/10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/screenshot/10.png
--------------------------------------------------------------------------------
/screenshot/11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/screenshot/11.png
--------------------------------------------------------------------------------
/screenshot/12.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/screenshot/12.jpg
--------------------------------------------------------------------------------
/screenshot/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/screenshot/2.png
--------------------------------------------------------------------------------
/screenshot/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/screenshot/3.png
--------------------------------------------------------------------------------
/screenshot/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/screenshot/4.png
--------------------------------------------------------------------------------
/screenshot/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/screenshot/5.png
--------------------------------------------------------------------------------
/screenshot/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/screenshot/6.png
--------------------------------------------------------------------------------
/screenshot/7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/screenshot/7.png
--------------------------------------------------------------------------------
/screenshot/8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/screenshot/8.png
--------------------------------------------------------------------------------
/screenshot/9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/screenshot/9.png
--------------------------------------------------------------------------------
/screenshot/QRCode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/screenshot/QRCode.png
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/wanAndroid.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leiyun-studio/WanAndroid/abd7c07203f9e03e40ce436f23c4086913a0b0ec/wanAndroid.jks
--------------------------------------------------------------------------------