├── .gitignore ├── .idea ├── .name ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── findbugs-idea.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── rx │ │ └── dong │ │ └── com │ │ └── rxjoke │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── rx │ │ │ └── dong │ │ │ └── com │ │ │ └── rxjoke │ │ │ ├── BaseApp.java │ │ │ ├── api │ │ │ ├── JokeApi.java │ │ │ └── RxService.java │ │ │ ├── common │ │ │ ├── AutoLoadRecylerView.java │ │ │ └── DividerItemDecoration.java │ │ │ ├── model │ │ │ ├── ContentlistEntity.java │ │ │ └── JokeEntity.java │ │ │ ├── presenter │ │ │ ├── BasePresenter.java │ │ │ ├── JokePresenter.java │ │ │ └── Presenter.java │ │ │ ├── ui │ │ │ ├── BaseActivity.java │ │ │ ├── activity │ │ │ │ └── MainActivity.java │ │ │ ├── adapter │ │ │ │ └── JokeAdapter.java │ │ │ └── view │ │ │ │ ├── JokeView.java │ │ │ │ └── MvpView.java │ │ │ └── util │ │ │ └── TimeUtil.java │ └── res │ │ ├── drawable-xhdpi │ │ └── app_copyright_jdd.png │ │ ├── drawable │ │ ├── button_stroke.xml │ │ └── list_divider.xml │ │ ├── layout │ │ ├── activity_main.xml │ │ ├── common_error.xml │ │ ├── joke_list_item.xml │ │ └── recycle_view_content.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── rx │ └── dong │ └── com │ └── rxjoke │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | <<<<<<< HEAD 2 | *.iml 3 | .gradle 4 | /local.properties 5 | /.idea/workspace.xml 6 | /.idea/libraries 7 | .DS_Store 8 | /build 9 | /captures 10 | ======= 11 | # Built application files 12 | *.apk 13 | *.ap_ 14 | 15 | # Files for the Dalvik VM 16 | *.dex 17 | 18 | # Java class files 19 | *.class 20 | 21 | # Generated files 22 | bin/ 23 | gen/ 24 | 25 | # Gradle files 26 | .gradle/ 27 | build/ 28 | /*/build/ 29 | 30 | # Local configuration file (sdk path, etc) 31 | local.properties 32 | 33 | # Proguard folder generated by Eclipse 34 | proguard/ 35 | 36 | # Log Files 37 | *.log 38 | >>>>>>> 85da73e14f8586b2cc9035e036f4e9d6b5db4011 39 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | RxJoke -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/findbugs-idea.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 32 | 203 | 216 | 225 | 226 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | 47 | 48 | 49 | 50 | 1.8 51 | 52 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, and 10 | distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by the copyright 13 | owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all other entities 16 | that control, are controlled by, or are under common control with that entity. 17 | For the purposes of this definition, "control" means (i) the power, direct or 18 | indirect, to cause the direction or management of such entity, whether by 19 | contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the 20 | outstanding shares, or (iii) beneficial ownership of such entity. 21 | 22 | "You" (or "Your") shall mean an individual or Legal Entity exercising 23 | permissions granted by this License. 24 | 25 | "Source" form shall mean the preferred form for making modifications, including 26 | but not limited to software source code, documentation source, and configuration 27 | files. 28 | 29 | "Object" form shall mean any form resulting from mechanical transformation or 30 | translation of a Source form, including but not limited to compiled object code, 31 | generated documentation, and conversions to other media types. 32 | 33 | "Work" shall mean the work of authorship, whether in Source or Object form, made 34 | available under the License, as indicated by a copyright notice that is included 35 | in or attached to the work (an example is provided in the Appendix below). 36 | 37 | "Derivative Works" shall mean any work, whether in Source or Object form, that 38 | is based on (or derived from) the Work and for which the editorial revisions, 39 | annotations, elaborations, or other modifications represent, as a whole, an 40 | original work of authorship. For the purposes of this License, Derivative Works 41 | shall not include works that remain separable from, or merely link (or bind by 42 | name) to the interfaces of, the Work and Derivative Works thereof. 43 | 44 | "Contribution" shall mean any work of authorship, including the original version 45 | of the Work and any modifications or additions to that Work or Derivative Works 46 | thereof, that is intentionally submitted to Licensor for inclusion in the Work 47 | by the copyright owner or by an individual or Legal Entity authorized to submit 48 | on behalf of the copyright owner. For the purposes of this definition, 49 | "submitted" means any form of electronic, verbal, or written communication sent 50 | to the Licensor or its representatives, including but not limited to 51 | communication on electronic mailing lists, source code control systems, and 52 | issue tracking systems that are managed by, or on behalf of, the Licensor for 53 | the purpose of discussing and improving the Work, but excluding communication 54 | that is conspicuously marked or otherwise designated in writing by the copyright 55 | owner as "Not a Contribution." 56 | 57 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf 58 | of whom a Contribution has been received by Licensor and subsequently 59 | incorporated within the Work. 60 | 61 | 2. Grant of Copyright License. 62 | 63 | Subject to the terms and conditions of this License, each Contributor hereby 64 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 65 | irrevocable copyright license to reproduce, prepare Derivative Works of, 66 | publicly display, publicly perform, sublicense, and distribute the Work and such 67 | Derivative Works in Source or Object form. 68 | 69 | 3. Grant of Patent License. 70 | 71 | Subject to the terms and conditions of this License, each Contributor hereby 72 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 73 | irrevocable (except as stated in this section) patent license to make, have 74 | made, use, offer to sell, sell, import, and otherwise transfer the Work, where 75 | such license applies only to those patent claims licensable by such Contributor 76 | that are necessarily infringed by their Contribution(s) alone or by combination 77 | of their Contribution(s) with the Work to which such Contribution(s) was 78 | submitted. If You institute patent litigation against any entity (including a 79 | cross-claim or counterclaim in a lawsuit) alleging that the Work or a 80 | Contribution incorporated within the Work constitutes direct or contributory 81 | patent infringement, then any patent licenses granted to You under this License 82 | for that Work shall terminate as of the date such litigation is filed. 83 | 84 | 4. Redistribution. 85 | 86 | You may reproduce and distribute copies of the Work or Derivative Works thereof 87 | in any medium, with or without modifications, and in Source or Object form, 88 | provided that You meet the following conditions: 89 | 90 | You must give any other recipients of the Work or Derivative Works a copy of 91 | this License; and 92 | You must cause any modified files to carry prominent notices stating that You 93 | changed the files; and 94 | You must retain, in the Source form of any Derivative Works that You distribute, 95 | all copyright, patent, trademark, and attribution notices from the Source form 96 | of the Work, excluding those notices that do not pertain to any part of the 97 | Derivative Works; and 98 | If the Work includes a "NOTICE" text file as part of its distribution, then any 99 | Derivative Works that You distribute must include a readable copy of the 100 | attribution notices contained within such NOTICE file, excluding those notices 101 | that do not pertain to any part of the Derivative Works, in at least one of the 102 | following places: within a NOTICE text file distributed as part of the 103 | Derivative Works; within the Source form or documentation, if provided along 104 | with the Derivative Works; or, within a display generated by the Derivative 105 | Works, if and wherever such third-party notices normally appear. The contents of 106 | the NOTICE file are for informational purposes only and do not modify the 107 | License. You may add Your own attribution notices within Derivative Works that 108 | You distribute, alongside or as an addendum to the NOTICE text from the Work, 109 | provided that such additional attribution notices cannot be construed as 110 | modifying the License. 111 | You may add Your own copyright statement to Your modifications and may provide 112 | additional or different license terms and conditions for use, reproduction, or 113 | distribution of Your modifications, or for any such Derivative Works as a whole, 114 | provided Your use, reproduction, and distribution of the Work otherwise complies 115 | with the conditions stated in this License. 116 | 117 | 5. Submission of Contributions. 118 | 119 | Unless You explicitly state otherwise, any Contribution intentionally submitted 120 | for inclusion in the Work by You to the Licensor shall be under the terms and 121 | conditions of this License, without any additional terms or conditions. 122 | Notwithstanding the above, nothing herein shall supersede or modify the terms of 123 | any separate license agreement you may have executed with Licensor regarding 124 | such Contributions. 125 | 126 | 6. Trademarks. 127 | 128 | This License does not grant permission to use the trade names, trademarks, 129 | service marks, or product names of the Licensor, except as required for 130 | reasonable and customary use in describing the origin of the Work and 131 | reproducing the content of the NOTICE file. 132 | 133 | 7. Disclaimer of Warranty. 134 | 135 | Unless required by applicable law or agreed to in writing, Licensor provides the 136 | Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, 137 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, 138 | including, without limitation, any warranties or conditions of TITLE, 139 | NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are 140 | solely responsible for determining the appropriateness of using or 141 | redistributing the Work and assume any risks associated with Your exercise of 142 | permissions under this License. 143 | 144 | 8. Limitation of Liability. 145 | 146 | In no event and under no legal theory, whether in tort (including negligence), 147 | contract, or otherwise, unless required by applicable law (such as deliberate 148 | and grossly negligent acts) or agreed to in writing, shall any Contributor be 149 | liable to You for damages, including any direct, indirect, special, incidental, 150 | or consequential damages of any character arising as a result of this License or 151 | out of the use or inability to use the Work (including but not limited to 152 | damages for loss of goodwill, work stoppage, computer failure or malfunction, or 153 | any and all other commercial damages or losses), even if such Contributor has 154 | been advised of the possibility of such damages. 155 | 156 | 9. Accepting Warranty or Additional Liability. 157 | 158 | While redistributing the Work or Derivative Works thereof, You may choose to 159 | offer, and charge a fee for, acceptance of support, warranty, indemnity, or 160 | other liability obligations and/or rights consistent with this License. However, 161 | in accepting such obligations, You may act only on Your own behalf and on Your 162 | sole responsibility, not on behalf of any other Contributor, and only if You 163 | agree to indemnify, defend, and hold each Contributor harmless for any liability 164 | incurred by, or claims asserted against, such Contributor by reason of your 165 | accepting any such warranty or additional liability. 166 | 167 | END OF TERMS AND CONDITIONS 168 | 169 | APPENDIX: How to apply the Apache License to your work 170 | 171 | To apply the Apache License to your work, attach the following boilerplate 172 | notice, with the fields enclosed by brackets "{}" replaced with your own 173 | identifying information. (Don't include the brackets!) The text should be 174 | enclosed in the appropriate comment syntax for the file format. We also 175 | recommend that a file or class name and description of purpose be included on 176 | the same "printed page" as the copyright notice for easier identification within 177 | third-party archives. 178 | 179 | Copyright 2016 JDD 180 | 181 | Licensed under the Apache License, Version 2.0 (the "License"); 182 | you may not use this file except in compliance with the License. 183 | You may obtain a copy of the License at 184 | 185 | http://www.apache.org/licenses/LICENSE-2.0 186 | 187 | Unless required by applicable law or agreed to in writing, software 188 | distributed under the License is distributed on an "AS IS" BASIS, 189 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 190 | See the License for the specific language governing permissions and 191 | limitations under the License. 192 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #RxJoke 2 | 3 | ---------- 4 | 5 | RxJoke是一个基于Rxjava,Retrofit,Dagger2和Mvp设计的一款App。 6 | 7 | [More info!](http://www.jianshu.com/p/9430eca553a5 "More info") 8 | 9 | ##项目结构 10 | * MVP框架。 11 | * dagger2来完成依赖注入。 12 | * retrofit2+rxjava实现restful的http请求。 13 | 14 | ##第三方类库 15 | * retrofit2 16 | * dagger2 17 | * butterknife 18 | * rxjava+rxandroid 19 | * leakcanary 20 | * glide 21 | * mvp 22 | * android support design 23 | 24 | ##截图 25 | 26 | 27 | 28 | 29 | 30 | 31 | ## License 32 | 33 | Copyright 2016 JDD 34 | 35 | Licensed under the Apache License, Version 2.0 (the "License"); 36 | you may not use this file except in compliance with the License. 37 | You may obtain a copy of the License at 38 | 39 | http://www.apache.org/licenses/LICENSE-2.0 40 | 41 | Unless required by applicable law or agreed to in writing, software 42 | distributed under the License is distributed on an "AS IS" BASIS, 43 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 44 | See the License for the specific language governing permissions and 45 | limitations under the License. 46 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.2" 6 | 7 | defaultConfig { 8 | applicationId "rx.dong.com.rxjoke" 9 | minSdkVersion 15 10 | targetSdkVersion 23 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(include: ['*.jar'], dir: 'libs') 24 | testCompile 'junit:junit:4.12' 25 | compile 'com.android.support:appcompat-v7:23.2.0' 26 | compile 'com.jakewharton:butterknife:7.0.1' 27 | compile 'com.orhanobut:logger:1.10' 28 | compile 'com.android.support:recyclerview-v7:23.2.0' 29 | //leakcanary 30 | debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1' 31 | // or 1.4-beta1 32 | releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1' 33 | // or 1.4-beta1 34 | testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1' 35 | // or 1.4-beta1 36 | //retrofit2 37 | compile 'com.squareup.retrofit2:retrofit:2.0.1' 38 | compile 'com.squareup.retrofit2:adapter-rxjava:2.0.1' 39 | compile 'com.squareup.retrofit2:converter-gson:2.0.1' 40 | compile 'com.google.code.gson:gson:2.6.2' 41 | //rxjava 42 | compile 'io.reactivex:rxjava:1.1.2' 43 | compile 'io.reactivex:rxandroid:1.1.0' 44 | //okhttp 45 | compile 'com.squareup.okhttp3:okhttp:3.2.0' 46 | compile 'com.squareup.okhttp3:logging-interceptor:3.2.0' 47 | 48 | } 49 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\Tools\Installed\AndroidSDK/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/rx/dong/com/rxjoke/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package rx.dong.com.rxjoke; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/java/rx/dong/com/rxjoke/BaseApp.java: -------------------------------------------------------------------------------- 1 | package rx.dong.com.rxjoke; 2 | 3 | import android.app.Application; 4 | 5 | import com.squareup.leakcanary.LeakCanary; 6 | 7 | /** 8 | * Created by JDD on 2016/4/8. 9 | */ 10 | public class BaseApp extends Application { 11 | @Override 12 | public void onCreate() { 13 | super.onCreate(); 14 | LeakCanary.install(this); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/rx/dong/com/rxjoke/api/JokeApi.java: -------------------------------------------------------------------------------- 1 | package rx.dong.com.rxjoke.api; 2 | 3 | import retrofit2.Call; 4 | import retrofit2.http.GET; 5 | import retrofit2.http.Header; 6 | import retrofit2.http.Headers; 7 | import retrofit2.http.Query; 8 | import rx.Observable; 9 | import rx.dong.com.rxjoke.model.JokeEntity; 10 | 11 | /** 12 | * Created by JDD on 2016/4/8. 13 | */ 14 | public interface JokeApi { 15 | 16 | @Headers("apikey:83ec99fff780989a5376a1bc595ed5ff") 17 | @GET("showapi_joke/joke_text") 18 | Observable getJoke(@Query("page") int page); 19 | 20 | @GET("showapi_joke/joke_text") 21 | Call callJoke(@Header("apikey") String apikey, @Query("page") int page); 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/rx/dong/com/rxjoke/api/RxService.java: -------------------------------------------------------------------------------- 1 | package rx.dong.com.rxjoke.api; 2 | 3 | import okhttp3.OkHttpClient; 4 | import okhttp3.logging.HttpLoggingInterceptor; 5 | import retrofit2.Retrofit; 6 | import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; 7 | import retrofit2.converter.gson.GsonConverterFactory; 8 | 9 | /** 10 | * Created by SkyEyesStion on 2016/2/26. 11 | */ 12 | public class RxService { 13 | private static final String BASETESTURL = "http://apis.baidu.com/showapi_open_bus/"; 14 | private static OkHttpClient okHttpClient = new OkHttpClient.Builder().addInterceptor 15 | (new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)).build(); 16 | private static Retrofit retrofit = new Retrofit.Builder() 17 | .baseUrl(BASETESTURL) 18 | .client(okHttpClient) 19 | .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) 20 | .addConverterFactory(GsonConverterFactory.create()) 21 | .build(); 22 | 23 | private RxService() { 24 | //construct 25 | 26 | } 27 | 28 | public static T createApi(Class clazz) { 29 | 30 | return retrofit.create(clazz); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/rx/dong/com/rxjoke/common/AutoLoadRecylerView.java: -------------------------------------------------------------------------------- 1 | package rx.dong.com.rxjoke.common; 2 | 3 | import android.content.Context; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.widget.LinearLayoutManager; 6 | import android.support.v7.widget.RecyclerView; 7 | import android.util.AttributeSet; 8 | 9 | /** 10 | * Created by JDD on 2016/4/8. 11 | */ 12 | public class AutoLoadRecylerView extends RecyclerView { 13 | private loadMoreListener loadMoreListener; 14 | private AutoLoadScroller autoLoadScroller; 15 | private boolean isLoading = false; 16 | 17 | public interface loadMoreListener { 18 | void onLoadMore(); 19 | } 20 | 21 | public AutoLoadRecylerView(Context context) { 22 | this(context, null); 23 | } 24 | 25 | 26 | public AutoLoadRecylerView(Context context, @Nullable AttributeSet attrs) { 27 | super(context, attrs); 28 | autoLoadScroller = new AutoLoadScroller(); 29 | addOnScrollListener(autoLoadScroller); 30 | } 31 | 32 | 33 | public void setLoadMoreListener(AutoLoadRecylerView.loadMoreListener loadMoreListener) { 34 | this.loadMoreListener = loadMoreListener; 35 | } 36 | 37 | public boolean isLoading() { 38 | return isLoading; 39 | } 40 | 41 | public void setLoading(boolean loading) { 42 | isLoading = loading; 43 | } 44 | 45 | public void removeAutoScroller() { 46 | removeOnScrollListener(autoLoadScroller); 47 | } 48 | 49 | private class AutoLoadScroller extends OnScrollListener { 50 | @Override 51 | public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 52 | super.onScrolled(recyclerView, dx, dy); 53 | if (getLayoutManager() instanceof LinearLayoutManager) { 54 | int lastVisiblePos = ((LinearLayoutManager) getLayoutManager()).findLastVisibleItemPosition(); 55 | int itemCount = getAdapter().getItemCount(); 56 | if (loadMoreListener != null && !isLoading && lastVisiblePos > itemCount - 2 && dy > 0) { 57 | loadMoreListener.onLoadMore(); 58 | isLoading = true; 59 | } 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /app/src/main/java/rx/dong/com/rxjoke/common/DividerItemDecoration.java: -------------------------------------------------------------------------------- 1 | package rx.dong.com.rxjoke.common; 2 | 3 | 4 | import android.content.Context; 5 | import android.graphics.Canvas; 6 | import android.graphics.Rect; 7 | import android.graphics.drawable.Drawable; 8 | import android.os.Build; 9 | import android.support.v7.widget.LinearLayoutManager; 10 | import android.support.v7.widget.RecyclerView; 11 | import android.view.View; 12 | 13 | import rx.dong.com.rxjoke.R; 14 | 15 | 16 | /** 17 | * 用于RecyclerView分割线 18 | * 19 | * @author lsxiao 20 | * @date 2015-11-05 00:27 21 | */ 22 | public class DividerItemDecoration extends RecyclerView.ItemDecoration { 23 | 24 | public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL; 25 | 26 | public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL; 27 | 28 | private Drawable mDivider; 29 | 30 | private int mOrientation; 31 | 32 | public DividerItemDecoration(Context context, int orientation) { 33 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 34 | mDivider = context.getDrawable(R.drawable.list_divider); 35 | } else 36 | mDivider = context.getResources().getDrawable(R.drawable.list_divider); 37 | setOrientation(orientation); 38 | } 39 | 40 | public void setOrientation(int orientation) { 41 | if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) { 42 | throw new IllegalArgumentException("invalid orientation"); 43 | } 44 | mOrientation = orientation; 45 | } 46 | 47 | @Override 48 | public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { 49 | if (mOrientation == VERTICAL_LIST) { 50 | drawVertical(c, parent); 51 | } else { 52 | drawHorizontal(c, parent); 53 | } 54 | } 55 | 56 | public void drawVertical(Canvas c, RecyclerView parent) { 57 | final int left = parent.getPaddingLeft(); 58 | final int right = parent.getWidth() - parent.getPaddingRight(); 59 | 60 | final int childCount = parent.getChildCount(); 61 | for (int i = 0; i < childCount; i++) { 62 | final View child = parent.getChildAt(i); 63 | final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child 64 | .getLayoutParams(); 65 | final int top = child.getBottom() + params.bottomMargin; 66 | final int bottom = top + mDivider.getIntrinsicHeight(); 67 | mDivider.setBounds(left, top, right, bottom); 68 | mDivider.draw(c); 69 | } 70 | } 71 | 72 | public void drawHorizontal(Canvas c, RecyclerView parent) { 73 | final int top = parent.getPaddingTop(); 74 | final int bottom = parent.getHeight() - parent.getPaddingBottom(); 75 | 76 | final int childCount = parent.getChildCount(); 77 | for (int i = 0; i < childCount; i++) { 78 | final View child = parent.getChildAt(i); 79 | final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child 80 | .getLayoutParams(); 81 | final int left = child.getRight() + params.rightMargin; 82 | final int right = left + mDivider.getIntrinsicHeight(); 83 | mDivider.setBounds(left, top, right, bottom); 84 | mDivider.draw(c); 85 | } 86 | } 87 | 88 | @Override 89 | public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State 90 | state) { 91 | if (mOrientation == VERTICAL_LIST) { 92 | outRect.set(0, 0, 0, mDivider.getIntrinsicHeight()); 93 | } else { 94 | outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0); 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /app/src/main/java/rx/dong/com/rxjoke/model/ContentlistEntity.java: -------------------------------------------------------------------------------- 1 | package rx.dong.com.rxjoke.model; 2 | 3 | /** 4 | * Created by JDD on 2016/4/23 0023. 5 | */ 6 | public class ContentlistEntity { 7 | private String ct; 8 | private String text; 9 | private String title; 10 | private int type; 11 | 12 | public String getCt() { 13 | return ct; 14 | } 15 | 16 | public void setCt(String ct) { 17 | this.ct = ct; 18 | } 19 | 20 | public String getText() { 21 | return text; 22 | } 23 | 24 | public void setText(String text) { 25 | this.text = text; 26 | } 27 | 28 | public String getTitle() { 29 | return title; 30 | } 31 | 32 | public void setTitle(String title) { 33 | this.title = title; 34 | } 35 | 36 | public int getType() { 37 | return type; 38 | } 39 | 40 | public void setType(int type) { 41 | this.type = type; 42 | } 43 | } -------------------------------------------------------------------------------- /app/src/main/java/rx/dong/com/rxjoke/model/JokeEntity.java: -------------------------------------------------------------------------------- 1 | package rx.dong.com.rxjoke.model; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Created by JDD on 2016/4/7. 7 | */ 8 | public class JokeEntity { 9 | /** 10 | * showapi_res_code : 0 11 | * showapi_res_error : 12 | * showapi_res_body : {"allNum":21320,"allPages":1066,"contentlist":[{"ct":"2016-04-08 13 | * 14:00:00.676","text":"今天在卫生间拉翔,进行中媳妇进来洗澡,我拉完翔就贱贱的伸出魔爪去摸咪咪,<\/p>

媳妇说:拉完也不洗手就来,咱娃还能喝上放心奶嘛?。。。。。<\/p>

瞬间碉堡。","title":"放心奶","type":1},{"ct":"2016-04-08 15 | * 14:00:00.674", 16 | * "text":"刚才下楼去买烟,听到士多店老板5 17 | * 岁的儿子蹲在门口唱:我有一头小毛驴我从来也不骑,有一天我心血来潮骑它去赶集。我手里拿着小皮鞭我心里正得意,不知怎么我的毛驴生了个小Baby。。  这TM谁教的。。。", 18 | * "title":"谁教的。。。","type":1},{"ct":"2016-04-08 14:00:00.674", 19 | * "text":"有一次课上跟我同桌比腿瘦,他是男的,我女的。他非得的说他比我瘦,于是我不服气,拿起他的手摸我的腿,说你快摸啊,你快摸啊。我永远都不会忘记同学们看我的眼神", 20 | * "title":"你快摸啊","type":1},{"ct":"2016-04-08 14:00:00.674", 21 | * "text":"我去早市买菜,买了很多,都快拎不动了,这时就听一男人喊:\u201c美女,拎不动了吧?\u201d 22 | * 扭头一看,猪肉摊上一帅哥正看着我,我暗喜,难道帅哥看我长得漂亮要帮忙?只听帅哥说:\u201c美女买点猪肉吧,吃了猪肉就有力气了,有力气以后就能拎动了\u2026\u2026 23 | * \u201d","title":"买点猪肉吧","type":1},{"ct":"2016-04-08 14:00:00.674", 24 | * "text":"老婆:老公,台风要来了!你可要抱紧我,万一我吹到别人家,别人不还怎么办?老公:你可拉倒吧!就你这样,人家顶着风也要把你送回来!","title":"送回来!", 25 | * "type":1},{"ct":"2016-04-08 14:00:00.673", 26 | * "text":"一天,我问我哥。我说:哥,当初你是怎么看上嫂子的。我哥说:那是一年夏天,我和你嫂子刚认识的时候,我请你嫂子吃冰棍,我看见她能把一支冰棍全塞嘴里五六秒,于是我就下定决心一定要把她追到手。我:\u2026\u2026\u2026\u2026","title":"一支冰棍全塞嘴里五六秒","type":1},{"ct":"2016-04-08 14:00:00.637","text":"在公厕上厕所,憋了很久,放了个巨长的屁。隔壁的哥们受不了了说:卧槽哥们,你这是要起飞啊。","title":"起飞","type":1},{"ct":"2016-04-08 14:00:00.636","text":"老师:知道什么是法盲吗?同学答:法盲就是法国的文盲。老师:名人呢?同学答:有名字的人。老师:白领的意思呢?同学答:白领工资。","title":"白领","type":1},{"ct":"2016-04-08 14:00:00.636","text":"记得小时候,男孩都喜欢电动玩具,女孩喜欢娃娃;随着年代发展到如今已完全颠覆,女孩喜欢电动玩具,男孩喜欢娃娃。谁能告诉我为啥?","title":"颠覆","type":1},{"ct":"2016-04-08 12:30:42.462","text":"老妈:\u201c过年了,看你期末成绩不错,给你包个大红包,开心吗?\u201d<\/p>

我:\u201c开心得不要不要的!\u201d<\/p>

老妈:\u201c啊?不要就算了。\u201d","title":"老妈:\u201c过年了,看你期末成绩不错","type":1},{"ct":"2016-04-08 12:30:42.461","text":"高一新生入学,寄宿生开会,生指老师说:\u201c宿舍就是你的家,大家要团结。\u201d  一个男生说:\u201c在这个家里谁是我的爸爸妈妈?\u201d  另一个男生说:\u201c我是你的爸爸。\u201d  那个男生说:\u201c你每天帮我买早餐。\u201d  生指老师说:\u201c在这个家里没有爸爸妈妈。\u201d  那个男生说:\u201c真不幸,我们成了孤儿。\u201d","title":"真不幸,我们成了孤儿","type":1},{"ct":"2016-04-08 12:30:42.461","text":"男朋友上课传给我了个纸包,打开一看是一只粉红色的小兔子。<\/p>

回纸条:捏的好可爱,哪买的橡皮泥?<\/p>

他:刚吃完的泡泡糖。","title":"男朋友上课传给我了个纸包","type":1},{"ct":"2016-04-08 12:30:42.443","text":"我的女朋友是个二货,中午吃饭时女友娇滴滴的对我说:你下面太硬。<\/p>

我迟钝了半天回句:你下面的水太多了。<\/p>

然后二货女友说道:恩恩,事实证明,煮好一锅面条不是件容易的事。。。","title":"我的女朋友是个二货,","type":1},{"ct":"2016-04-08 12:30:42.443","text":"\u201c你这把年纪。。。\u201d听了会让人不舒服,正确的说法叫做:\u201c在你现在这样的人生阶段。。。\u201d","title":"\u201c你这把年纪。。。\u201d听了会让人不舒服,正","type":1},{"ct":"2016-04-08 12:30:42.442","text":"晚上逛街,看见一大叔趴在地上不动,一看就是喝多了,像我这样帅气又好心的年轻人怎么能袖手旁观呢,于是果断把大叔扶了起来。。。<\/p>

妈蛋,钱包里居然没钱,还好手机卖了还能赚点。。","title":"晚上逛街,看见一大叔趴在地上不动","type":1},{"ct":"2016-04-08 12:30:42.442","text":"中学时,因为字写得丑,不敢写情书表白;多年后同学聚会,她已为人妻。她告诉我,其实她根本不在乎我字丑,只在乎我人丑。","title":"中学时,因为字写得丑","type":1},{"ct":"2016-04-08 12:30:42.441","text":"跟一2货舍友同去取款,他忽然认真地说:取款机对盲人并不方便,以后数字键应该改成语音播报的,这样盲人就可以听见自己输入的密码对不对了。<\/p>

听后,我不由得感叹道:现今这社会,如此古道热肠同时又智商低下的人太少了!这朋友我是交定了!","title":"跟一2货舍友同去取款","type":1},{"ct":"2016-04-08 12:30:42.440","text":"半夜想吃红薯,就让媳妇出去买。都特么去了三个钟头了,还没回来。卧槽,我这个担心啊,不会在外面自己吃完回来吧!","title":"半夜想吃红薯,就让媳妇出去买","type":1},{"ct":"2016-04-08 12:30:42.352","text":"1、就刚刚,我看到一个超级帅的男孩,我们就辣么注视对方好久,时间仿佛静止了...直到我拿着镜子的手感到酸疼才作罢。

<\/p>\r\n2、记得夏天的时候,去同事家做客,午睡的时候,同事问我需要什么东西盖着不?我幽幽的回道:我只需要盖着肚脐就可以。然后...同事立马从眼镜盒里拿块眼镜布给我盖上。

<\/p>\r\n3、公司女同事穿着齐逼牛仔裙,我坐在她对面赶脚浑身不自在,女同事说:听说穿齐逼小短裙会影响健康,是真的吗?我说:那还用说,我一看到齐逼小短裙血压就飙高\u2026\u2026

<\/p>\r\n4、开通宵的屌丝最讨人厌了,冲上来就问:包夜多少钱?尼玛,真是一点情调都没有....

<\/p>......","title":"冷死人的冷笑话","type":1},{"ct":"2016-04-08 12:00:00.828","text":"老王最爱挑毛病,恨不得鸡蛋里挑出骨头。  一日,去朋友家喝满月酒,对着婴儿左挑右挑没挑出毛病。  最后说:总体上还行,就是太幼稚了。  朋友:\u2026\u2026","title":"老王最爱挑毛病","type":1}],"currentPage":1,"maxResult":20,"ret_code":0} 27 | */ 28 | 29 | private int showapi_res_code; 30 | private String showapi_res_error; 31 | /** 32 | * allNum : 21320 33 | * allPages : 1066 34 | * contentlist : [{"ct":"2016-04-08 14:00:00.676", 35 | * "text":"今天在卫生间拉翔,进行中媳妇进来洗澡,我拉完翔就贱贱的伸出魔爪去摸咪咪,<\/p>

媳妇说:拉完也不洗手就来,咱娃还能喝上放心奶嘛?。。。。。<\/p>

瞬间碉堡。","title":"放心奶","type":1},{"ct":"2016-04-08 14:00:00.674", 37 | * "text":"刚才下楼去买烟,听到士多店老板5 38 | * 岁的儿子蹲在门口唱:我有一头小毛驴我从来也不骑,有一天我心血来潮骑它去赶集。我手里拿着小皮鞭我心里正得意,不知怎么我的毛驴生了个小Baby。。  这TM谁教的。。。", 39 | * "title":"谁教的。。。","type":1},{"ct":"2016-04-08 14:00:00.674", 40 | * "text":"有一次课上跟我同桌比腿瘦,他是男的,我女的。他非得的说他比我瘦,于是我不服气,拿起他的手摸我的腿,说你快摸啊,你快摸啊。我永远都不会忘记同学们看我的眼神", 41 | * "title":"你快摸啊","type":1},{"ct":"2016-04-08 14:00:00.674", 42 | * "text":"我去早市买菜,买了很多,都快拎不动了,这时就听一男人喊:\u201c美女,拎不动了吧?\u201d 43 | * 扭头一看,猪肉摊上一帅哥正看着我,我暗喜,难道帅哥看我长得漂亮要帮忙?只听帅哥说:\u201c美女买点猪肉吧,吃了猪肉就有力气了,有力气以后就能拎动了\u2026\u2026 44 | * \u201d","title":"买点猪肉吧","type":1},{"ct":"2016-04-08 14:00:00.674", 45 | * "text":"老婆:老公,台风要来了!你可要抱紧我,万一我吹到别人家,别人不还怎么办?老公:你可拉倒吧!就你这样,人家顶着风也要把你送回来!","title":"送回来!", 46 | * "type":1},{"ct":"2016-04-08 14:00:00.673", 47 | * "text":"一天,我问我哥。我说:哥,当初你是怎么看上嫂子的。我哥说:那是一年夏天,我和你嫂子刚认识的时候,我请你嫂子吃冰棍,我看见她能把一支冰棍全塞嘴里五六秒,于是我就下定决心一定要把她追到手。我:\u2026\u2026\u2026\u2026","title":"一支冰棍全塞嘴里五六秒","type":1},{"ct":"2016-04-08 14:00:00.637","text":"在公厕上厕所,憋了很久,放了个巨长的屁。隔壁的哥们受不了了说:卧槽哥们,你这是要起飞啊。","title":"起飞","type":1},{"ct":"2016-04-08 14:00:00.636","text":"老师:知道什么是法盲吗?同学答:法盲就是法国的文盲。老师:名人呢?同学答:有名字的人。老师:白领的意思呢?同学答:白领工资。","title":"白领","type":1},{"ct":"2016-04-08 14:00:00.636","text":"记得小时候,男孩都喜欢电动玩具,女孩喜欢娃娃;随着年代发展到如今已完全颠覆,女孩喜欢电动玩具,男孩喜欢娃娃。谁能告诉我为啥?","title":"颠覆","type":1},{"ct":"2016-04-08 12:30:42.462","text":"老妈:\u201c过年了,看你期末成绩不错,给你包个大红包,开心吗?\u201d<\/p>

我:\u201c开心得不要不要的!\u201d<\/p>

老妈:\u201c啊?不要就算了。\u201d","title":"老妈:\u201c过年了,看你期末成绩不错","type":1},{"ct":"2016-04-08 12:30:42.461","text":"高一新生入学,寄宿生开会,生指老师说:\u201c宿舍就是你的家,大家要团结。\u201d  一个男生说:\u201c在这个家里谁是我的爸爸妈妈?\u201d  另一个男生说:\u201c我是你的爸爸。\u201d  那个男生说:\u201c你每天帮我买早餐。\u201d  生指老师说:\u201c在这个家里没有爸爸妈妈。\u201d  那个男生说:\u201c真不幸,我们成了孤儿。\u201d","title":"真不幸,我们成了孤儿","type":1},{"ct":"2016-04-08 12:30:42.461","text":"男朋友上课传给我了个纸包,打开一看是一只粉红色的小兔子。<\/p>

回纸条:捏的好可爱,哪买的橡皮泥?<\/p>

他:刚吃完的泡泡糖。","title":"男朋友上课传给我了个纸包","type":1},{"ct":"2016-04-08 12:30:42.443","text":"我的女朋友是个二货,中午吃饭时女友娇滴滴的对我说:你下面太硬。<\/p>

我迟钝了半天回句:你下面的水太多了。<\/p>

然后二货女友说道:恩恩,事实证明,煮好一锅面条不是件容易的事。。。","title":"我的女朋友是个二货,","type":1},{"ct":"2016-04-08 12:30:42.443","text":"\u201c你这把年纪。。。\u201d听了会让人不舒服,正确的说法叫做:\u201c在你现在这样的人生阶段。。。\u201d","title":"\u201c你这把年纪。。。\u201d听了会让人不舒服,正","type":1},{"ct":"2016-04-08 12:30:42.442","text":"晚上逛街,看见一大叔趴在地上不动,一看就是喝多了,像我这样帅气又好心的年轻人怎么能袖手旁观呢,于是果断把大叔扶了起来。。。<\/p>

妈蛋,钱包里居然没钱,还好手机卖了还能赚点。。","title":"晚上逛街,看见一大叔趴在地上不动","type":1},{"ct":"2016-04-08 12:30:42.442","text":"中学时,因为字写得丑,不敢写情书表白;多年后同学聚会,她已为人妻。她告诉我,其实她根本不在乎我字丑,只在乎我人丑。","title":"中学时,因为字写得丑","type":1},{"ct":"2016-04-08 12:30:42.441","text":"跟一2货舍友同去取款,他忽然认真地说:取款机对盲人并不方便,以后数字键应该改成语音播报的,这样盲人就可以听见自己输入的密码对不对了。<\/p>

听后,我不由得感叹道:现今这社会,如此古道热肠同时又智商低下的人太少了!这朋友我是交定了!","title":"跟一2货舍友同去取款","type":1},{"ct":"2016-04-08 12:30:42.440","text":"半夜想吃红薯,就让媳妇出去买。都特么去了三个钟头了,还没回来。卧槽,我这个担心啊,不会在外面自己吃完回来吧!","title":"半夜想吃红薯,就让媳妇出去买","type":1},{"ct":"2016-04-08 12:30:42.352","text":"1、就刚刚,我看到一个超级帅的男孩,我们就辣么注视对方好久,时间仿佛静止了...直到我拿着镜子的手感到酸疼才作罢。

<\/p>\r\n2、记得夏天的时候,去同事家做客,午睡的时候,同事问我需要什么东西盖着不?我幽幽的回道:我只需要盖着肚脐就可以。然后...同事立马从眼镜盒里拿块眼镜布给我盖上。

<\/p>\r\n3、公司女同事穿着齐逼牛仔裙,我坐在她对面赶脚浑身不自在,女同事说:听说穿齐逼小短裙会影响健康,是真的吗?我说:那还用说,我一看到齐逼小短裙血压就飙高\u2026\u2026

<\/p>\r\n4、开通宵的屌丝最讨人厌了,冲上来就问:包夜多少钱?尼玛,真是一点情调都没有....

<\/p>......","title":"冷死人的冷笑话","type":1},{"ct":"2016-04-08 12:00:00.828","text":"老王最爱挑毛病,恨不得鸡蛋里挑出骨头。  一日,去朋友家喝满月酒,对着婴儿左挑右挑没挑出毛病。  最后说:总体上还行,就是太幼稚了。  朋友:\u2026\u2026","title":"老王最爱挑毛病","type":1}] 48 | * currentPage : 1 49 | * maxResult : 20 50 | * ret_code : 0 51 | */ 52 | 53 | private ShowapiResBodyEntity showapi_res_body; 54 | 55 | public int getShowapi_res_code() { 56 | return showapi_res_code; 57 | } 58 | 59 | public void setShowapi_res_code(int showapi_res_code) { 60 | this.showapi_res_code = showapi_res_code; 61 | } 62 | 63 | public String getShowapi_res_error() { 64 | return showapi_res_error; 65 | } 66 | 67 | public void setShowapi_res_error(String showapi_res_error) { 68 | this.showapi_res_error = showapi_res_error; 69 | } 70 | 71 | public ShowapiResBodyEntity getShowapi_res_body() { 72 | return showapi_res_body; 73 | } 74 | 75 | public void setShowapi_res_body(ShowapiResBodyEntity showapi_res_body) { 76 | this.showapi_res_body = showapi_res_body; 77 | } 78 | 79 | public static class ShowapiResBodyEntity { 80 | private int allNum; 81 | private int allPages; 82 | private int currentPage; 83 | private int maxResult; 84 | private int ret_code; 85 | /** 86 | * ct : 2016-04-08 14:00:00.676 87 | * text : 今天在卫生间拉翔,进行中媳妇进来洗澡,我拉完翔就贱贱的伸出魔爪去摸咪咪,

媳妇说:拉完也不洗手就来,咱娃还能喝上放心奶嘛?。。。。。

瞬间碉堡。 89 | * title : 放心奶 90 | * type : 1 91 | */ 92 | 93 | private List contentlist; 94 | 95 | public int getAllNum() { 96 | return allNum; 97 | } 98 | 99 | public void setAllNum(int allNum) { 100 | this.allNum = allNum; 101 | } 102 | 103 | public int getAllPages() { 104 | return allPages; 105 | } 106 | 107 | public void setAllPages(int allPages) { 108 | this.allPages = allPages; 109 | } 110 | 111 | public int getCurrentPage() { 112 | return currentPage; 113 | } 114 | 115 | public void setCurrentPage(int currentPage) { 116 | this.currentPage = currentPage; 117 | } 118 | 119 | public int getMaxResult() { 120 | return maxResult; 121 | } 122 | 123 | public void setMaxResult(int maxResult) { 124 | this.maxResult = maxResult; 125 | } 126 | 127 | public int getRet_code() { 128 | return ret_code; 129 | } 130 | 131 | public void setRet_code(int ret_code) { 132 | this.ret_code = ret_code; 133 | } 134 | 135 | public List getContentlist() { 136 | return contentlist; 137 | } 138 | 139 | public void setContentlist(List contentlist) { 140 | this.contentlist = contentlist; 141 | } 142 | 143 | } 144 | } 145 | 146 | -------------------------------------------------------------------------------- /app/src/main/java/rx/dong/com/rxjoke/presenter/BasePresenter.java: -------------------------------------------------------------------------------- 1 | package rx.dong.com.rxjoke.presenter; 2 | 3 | 4 | import rx.dong.com.rxjoke.ui.view.MvpView; 5 | 6 | /** 7 | * Base class that implements the Presenter interface and provides a base implementation for 8 | * attachView() and detachView(). It also handles keeping a reference to the mvpView that 9 | * can be accessed from the children classes by calling getMvpView(). 10 | */ 11 | public class BasePresenter implements Presenter { 12 | 13 | private T mMvpView; 14 | 15 | @Override 16 | public void attachView(T mvpView) { 17 | mMvpView = mvpView; 18 | } 19 | 20 | @Override 21 | public void detachView() { 22 | mMvpView = null; 23 | } 24 | 25 | public boolean isViewAttached() { 26 | return mMvpView != null; 27 | } 28 | 29 | public T getMvpView() { 30 | return mMvpView; 31 | } 32 | 33 | public void checkViewAttached() { 34 | if (!isViewAttached()) throw new MvpViewNotAttachedException(); 35 | } 36 | 37 | public static class MvpViewNotAttachedException extends RuntimeException { 38 | public MvpViewNotAttachedException() { 39 | super("Please call Presenter.attachView(MvpView) before" + 40 | " requesting data to the Presenter"); 41 | } 42 | } 43 | } 44 | 45 | -------------------------------------------------------------------------------- /app/src/main/java/rx/dong/com/rxjoke/presenter/JokePresenter.java: -------------------------------------------------------------------------------- 1 | package rx.dong.com.rxjoke.presenter; 2 | 3 | import com.orhanobut.logger.Logger; 4 | 5 | import java.util.List; 6 | 7 | import rx.Observer; 8 | import rx.android.schedulers.AndroidSchedulers; 9 | import rx.dong.com.rxjoke.api.JokeApi; 10 | import rx.dong.com.rxjoke.api.RxService; 11 | import rx.dong.com.rxjoke.model.ContentlistEntity; 12 | import rx.dong.com.rxjoke.model.JokeEntity; 13 | import rx.dong.com.rxjoke.ui.view.JokeView; 14 | import rx.functions.Func1; 15 | import rx.schedulers.Schedulers; 16 | 17 | /** 18 | * Created by JDD on 2016/4/21 0021. 19 | */ 20 | public class JokePresenter extends BasePresenter { 21 | 22 | @Override 23 | public void attachView(JokeView mvpView) { 24 | super.attachView(mvpView); 25 | } 26 | 27 | @Override 28 | public void detachView() { 29 | super.detachView(); 30 | } 31 | 32 | public void loadList(final int page) { 33 | RxService.createApi(JokeApi.class) 34 | .getJoke(page) 35 | .subscribeOn(Schedulers.io()) 36 | .map(new Func1>() { 37 | @Override 38 | public List call(JokeEntity jokeEntity) { 39 | return jokeEntity.getShowapi_res_body().getContentlist(); 40 | } 41 | }) 42 | .observeOn(AndroidSchedulers.mainThread()) 43 | .subscribe(new Observer>() { 44 | @Override 45 | public void onCompleted() { 46 | 47 | } 48 | 49 | @Override 50 | public void onError(Throwable e) { 51 | Logger.e(e.getMessage()); 52 | getMvpView().showError(null, null); 53 | } 54 | 55 | @Override 56 | public void onNext(List contentlistEntities) { 57 | if (page == 1) { 58 | getMvpView().refresh(contentlistEntities); 59 | } else { 60 | getMvpView().loadMore(contentlistEntities); 61 | } 62 | } 63 | }); 64 | 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/java/rx/dong/com/rxjoke/presenter/Presenter.java: -------------------------------------------------------------------------------- 1 | package rx.dong.com.rxjoke.presenter; 2 | 3 | 4 | import rx.dong.com.rxjoke.ui.view.MvpView; 5 | 6 | /** 7 | * Every presenter in the app must either implement this interface or extend BasePresenter 8 | * indicating the MvpView type that wants to be attached with. 9 | */ 10 | public interface Presenter { 11 | 12 | void attachView(V mvpView); 13 | 14 | void detachView(); 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/rx/dong/com/rxjoke/ui/BaseActivity.java: -------------------------------------------------------------------------------- 1 | package rx.dong.com.rxjoke.ui; 2 | 3 | import android.support.v7.app.AppCompatActivity; 4 | import android.view.View; 5 | 6 | import rx.dong.com.rxjoke.ui.view.MvpView; 7 | 8 | /** 9 | * Created by JDD on 2016/4/22 0022. 10 | */ 11 | public class BaseActivity extends AppCompatActivity implements MvpView { 12 | 13 | @Override 14 | public void showLoading(String msg) { 15 | 16 | } 17 | 18 | @Override 19 | public void hideLoading() { 20 | 21 | } 22 | 23 | @Override 24 | public void showError(String msg, View.OnClickListener onClickListener) { 25 | 26 | } 27 | 28 | @Override 29 | public void showEmpty(String msg, View.OnClickListener onClickListener) { 30 | 31 | } 32 | 33 | @Override 34 | public void showEmpty(String msg, View.OnClickListener onClickListener, int imageId) { 35 | 36 | } 37 | 38 | @Override 39 | public void showNetError(View.OnClickListener onClickListener) { 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/rx/dong/com/rxjoke/ui/activity/MainActivity.java: -------------------------------------------------------------------------------- 1 | package rx.dong.com.rxjoke.ui.activity; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v4.widget.SwipeRefreshLayout; 6 | import android.support.v7.widget.LinearLayoutManager; 7 | import android.view.View; 8 | import android.widget.Button; 9 | import android.widget.RelativeLayout; 10 | import android.widget.TextView; 11 | 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | import butterknife.Bind; 16 | import butterknife.ButterKnife; 17 | import butterknife.OnClick; 18 | import rx.dong.com.rxjoke.R; 19 | import rx.dong.com.rxjoke.common.AutoLoadRecylerView; 20 | import rx.dong.com.rxjoke.common.AutoLoadRecylerView.loadMoreListener; 21 | import rx.dong.com.rxjoke.common.DividerItemDecoration; 22 | import rx.dong.com.rxjoke.model.ContentlistEntity; 23 | import rx.dong.com.rxjoke.presenter.JokePresenter; 24 | import rx.dong.com.rxjoke.ui.BaseActivity; 25 | import rx.dong.com.rxjoke.ui.adapter.JokeAdapter; 26 | import rx.dong.com.rxjoke.ui.view.JokeView; 27 | 28 | /** 29 | * Created by JDD on 2016/4/8. 30 | */ 31 | public class MainActivity extends BaseActivity implements JokeView, 32 | SwipeRefreshLayout.OnRefreshListener, loadMoreListener { 33 | 34 | @Bind(R.id.record_recycleview) 35 | AutoLoadRecylerView recordRecycleview; 36 | @Bind(R.id.common_error_txt) 37 | TextView commonErrorTxt; 38 | @Bind(R.id.retry_btn) 39 | Button retryBtn; 40 | @Bind(R.id.common_error) 41 | RelativeLayout commonError; 42 | @Bind(R.id.joke_refresh_layout) 43 | SwipeRefreshLayout jokeRefreshLayout; 44 | private JokePresenter jokePresenter; 45 | private LinearLayoutManager layoutManager; 46 | private int page = 1; 47 | private List jokeList; 48 | private JokeAdapter jokeAdapter; 49 | 50 | @Override 51 | protected void onCreate(@Nullable Bundle savedInstanceState) { 52 | super.onCreate(savedInstanceState); 53 | setContentView(R.layout.activity_main); 54 | ButterKnife.bind(this); 55 | initView(); 56 | initData(); 57 | loadData(); 58 | 59 | 60 | } 61 | 62 | private void initView() { 63 | jokeRefreshLayout.setOnRefreshListener(this); 64 | layoutManager = new LinearLayoutManager(this); 65 | recordRecycleview.setLayoutManager(layoutManager); 66 | recordRecycleview.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration 67 | .VERTICAL_LIST)); 68 | recordRecycleview.setLoadMoreListener(this); 69 | } 70 | 71 | private void initData() { 72 | jokeList = new ArrayList<>(); 73 | jokeAdapter = new JokeAdapter(jokeList); 74 | recordRecycleview.setAdapter(jokeAdapter); 75 | 76 | jokePresenter = new JokePresenter(); 77 | jokePresenter.attachView(this); 78 | } 79 | 80 | private void loadData() { 81 | jokePresenter.loadList(page); 82 | page++; 83 | } 84 | 85 | @Override 86 | public void onRefresh() { 87 | page = 1; 88 | loadData(); 89 | } 90 | 91 | 92 | @Override 93 | public void onLoadMore() { 94 | loadData(); 95 | } 96 | 97 | /** 98 | * @param data 回调 以下三个方法是presenter回调的函数 用于更新界面 99 | */ 100 | @Override 101 | public void refresh(List data) { 102 | commonError.setVisibility(View.GONE); 103 | jokeList.clear(); 104 | jokeList.addAll(data); 105 | jokeAdapter.notifyDataSetChanged(); 106 | jokeRefreshLayout.setRefreshing(false); 107 | } 108 | 109 | @Override 110 | public void loadMore(List data) { 111 | commonError.setVisibility(View.GONE); 112 | jokeList.addAll(data); 113 | jokeAdapter.notifyDataSetChanged(); 114 | recordRecycleview.setLoading(false); 115 | } 116 | 117 | @Override 118 | public void showError(String msg, View.OnClickListener onClickListener) { 119 | super.showError(msg, onClickListener); 120 | commonError.setVisibility(View.VISIBLE); 121 | recordRecycleview.setLoading(false); 122 | jokeRefreshLayout.setRefreshing(false); 123 | } 124 | 125 | @OnClick(R.id.retry_btn) 126 | void setRetryBtnonClick() { 127 | onRefresh(); 128 | } 129 | 130 | @Override 131 | protected void onDestroy() { 132 | super.onDestroy(); 133 | jokePresenter.detachView(); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /app/src/main/java/rx/dong/com/rxjoke/ui/adapter/JokeAdapter.java: -------------------------------------------------------------------------------- 1 | package rx.dong.com.rxjoke.ui.adapter; 2 | 3 | import android.support.v7.widget.RecyclerView; 4 | import android.text.Html; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.TextView; 9 | 10 | import java.util.List; 11 | 12 | import butterknife.Bind; 13 | import butterknife.ButterKnife; 14 | import rx.dong.com.rxjoke.R; 15 | import rx.dong.com.rxjoke.model.ContentlistEntity; 16 | import rx.dong.com.rxjoke.util.TimeUtil; 17 | 18 | /** 19 | * Created by JDD on 2016/4/23 0023. 20 | */ 21 | public class JokeAdapter extends RecyclerView.Adapter { 22 | 23 | private List jokeList; 24 | 25 | public JokeAdapter(List jokeList) { 26 | this.jokeList = jokeList; 27 | } 28 | 29 | @Override 30 | public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 31 | View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.joke_list_item, 32 | parent, false); 33 | JokeViewHolder holder = new JokeViewHolder(view); 34 | return holder; 35 | } 36 | 37 | @Override 38 | public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { 39 | JokeViewHolder jokeViewHolder = (JokeViewHolder) holder; 40 | jokeViewHolder.title.setText("#" + jokeList.get(position).getTitle() + "#"); 41 | jokeViewHolder.time.setText(TimeUtil.getDateBySplit(jokeList.get(position).getCt())); 42 | /*使html中<标签>得以转化*/ 43 | jokeViewHolder.content.setText(Html.fromHtml(jokeList.get(position).getText().toString())); 44 | 45 | 46 | } 47 | 48 | @Override 49 | public int getItemCount() { 50 | return jokeList.size(); 51 | } 52 | 53 | static class JokeViewHolder extends RecyclerView.ViewHolder { 54 | @Bind(R.id.title) 55 | TextView title; 56 | @Bind(R.id.time) 57 | TextView time; 58 | @Bind(R.id.content) 59 | TextView content; 60 | 61 | public JokeViewHolder(View view) { 62 | super(view); 63 | ButterKnife.bind(this, view); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/java/rx/dong/com/rxjoke/ui/view/JokeView.java: -------------------------------------------------------------------------------- 1 | package rx.dong.com.rxjoke.ui.view; 2 | 3 | import java.util.List; 4 | 5 | import rx.dong.com.rxjoke.model.ContentlistEntity; 6 | 7 | /** 8 | * Created by JDD on 2016/4/21 0021. 9 | */ 10 | public interface JokeView extends MvpView { 11 | void refresh(List data); 12 | 13 | void loadMore(List data); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/rx/dong/com/rxjoke/ui/view/MvpView.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 [1076559197@qq.com | tchen0707@gmail.com] 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License”); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package rx.dong.com.rxjoke.ui.view; 18 | 19 | 20 | import android.view.View; 21 | 22 | public interface MvpView { 23 | 24 | void showLoading(String msg); 25 | 26 | void hideLoading(); 27 | 28 | void showError(String msg, View.OnClickListener onClickListener); 29 | 30 | void showEmpty(String msg, View.OnClickListener onClickListener); 31 | 32 | void showEmpty(String msg, View.OnClickListener onClickListener, int imageId); 33 | 34 | void showNetError(View.OnClickListener onClickListener); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/rx/dong/com/rxjoke/util/TimeUtil.java: -------------------------------------------------------------------------------- 1 | package rx.dong.com.rxjoke.util; 2 | 3 | /** 4 | * Created by JDD on 2016/4/23 0023. 5 | */ 6 | public class TimeUtil { 7 | public static String getDateBySplit(String str) { 8 | String[] strings = str.split(" "); 9 | return strings[0]; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/app_copyright_jdd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDDJJ/RxJoke/b5d9fdfb0f6a3eeb7e1d039a9321395206fe00eb/app/src/main/res/drawable-xhdpi/app_copyright_jdd.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/button_stroke.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/list_divider.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/layout/common_error.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 18 | 19 |