├── .gitignore ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── diffey │ │ └── view │ │ └── rxzhihu │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── diffey │ │ │ └── view │ │ │ └── rxzhihu │ │ │ ├── ZhihuApplication.java │ │ │ ├── adapter │ │ │ ├── MainAdapter.java │ │ │ ├── MainMenuAdapter.java │ │ │ ├── StoryAdapter.java │ │ │ └── TRClientAdapter.java │ │ │ ├── api │ │ │ ├── TRApi.java │ │ │ ├── TRService.java │ │ │ ├── ZhihuApi.java │ │ │ └── ZhihuService.java │ │ │ ├── base │ │ │ ├── BaseActivity.java │ │ │ ├── BaseFragemnt.java │ │ │ └── SimpleActivity.java │ │ │ ├── bean │ │ │ ├── ChatBean.java │ │ │ ├── MenuItem.java │ │ │ ├── NewsEntity.java │ │ │ ├── StoriesEntity.java │ │ │ ├── StoryDetailsEntity.java │ │ │ ├── TREntity.java │ │ │ └── TopStoriesEntity.java │ │ │ ├── contant │ │ │ ├── Contant.java │ │ │ └── UrlContant.java │ │ │ ├── db │ │ │ ├── DBContant.java │ │ │ ├── ZPOpenHelper.java │ │ │ ├── bean │ │ │ │ └── NewBean.java │ │ │ └── dao │ │ │ │ └── NewDao.java │ │ │ ├── receiver │ │ │ └── NetStateReceiver.java │ │ │ ├── ui │ │ │ ├── activity │ │ │ │ ├── MainActivity.java │ │ │ │ ├── SettingActivity.java │ │ │ │ ├── StoryActivity.java │ │ │ │ └── TRClientActivity.java │ │ │ └── fragment │ │ │ │ ├── MainFragment.java │ │ │ │ ├── MainMenuFragment.java │ │ │ │ ├── SettingFragment.java │ │ │ │ └── StoryFragment.java │ │ │ ├── util │ │ │ ├── AppInfoUtils.java │ │ │ ├── DensityUtils.java │ │ │ ├── GsonUtils.java │ │ │ ├── HtmlUtils.java │ │ │ ├── IntentUtils.java │ │ │ ├── NetWorkUtils.java │ │ │ ├── ScreenSizeUtils.java │ │ │ └── ViewUtils.java │ │ │ └── view │ │ │ └── AutoLoadRecylerView.java │ └── res │ │ ├── anim │ │ └── item_bottom_in.xml │ │ ├── drawable-hdpi │ │ ├── chat_bg_normal.9.png │ │ ├── chat_robot_bg_normal.9.png │ │ ├── ic_action_refresh.png │ │ ├── ic_actionbar_back.png │ │ ├── ic_movie_white_24dp.png │ │ ├── icon.png │ │ ├── send_btn_normal.9.png │ │ └── send_btn_pressed.9.png │ │ ├── drawable-xhdpi │ │ ├── ic_action_refresh.png │ │ ├── ic_movie_white_24dp.png │ │ └── ic_settings_white_24dp.png │ │ ├── drawable │ │ ├── common_card_1.xml │ │ ├── common_card_2.xml │ │ ├── common_card_trans.xml │ │ ├── item_chat_bg.xml │ │ ├── item_list_selector.xml │ │ ├── item_main_bg_selector.xml │ │ └── send_btn_bg.xml │ │ ├── layout │ │ ├── activity_main.xml │ │ ├── activity_setting.xml │ │ ├── activity_story.xml │ │ ├── activity_trclient.xml │ │ ├── common_error.xml │ │ ├── common_loading.xml │ │ ├── common_toolbar.xml │ │ ├── fragment_main.xml │ │ ├── fragment_main_menu.xml │ │ ├── fragment_story.xml │ │ ├── item_main.xml │ │ ├── item_main_menu.xml │ │ ├── item_trc.xml │ │ └── item_trc_robot.xml │ │ ├── menu │ │ └── menu_main.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-v19 │ │ └── styles.xml │ │ ├── values-v21 │ │ └── styles.xml │ │ ├── values-w820dp │ │ └── dimens.xml │ │ ├── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ │ └── xml │ │ └── preferences.xml │ └── test │ └── java │ └── com │ └── diffey │ └── view │ └── zhihupage │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── img ├── chat.png ├── details.png └── main.png └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | 15 | # Gradle files 16 | .gradle/ 17 | build/ 18 | 19 | # Local configuration file (sdk path, etc) 20 | local.properties 21 | 22 | # Proguard folder generated by Eclipse 23 | proguard/ 24 | 25 | # Log Files 26 | *.log 27 | 28 | # Android Studio Navigation editor temp files 29 | .navigation/ 30 | 31 | # Android Studio captures folder 32 | captures/ 33 | 34 | *.iml 35 | .gradle 36 | /.idea 37 | .idea 38 | .DS_Store 39 | /build 40 | -------------------------------------------------------------------------------- /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, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RxZhihuPager 2 | 知乎日报客户端,Rxjava + Retrofit实践 3 | ### 下载 4 | 地址:http://fir.im/b3gh 5 | ### 截图 6 | 7 | 8 | ### 参考 9 | [ZhihuPager](https://github.com/cundong/ZhihuPaper) 10 | 11 | [JainDanRxJava](https://github.com/ZhaoKaiQiang/JianDanRxJava) 12 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'me.tatarka.retrolambda' 3 | 4 | android { 5 | compileSdkVersion 23 6 | buildToolsVersion "23.0.2" 7 | 8 | defaultConfig { 9 | applicationId "com.diffey.rxzhihu" 10 | minSdkVersion 14 11 | targetSdkVersion 23 12 | versionCode 2 13 | versionName "1.1" 14 | } 15 | buildTypes { 16 | release { 17 | minifyEnabled false 18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 19 | } 20 | } 21 | 22 | compileOptions { 23 | sourceCompatibility JavaVersion.VERSION_1_8 24 | targetCompatibility JavaVersion.VERSION_1_8 25 | } 26 | } 27 | 28 | dependencies { 29 | compile fileTree(include: ['*.jar'], dir: 'libs') 30 | compile 'com.diffey.view.circularloading:circularloading:0.0.1' 31 | 32 | compile 'com.android.support:support-v4:23.1.1' 33 | compile 'com.android.support:appcompat-v7:23.1.1' 34 | compile 'com.android.support:cardview-v7:23.1.1' 35 | compile 'com.android.support:recyclerview-v7:23.1.1' 36 | 37 | compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4' 38 | compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4' 39 | compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4' 40 | 41 | compile 'io.reactivex:rxandroid:1.0.1' 42 | 43 | compile 'com.facebook.fresco:fresco:0.9.0+' 44 | 45 | compile 'com.github.recruit-lifestyle:WaveSwipeRefreshLayout:1.5' 46 | compile('com.github.afollestad.material-dialogs:core:0.8.5.3@aar') { 47 | transitive = true 48 | } 49 | 50 | compile 'com.jakewharton:butterknife:7.0.1' 51 | compile 'com.orhanobut:logger:1.10' 52 | debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1' 53 | releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1' 54 | compile 'com.facebook.stetho:stetho:1.1.0' 55 | compile 'com.facebook.stetho:stetho-okhttp:1.1.0' 56 | } 57 | -------------------------------------------------------------------------------- /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 E:\android-sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/diffey/view/rxzhihu/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu; 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 | 7 | 14 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/ZhihuApplication.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu; 2 | 3 | import android.app.Application; 4 | 5 | import com.facebook.drawee.backends.pipeline.Fresco; 6 | import com.facebook.stetho.Stetho; 7 | import com.orhanobut.logger.Logger; 8 | import com.squareup.leakcanary.LeakCanary; 9 | 10 | 11 | /** 12 | * Created by diff on 2016/2/2. 13 | */ 14 | public class ZhihuApplication extends Application { 15 | private static final String TAG = "difflog"; 16 | 17 | @Override 18 | public void onCreate() { 19 | super.onCreate(); 20 | Logger.init(TAG); 21 | Stetho.initialize(Stetho.newInitializerBuilder(this) 22 | .enableDumpapp(Stetho.defaultDumperPluginsProvider(this)) 23 | .enableWebKitInspector(Stetho.defaultInspectorModulesProvider(this)) 24 | .build()); 25 | LeakCanary.install(this); 26 | Fresco.initialize(this); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/adapter/MainAdapter.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.adapter; 2 | 3 | import android.content.Context; 4 | import android.net.Uri; 5 | import android.support.v4.content.ContextCompat; 6 | import android.support.v7.widget.CardView; 7 | import android.support.v7.widget.RecyclerView; 8 | import android.view.LayoutInflater; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | import android.view.animation.AnimationUtils; 12 | import android.widget.RelativeLayout; 13 | import android.widget.TextView; 14 | 15 | import com.diffey.view.rxzhihu.R; 16 | import com.diffey.view.rxzhihu.bean.StoriesEntity; 17 | import com.diffey.view.rxzhihu.db.bean.NewBean; 18 | import com.diffey.view.rxzhihu.db.dao.NewDao; 19 | import com.diffey.view.rxzhihu.util.IntentUtils; 20 | import com.facebook.drawee.view.SimpleDraweeView; 21 | 22 | import java.util.ArrayList; 23 | import java.util.List; 24 | 25 | import butterknife.Bind; 26 | import butterknife.ButterKnife; 27 | 28 | /** 29 | * Created by diff on 2016/2/4. 30 | */ 31 | public class MainAdapter extends RecyclerView.Adapter { 32 | 33 | private Context mContext; 34 | private ArrayList storiesList; 35 | private long lastPos = -1; 36 | private NewDao newDao; 37 | 38 | public MainAdapter(Context mContext) { 39 | this.mContext = mContext; 40 | this.newDao = new NewDao(mContext); 41 | } 42 | 43 | @Override 44 | public MainHodler onCreateViewHolder(ViewGroup parent, int viewType) { 45 | View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_main, parent, false); 46 | return new MainHodler(view); 47 | } 48 | 49 | @Override 50 | public void onBindViewHolder(final MainHodler holder, final int position) { 51 | final StoriesEntity sto = storiesList.get(position); 52 | if (sto == null) { 53 | return; 54 | } 55 | 56 | if (sto.isRead()) { 57 | setTextColor(holder.itemMainTxtTitle, R.color.colorddd); 58 | } else { 59 | setTextColor(holder.itemMainTxtTitle, R.color.color666); 60 | } 61 | holder.itemMainTxtTitle.setText(sto.getTitle()); 62 | 63 | List imgs = sto.getImages(); 64 | if (imgs != null && imgs.size() > 0) { 65 | holder.itemMainImg.setImageURI(Uri.parse(imgs.get(0))); 66 | } 67 | 68 | holder.itemMainRl.setOnClickListener(v -> { 69 | if (!sto.isRead()) { 70 | setTextColor(holder.itemMainTxtTitle, R.color.colorddd); 71 | sto.setRead(true); 72 | new Thread(() -> newDao.addNewBean(new NewBean(sto.getId()))).start(); 73 | } 74 | IntentUtils.toStoryActivity(mContext, position, storiesList); 75 | }); 76 | startAnimator(holder.itemMainCard, position); 77 | } 78 | 79 | private void setTextColor(TextView textView, int color) { 80 | textView.setTextColor(ContextCompat.getColor(mContext, color)); 81 | } 82 | 83 | private void startAnimator(View view, long position) { 84 | if (position > lastPos) { 85 | view.startAnimation(AnimationUtils.loadAnimation(this.mContext, R.anim.item_bottom_in)); 86 | lastPos = position; 87 | } 88 | } 89 | 90 | @Override 91 | public int getItemCount() { 92 | return storiesList == null ? 0 : storiesList.size(); 93 | } 94 | 95 | @Override 96 | public void onViewDetachedFromWindow(MainAdapter.MainHodler holder) { 97 | holder.itemMainCard.clearAnimation(); 98 | } 99 | 100 | 101 | public void changeData(ArrayList list) { 102 | storiesList = list; 103 | notifyDataSetChanged(); 104 | } 105 | 106 | public void addData(ArrayList list) { 107 | if (storiesList == null) { 108 | changeData(list); 109 | } else { 110 | storiesList.addAll(list); 111 | notifyDataSetChanged(); 112 | } 113 | } 114 | 115 | class MainHodler extends RecyclerView.ViewHolder { 116 | @Bind(R.id.item_main_txt_title) 117 | TextView itemMainTxtTitle; 118 | 119 | @Bind(R.id.item_main_img) 120 | SimpleDraweeView itemMainImg; 121 | 122 | @Bind(R.id.item_main_rl) 123 | RelativeLayout itemMainRl; 124 | 125 | @Bind(R.id.item_main_card) 126 | CardView itemMainCard; 127 | 128 | 129 | public MainHodler(View itemView) { 130 | super(itemView); 131 | ButterKnife.bind(this, itemView); 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/adapter/MainMenuAdapter.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.adapter; 2 | 3 | import android.content.Context; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.BaseAdapter; 8 | import android.widget.ImageView; 9 | import android.widget.TextView; 10 | 11 | import com.diffey.view.rxzhihu.R; 12 | import com.diffey.view.rxzhihu.bean.MenuItem; 13 | 14 | import java.util.List; 15 | 16 | /** 17 | * Created by diff on 2016/2/3. 18 | */ 19 | public class MainMenuAdapter extends BaseAdapter { 20 | private Context mContext; 21 | private List menuItemList; 22 | 23 | public MainMenuAdapter(Context context, List menuItemList) { 24 | mContext = context; 25 | this.menuItemList = menuItemList; 26 | } 27 | 28 | @Override 29 | public int getCount() { 30 | return menuItemList == null ? 0 : menuItemList.size(); 31 | } 32 | 33 | @Override 34 | public Object getItem(int position) { 35 | return menuItemList.get(position); 36 | } 37 | 38 | @Override 39 | public long getItemId(int position) { 40 | return position; 41 | } 42 | 43 | @Override 44 | public View getView(int position, View convertView, ViewGroup parent) { 45 | ViewHolder viewHolder; 46 | if (convertView == null) { 47 | convertView = LayoutInflater.from(mContext).inflate(R.layout.item_main_menu, parent, false); 48 | viewHolder = new ViewHolder(); 49 | viewHolder.imageView = (ImageView) convertView.findViewById(R.id.item_main_menu_img); 50 | viewHolder.textView = (TextView) convertView.findViewById(R.id.item_main_menu_txt); 51 | convertView.setTag(viewHolder); 52 | } else { 53 | viewHolder = (ViewHolder) convertView.getTag(); 54 | } 55 | 56 | viewHolder.imageView.setImageResource(menuItemList.get(position).getResId()); 57 | viewHolder.textView.setText(menuItemList.get(position).getTitle()); 58 | 59 | return convertView; 60 | } 61 | 62 | class ViewHolder { 63 | ImageView imageView; 64 | TextView textView; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/adapter/StoryAdapter.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.adapter; 2 | 3 | import android.os.Bundle; 4 | import android.support.v4.app.Fragment; 5 | import android.support.v4.app.FragmentManager; 6 | import android.support.v4.app.FragmentPagerAdapter; 7 | 8 | import com.diffey.view.rxzhihu.bean.StoriesEntity; 9 | import com.diffey.view.rxzhihu.ui.fragment.StoryFragment; 10 | 11 | import java.util.ArrayList; 12 | 13 | /** 14 | * Created by diff on 2016/2/5. 15 | */ 16 | public class StoryAdapter extends FragmentPagerAdapter { 17 | private ArrayList storiesEntities; 18 | 19 | public StoryAdapter(FragmentManager fm, ArrayList storiesEntities) { 20 | super(fm); 21 | this.storiesEntities = storiesEntities; 22 | } 23 | 24 | @Override 25 | public Fragment getItem(int position) { 26 | StoryFragment storyFragment = new StoryFragment(); 27 | Bundle bundle = new Bundle(); 28 | bundle.putInt(StoryFragment.PARAM_ID, storiesEntities.get(position).getId()); 29 | storyFragment.setArguments(bundle); 30 | return storyFragment; 31 | } 32 | 33 | @Override 34 | public int getCount() { 35 | return storiesEntities == null ? 0 : storiesEntities.size(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/adapter/TRClientAdapter.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.adapter; 2 | 3 | import android.content.Context; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.BaseAdapter; 8 | import android.widget.TextView; 9 | 10 | import com.diffey.view.rxzhihu.R; 11 | import com.diffey.view.rxzhihu.bean.ChatBean; 12 | 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | 16 | /** 17 | * Created by diff on 2016/2/15. 18 | */ 19 | public class TRClientAdapter extends BaseAdapter { 20 | private static final int VIEW_TYPE = 2; 21 | public static final int TYPE_USER = 0; 22 | public static final int TYPE_ROBOT = 1; 23 | 24 | private List list; 25 | private Context mContext; 26 | 27 | public TRClientAdapter(Context mContext) { 28 | this.mContext = mContext; 29 | } 30 | 31 | public TRClientAdapter(Context mContext, List list) { 32 | this.mContext = mContext; 33 | this.list = list; 34 | } 35 | 36 | public void addData(ChatBean chatBean) { 37 | if (list == null) { 38 | list = new ArrayList<>(); 39 | } 40 | 41 | list.add(chatBean); 42 | notifyDataSetChanged(); 43 | } 44 | 45 | @Override 46 | public int getViewTypeCount() { 47 | return VIEW_TYPE; 48 | } 49 | 50 | @Override 51 | public int getItemViewType(int position) { 52 | return list.get(position).getType(); 53 | } 54 | 55 | @Override 56 | public int getCount() { 57 | return list == null ? 0 : list.size(); 58 | } 59 | 60 | @Override 61 | public Object getItem(int position) { 62 | return list.get(position); 63 | } 64 | 65 | @Override 66 | public long getItemId(int position) { 67 | return position; 68 | } 69 | 70 | @Override 71 | public View getView(int position, View convertView, ViewGroup parent) { 72 | ViewHolder viewHolder; 73 | if (convertView == null) { 74 | viewHolder = new ViewHolder(); 75 | 76 | if (getItemViewType(position) == TYPE_USER) { 77 | convertView = LayoutInflater.from(mContext).inflate(R.layout.item_trc, parent, false); 78 | viewHolder.textView = (TextView) convertView.findViewById(R.id.item_trc_txt); 79 | } else { 80 | convertView = LayoutInflater.from(mContext).inflate(R.layout.item_trc_robot, parent, false); 81 | viewHolder.textView = (TextView) convertView.findViewById(R.id.item_trc_robot_txt); 82 | } 83 | 84 | convertView.setTag(viewHolder); 85 | } else { 86 | viewHolder = (ViewHolder) convertView.getTag(); 87 | } 88 | 89 | viewHolder.textView.setText(list.get(position).getInfo()); 90 | 91 | return convertView; 92 | } 93 | 94 | class ViewHolder { 95 | TextView textView; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/api/TRApi.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.api; 2 | 3 | import com.diffey.view.rxzhihu.bean.TREntity; 4 | 5 | import retrofit2.Call; 6 | import retrofit2.http.Field; 7 | import retrofit2.http.FormUrlEncoded; 8 | import retrofit2.http.POST; 9 | 10 | /** 11 | * Created by diff on 2016/2/16. 12 | */ 13 | public interface TRApi { 14 | 15 | @FormUrlEncoded 16 | @POST("api") 17 | Call getTRResponse(@Field("key") String key, @Field("info") String info, @Field("userid") String userid); 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/api/TRService.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.api; 2 | 3 | import retrofit2.Retrofit; 4 | import retrofit2.converter.gson.GsonConverterFactory; 5 | 6 | /** 7 | * Created by diff on 2016/2/15. 8 | */ 9 | public class TRService { 10 | public static final String BASE_TRC_URL = "http://www.tuling123.com/openapi/"; 11 | 12 | private static Retrofit retrofit = new Retrofit.Builder() 13 | .baseUrl(BASE_TRC_URL) 14 | .addConverterFactory(GsonConverterFactory.create()) 15 | .build(); 16 | 17 | private TRService() { 18 | } 19 | 20 | public static TRApi createTRService() { 21 | return retrofit.create(TRApi.class); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/api/ZhihuApi.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.api; 2 | 3 | import com.diffey.view.rxzhihu.bean.NewsEntity; 4 | import com.diffey.view.rxzhihu.bean.StoryDetailsEntity; 5 | 6 | import retrofit2.http.GET; 7 | import retrofit2.http.Path; 8 | import rx.Observable; 9 | 10 | /** 11 | * Created by diff on 2016/2/16. 12 | */ 13 | public interface ZhihuApi { 14 | 15 | @GET("api/4/news/latest") 16 | Observable getLastestNews(); 17 | 18 | @GET("api/4/news/before/{id}") 19 | Observable getBeforeNews(@Path("id") String id); 20 | 21 | @GET("api/4/news/{id}") 22 | Observable getNewsDetails(@Path("id") int id); 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/api/ZhihuService.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.api; 2 | 3 | import retrofit2.Retrofit; 4 | import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; 5 | import retrofit2.converter.gson.GsonConverterFactory; 6 | 7 | /** 8 | * Created by diff on 2016/2/15. 9 | */ 10 | public class ZhihuService { 11 | public static final String BASE_ZHIHU_URL = "http://news-at.zhihu.com/"; 12 | 13 | private static Retrofit retrofit = new Retrofit.Builder() 14 | .baseUrl(BASE_ZHIHU_URL) 15 | .addConverterFactory(GsonConverterFactory.create()) 16 | .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) 17 | .build(); 18 | 19 | private ZhihuService() { 20 | } 21 | 22 | public static ZhihuApi createZhihuService() { 23 | return retrofit.create(ZhihuApi.class); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/base/BaseActivity.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.base; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.annotation.Nullable; 6 | import android.support.v7.app.AppCompatActivity; 7 | 8 | /** 9 | * Created by diff on 2016/2/2. 10 | */ 11 | public abstract class BaseActivity extends AppCompatActivity { 12 | @Override 13 | protected void onCreate(@Nullable Bundle savedInstanceState) { 14 | super.onCreate(savedInstanceState); 15 | beforeContentView(); 16 | setContentView(getContentView()); 17 | obtainParam(getIntent()); 18 | initView(); 19 | initListener(); 20 | initData(); 21 | } 22 | 23 | protected abstract void obtainParam(Intent intent); 24 | 25 | protected abstract void beforeContentView(); 26 | 27 | protected abstract int getContentView(); 28 | 29 | protected abstract void initView(); 30 | 31 | protected abstract void initListener(); 32 | 33 | protected abstract void initData(); 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/base/BaseFragemnt.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.base; 2 | 3 | /** 4 | * Created by diff on 2016/2/2. 5 | */ 6 | public class BaseFragemnt { 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/base/SimpleActivity.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.base; 2 | 3 | import android.content.Intent; 4 | 5 | /** 6 | * Created by diff on 2016/2/3. 7 | */ 8 | public abstract class SimpleActivity extends BaseActivity { 9 | @Override 10 | protected void beforeContentView() { 11 | 12 | } 13 | 14 | @Override 15 | protected void obtainParam(Intent intent) { 16 | 17 | } 18 | 19 | @Override 20 | protected void initView() { 21 | 22 | } 23 | 24 | @Override 25 | protected void initListener() { 26 | 27 | } 28 | 29 | @Override 30 | protected void initData() { 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/bean/ChatBean.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.bean; 2 | 3 | /** 4 | * Created by diff on 2016/2/15. 5 | */ 6 | public class ChatBean { 7 | private int type; 8 | private String info; 9 | 10 | public ChatBean(int type, String info) { 11 | this.type = type; 12 | this.info = info; 13 | } 14 | 15 | public String getInfo() { 16 | return info; 17 | } 18 | 19 | public void setInfo(String info) { 20 | this.info = info; 21 | } 22 | 23 | public int getType() { 24 | return type; 25 | } 26 | 27 | public void setType(int type) { 28 | this.type = type; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/bean/MenuItem.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.bean; 2 | 3 | /** 4 | * Created by diff on 2016/2/6. 5 | */ 6 | public class MenuItem { 7 | private String title; 8 | private int resId; 9 | 10 | public MenuItem(int resId, String title) { 11 | this.resId = resId; 12 | this.title = title; 13 | } 14 | 15 | public int getResId() { 16 | return resId; 17 | } 18 | 19 | public void setResId(int resId) { 20 | this.resId = resId; 21 | } 22 | 23 | public String getTitle() { 24 | return title; 25 | } 26 | 27 | public void setTitle(String title) { 28 | this.title = title; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/bean/NewsEntity.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.bean; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * Created by diff on 2016/2/3. 11 | */ 12 | public class NewsEntity implements Parcelable { 13 | 14 | private String date; 15 | 16 | private ArrayList stories; 17 | 18 | private List top_stories; 19 | 20 | 21 | public void setDate(String date) { 22 | this.date = date; 23 | } 24 | 25 | public void setStories(ArrayList stories) { 26 | this.stories = stories; 27 | } 28 | 29 | public void setTop_stories(List top_stories) { 30 | this.top_stories = top_stories; 31 | } 32 | 33 | public String getDate() { 34 | return date; 35 | } 36 | 37 | public ArrayList getStories() { 38 | return stories; 39 | } 40 | 41 | public List getTop_stories() { 42 | return top_stories; 43 | } 44 | 45 | 46 | @Override 47 | public int describeContents() { 48 | return 0; 49 | } 50 | 51 | @Override 52 | public void writeToParcel(Parcel dest, int flags) { 53 | dest.writeString(this.date); 54 | dest.writeList(this.stories); 55 | dest.writeList(this.top_stories); 56 | } 57 | 58 | public NewsEntity() { 59 | } 60 | 61 | protected NewsEntity(Parcel in) { 62 | this.date = in.readString(); 63 | this.stories = new ArrayList(); 64 | in.readList(this.stories, List.class.getClassLoader()); 65 | this.top_stories = new ArrayList(); 66 | in.readList(this.top_stories, List.class.getClassLoader()); 67 | } 68 | 69 | public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { 70 | public NewsEntity createFromParcel(Parcel source) { 71 | return new NewsEntity(source); 72 | } 73 | 74 | public NewsEntity[] newArray(int size) { 75 | return new NewsEntity[size]; 76 | } 77 | }; 78 | 79 | @Override 80 | public String toString() { 81 | return "NewsEntity{" + 82 | "date='" + date + '\'' + 83 | ", stories=" + stories + 84 | ", top_stories=" + top_stories + 85 | '}'; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/bean/StoriesEntity.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.bean; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | 6 | import java.util.List; 7 | 8 | public class StoriesEntity implements Parcelable { 9 | private int type; 10 | private int id; 11 | private String ga_prefix; 12 | private String title; 13 | private List images; 14 | private boolean isRead = false; 15 | 16 | public void setType(int type) { 17 | this.type = type; 18 | } 19 | 20 | public void setId(int id) { 21 | this.id = id; 22 | } 23 | 24 | public void setGa_prefix(String ga_prefix) { 25 | this.ga_prefix = ga_prefix; 26 | } 27 | 28 | public void setTitle(String title) { 29 | this.title = title; 30 | } 31 | 32 | public void setImages(List images) { 33 | this.images = images; 34 | } 35 | 36 | public int getType() { 37 | return type; 38 | } 39 | 40 | public int getId() { 41 | return id; 42 | } 43 | 44 | public String getGa_prefix() { 45 | return ga_prefix; 46 | } 47 | 48 | public String getTitle() { 49 | return title; 50 | } 51 | 52 | public List getImages() { 53 | return images; 54 | } 55 | 56 | public boolean isRead() { 57 | return isRead; 58 | } 59 | 60 | public void setRead(boolean read) { 61 | isRead = read; 62 | } 63 | 64 | @Override 65 | public String toString() { 66 | return "StoriesEntity{" + 67 | "ga_prefix='" + ga_prefix + '\'' + 68 | ", type=" + type + 69 | ", id=" + id + 70 | ", title='" + title + '\'' + 71 | ", images=" + images + 72 | ", isRead=" + isRead + 73 | '}'; 74 | } 75 | 76 | public StoriesEntity() { 77 | } 78 | 79 | @Override 80 | public int describeContents() { 81 | return 0; 82 | } 83 | 84 | @Override 85 | public void writeToParcel(Parcel dest, int flags) { 86 | dest.writeInt(this.type); 87 | dest.writeInt(this.id); 88 | dest.writeString(this.ga_prefix); 89 | dest.writeString(this.title); 90 | dest.writeStringList(this.images); 91 | dest.writeByte(isRead ? (byte) 1 : (byte) 0); 92 | } 93 | 94 | protected StoriesEntity(Parcel in) { 95 | this.type = in.readInt(); 96 | this.id = in.readInt(); 97 | this.ga_prefix = in.readString(); 98 | this.title = in.readString(); 99 | this.images = in.createStringArrayList(); 100 | this.isRead = in.readByte() != 0; 101 | } 102 | 103 | public static final Creator CREATOR = new Creator() { 104 | public StoriesEntity createFromParcel(Parcel source) { 105 | return new StoriesEntity(source); 106 | } 107 | 108 | public StoriesEntity[] newArray(int size) { 109 | return new StoriesEntity[size]; 110 | } 111 | }; 112 | } 113 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/bean/StoryDetailsEntity.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.bean; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Created by diff on 2016/2/4. 10 | */ 11 | public class StoryDetailsEntity implements Parcelable { 12 | 13 | private String body; 14 | private String image_source; 15 | private String title; 16 | private String image; 17 | private String share_url; 18 | private String ga_prefix; 19 | private int type; 20 | private int id; 21 | private List css; 22 | 23 | public void setBody(String body) { 24 | this.body = body; 25 | } 26 | 27 | public void setImage_source(String image_source) { 28 | this.image_source = image_source; 29 | } 30 | 31 | public void setTitle(String title) { 32 | this.title = title; 33 | } 34 | 35 | public void setImage(String image) { 36 | this.image = image; 37 | } 38 | 39 | public void setShare_url(String share_url) { 40 | this.share_url = share_url; 41 | } 42 | 43 | public void setGa_prefix(String ga_prefix) { 44 | this.ga_prefix = ga_prefix; 45 | } 46 | 47 | public void setType(int type) { 48 | this.type = type; 49 | } 50 | 51 | public void setId(int id) { 52 | this.id = id; 53 | } 54 | 55 | public void setCss(List css) { 56 | this.css = css; 57 | } 58 | 59 | public String getBody() { 60 | return body; 61 | } 62 | 63 | public String getImage_source() { 64 | return image_source; 65 | } 66 | 67 | public String getTitle() { 68 | return title; 69 | } 70 | 71 | public String getImage() { 72 | return image; 73 | } 74 | 75 | public String getShare_url() { 76 | return share_url; 77 | } 78 | 79 | public String getGa_prefix() { 80 | return ga_prefix; 81 | } 82 | 83 | public int getType() { 84 | return type; 85 | } 86 | 87 | public int getId() { 88 | return id; 89 | } 90 | 91 | public List getCss() { 92 | return css; 93 | } 94 | 95 | @Override 96 | public int describeContents() { 97 | return 0; 98 | } 99 | 100 | @Override 101 | public void writeToParcel(Parcel dest, int flags) { 102 | dest.writeString(this.body); 103 | dest.writeString(this.image_source); 104 | dest.writeString(this.title); 105 | dest.writeString(this.image); 106 | dest.writeString(this.share_url); 107 | dest.writeString(this.ga_prefix); 108 | dest.writeInt(this.type); 109 | dest.writeInt(this.id); 110 | dest.writeStringList(this.css); 111 | } 112 | 113 | public StoryDetailsEntity() { 114 | } 115 | 116 | protected StoryDetailsEntity(Parcel in) { 117 | this.body = in.readString(); 118 | this.image_source = in.readString(); 119 | this.title = in.readString(); 120 | this.image = in.readString(); 121 | this.share_url = in.readString(); 122 | this.ga_prefix = in.readString(); 123 | this.type = in.readInt(); 124 | this.id = in.readInt(); 125 | this.css = in.createStringArrayList(); 126 | } 127 | 128 | public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { 129 | public StoryDetailsEntity createFromParcel(Parcel source) { 130 | return new StoryDetailsEntity(source); 131 | } 132 | 133 | public StoryDetailsEntity[] newArray(int size) { 134 | return new StoryDetailsEntity[size]; 135 | } 136 | }; 137 | } 138 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/bean/TREntity.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.bean; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | 6 | /** 7 | * Created by diff on 2016/2/15. 8 | */ 9 | public class TREntity implements Parcelable { 10 | 11 | private int code; 12 | private String text; 13 | 14 | public void setCode(int code) { 15 | this.code = code; 16 | } 17 | 18 | public void setText(String text) { 19 | this.text = text; 20 | } 21 | 22 | public int getCode() { 23 | return code; 24 | } 25 | 26 | public String getText() { 27 | return text; 28 | } 29 | 30 | @Override 31 | public String toString() { 32 | return "TREntity{" + 33 | "code=" + code + 34 | ", text='" + text + '\'' + 35 | '}'; 36 | } 37 | 38 | @Override 39 | public int describeContents() { 40 | return 0; 41 | } 42 | 43 | @Override 44 | public void writeToParcel(Parcel dest, int flags) { 45 | dest.writeInt(this.code); 46 | dest.writeString(this.text); 47 | } 48 | 49 | public TREntity() { 50 | } 51 | 52 | protected TREntity(Parcel in) { 53 | this.code = in.readInt(); 54 | this.text = in.readString(); 55 | } 56 | 57 | public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { 58 | public TREntity createFromParcel(Parcel source) { 59 | return new TREntity(source); 60 | } 61 | 62 | public TREntity[] newArray(int size) { 63 | return new TREntity[size]; 64 | } 65 | }; 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/bean/TopStoriesEntity.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.bean; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | 6 | public class TopStoriesEntity implements Parcelable { 7 | private String image; 8 | private int type; 9 | private int id; 10 | private String ga_prefix; 11 | private String title; 12 | 13 | public void setImage(String image) { 14 | this.image = image; 15 | } 16 | 17 | public void setType(int type) { 18 | this.type = type; 19 | } 20 | 21 | public void setId(int id) { 22 | this.id = id; 23 | } 24 | 25 | public void setGa_prefix(String ga_prefix) { 26 | this.ga_prefix = ga_prefix; 27 | } 28 | 29 | public void setTitle(String title) { 30 | this.title = title; 31 | } 32 | 33 | public String getImage() { 34 | return image; 35 | } 36 | 37 | public int getType() { 38 | return type; 39 | } 40 | 41 | public int getId() { 42 | return id; 43 | } 44 | 45 | public String getGa_prefix() { 46 | return ga_prefix; 47 | } 48 | 49 | public String getTitle() { 50 | return title; 51 | } 52 | 53 | @Override 54 | public String toString() { 55 | return "TopStoriesEntity{" + 56 | "ga_prefix='" + ga_prefix + '\'' + 57 | ", image='" + image + '\'' + 58 | ", type=" + type + 59 | ", id=" + id + 60 | ", title='" + title + '\'' + 61 | '}'; 62 | } 63 | 64 | @Override 65 | public int describeContents() { 66 | return 0; 67 | } 68 | 69 | @Override 70 | public void writeToParcel(Parcel dest, int flags) { 71 | dest.writeString(this.image); 72 | dest.writeInt(this.type); 73 | dest.writeInt(this.id); 74 | dest.writeString(this.ga_prefix); 75 | dest.writeString(this.title); 76 | } 77 | 78 | public TopStoriesEntity() { 79 | } 80 | 81 | protected TopStoriesEntity(Parcel in) { 82 | this.image = in.readString(); 83 | this.type = in.readInt(); 84 | this.id = in.readInt(); 85 | this.ga_prefix = in.readString(); 86 | this.title = in.readString(); 87 | } 88 | 89 | public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { 90 | public TopStoriesEntity createFromParcel(Parcel source) { 91 | return new TopStoriesEntity(source); 92 | } 93 | 94 | public TopStoriesEntity[] newArray(int size) { 95 | return new TopStoriesEntity[size]; 96 | } 97 | }; 98 | } -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/contant/Contant.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.contant; 2 | 3 | /** 4 | * Created by diff on 2016/2/15. 5 | */ 6 | public class Contant { 7 | public static final String TRC_KEY = "ae536b38aa743f17ecb5f0e65a8dfea9"; 8 | public static final String TRC_USER_ID = "diffey"; 9 | public static final String TRC_ROBOT_REC = "嗨,我是智能聊天机器人小er,聊两块钱的"; 10 | public static final String TRC_ROBOT_REST = "小er已经休息,请明天再聊。"; 11 | public static final String TRC_ROBOT_FAILED = "暂时无法回应"; 12 | 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/contant/UrlContant.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.contant; 2 | 3 | /** 4 | * Created by diff on 2016/2/3. 5 | */ 6 | public class UrlContant { 7 | 8 | //github 9 | public static final String URL_DEV_GITHUB = "https://github.com/Runpop"; 10 | 11 | //简书 12 | public static final String URL_DEV_JIANSHU = "http://www.jianshu.com/users/e81e0133d845/latest_articles"; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/db/DBContant.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.db; 2 | 3 | /** 4 | * Created by diff on 2016/2/16. 5 | */ 6 | public class DBContant { 7 | public static final String DB_NAME = "Zhihu"; 8 | public static final int DB_VERSION = 1; 9 | 10 | public static final String TABLE_READ = "read"; 11 | public static final String READ_COL_NID = "nid"; 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/db/ZPOpenHelper.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.db; 2 | 3 | import android.content.Context; 4 | import android.database.sqlite.SQLiteDatabase; 5 | import android.database.sqlite.SQLiteOpenHelper; 6 | 7 | /** 8 | * Created by diff on 2016/2/16. 9 | */ 10 | public class ZPOpenHelper extends SQLiteOpenHelper { 11 | private static ZPOpenHelper zpOpenHelper; 12 | 13 | private ZPOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { 14 | super(context, name, factory, version); 15 | } 16 | 17 | public static ZPOpenHelper getInstance(Context context) { 18 | if (zpOpenHelper == null) { 19 | synchronized (ZPOpenHelper.class) { 20 | if (zpOpenHelper == null) { 21 | zpOpenHelper = new ZPOpenHelper(context.getApplicationContext(), DBContant.DB_NAME, null, DBContant.DB_VERSION); 22 | } 23 | } 24 | } 25 | return zpOpenHelper; 26 | } 27 | 28 | @Override 29 | public void onCreate(SQLiteDatabase db) { 30 | String createReadTable = "create table " + DBContant.TABLE_READ + "(" 31 | + DBContant.READ_COL_NID + " text)"; 32 | db.execSQL(createReadTable); 33 | } 34 | 35 | @Override 36 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 37 | 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/db/bean/NewBean.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.db.bean; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | 6 | /** 7 | * Created by diff on 2016/2/16. 8 | */ 9 | public class NewBean implements Parcelable { 10 | private int id; 11 | 12 | public NewBean(int id) { 13 | this.id = id; 14 | } 15 | 16 | public int getId() { 17 | return id; 18 | } 19 | 20 | public void setId(int id) { 21 | this.id = id; 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return "NewBean{" + 27 | "id=" + id + 28 | '}'; 29 | } 30 | 31 | @Override 32 | public int describeContents() { 33 | return 0; 34 | } 35 | 36 | @Override 37 | public void writeToParcel(Parcel dest, int flags) { 38 | dest.writeInt(this.id); 39 | } 40 | 41 | protected NewBean(Parcel in) { 42 | this.id = in.readInt(); 43 | } 44 | 45 | public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { 46 | public NewBean createFromParcel(Parcel source) { 47 | return new NewBean(source); 48 | } 49 | 50 | public NewBean[] newArray(int size) { 51 | return new NewBean[size]; 52 | } 53 | }; 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/db/dao/NewDao.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.db.dao; 2 | 3 | import android.content.ContentValues; 4 | import android.content.Context; 5 | import android.database.Cursor; 6 | import android.database.sqlite.SQLiteDatabase; 7 | 8 | import com.diffey.view.rxzhihu.db.DBContant; 9 | import com.diffey.view.rxzhihu.db.ZPOpenHelper; 10 | import com.diffey.view.rxzhihu.db.bean.NewBean; 11 | 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | /** 16 | * Created by diff on 2016/2/16. 17 | */ 18 | public class NewDao { 19 | private ZPOpenHelper zpOpenHelper; 20 | 21 | public NewDao(Context context) { 22 | zpOpenHelper = ZPOpenHelper.getInstance(context); 23 | } 24 | 25 | public void addNewBean(NewBean newBean) { 26 | SQLiteDatabase db = zpOpenHelper.getReadableDatabase(); 27 | ContentValues contentValues = new ContentValues(); 28 | contentValues.put(DBContant.READ_COL_NID, newBean.getId()); 29 | db.insert(DBContant.TABLE_READ, null, contentValues); 30 | db.close(); 31 | } 32 | 33 | public List getAllNewBeans() { 34 | List list = new ArrayList<>(); 35 | SQLiteDatabase db = zpOpenHelper.getReadableDatabase(); 36 | String rawQuery = "select * from " + DBContant.TABLE_READ; 37 | Cursor cursor = db.rawQuery(rawQuery, null); 38 | if (cursor.moveToFirst()) { 39 | do { 40 | NewBean newBean = new NewBean(cursor.getInt(0)); 41 | list.add(newBean); 42 | } while (cursor.moveToNext()); 43 | } 44 | return list; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/receiver/NetStateReceiver.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.receiver; 2 | 3 | import android.content.BroadcastReceiver; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | 7 | /** 8 | * Created by diff on 2016/2/16. 9 | */ 10 | public class NetStateReceiver extends BroadcastReceiver { 11 | @Override 12 | public void onReceive(Context context, Intent intent) { 13 | // if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) { 14 | // 15 | // } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/ui/activity/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.ui.activity; 2 | 3 | import android.app.FragmentManager; 4 | import android.app.FragmentTransaction; 5 | import android.content.res.Configuration; 6 | import android.os.Bundle; 7 | import android.support.v4.widget.DrawerLayout; 8 | import android.support.v7.app.ActionBar; 9 | import android.support.v7.app.ActionBarDrawerToggle; 10 | import android.support.v7.widget.Toolbar; 11 | import android.view.Gravity; 12 | import android.view.KeyEvent; 13 | import android.view.MenuItem; 14 | 15 | import com.diffey.view.rxzhihu.R; 16 | import com.diffey.view.rxzhihu.base.SimpleActivity; 17 | import com.diffey.view.rxzhihu.ui.fragment.MainFragment; 18 | import com.diffey.view.rxzhihu.ui.fragment.MainMenuFragment; 19 | 20 | import butterknife.Bind; 21 | import butterknife.ButterKnife; 22 | 23 | public class MainActivity extends SimpleActivity { 24 | 25 | @Bind(R.id.toolbar) 26 | Toolbar toolbar; 27 | 28 | @Bind(R.id.main_drawerlayout) 29 | DrawerLayout mainDrawerlayout; 30 | 31 | private ActionBarDrawerToggle drawerToggle; 32 | 33 | @Override 34 | protected int getContentView() { 35 | return R.layout.activity_main; 36 | } 37 | 38 | @Override 39 | protected void initView() { 40 | super.initView(); 41 | ButterKnife.bind(this); 42 | 43 | initToolBar(); 44 | addFragment(); 45 | } 46 | 47 | 48 | @Override 49 | protected void initData() { 50 | super.initData(); 51 | } 52 | 53 | private void initToolBar() { 54 | setSupportActionBar(toolbar); 55 | ActionBar actionBar = getSupportActionBar(); 56 | if (actionBar != null) { 57 | actionBar.setDisplayHomeAsUpEnabled(true); 58 | } 59 | 60 | drawerToggle = new ActionBarDrawerToggle(this, mainDrawerlayout, toolbar, 61 | R.string.app_name, R.string.app_name); 62 | drawerToggle.syncState(); 63 | mainDrawerlayout.setDrawerListener(drawerToggle); 64 | } 65 | 66 | private void addFragment() { 67 | FragmentManager manager = getFragmentManager(); 68 | FragmentTransaction transaction = manager.beginTransaction(); 69 | transaction.replace(R.id.main_content_container, new MainFragment()); 70 | transaction.replace(R.id.main_menu_container, new MainMenuFragment()); 71 | transaction.commit(); 72 | } 73 | 74 | @Override 75 | public boolean onKeyDown(int keyCode, KeyEvent event) { 76 | if (keyCode == KeyEvent.KEYCODE_BACK && mainDrawerlayout.isDrawerOpen(Gravity.LEFT)) { 77 | mainDrawerlayout.closeDrawers(); 78 | return true; 79 | } 80 | return super.onKeyDown(keyCode, event); 81 | } 82 | 83 | @Override 84 | public boolean onOptionsItemSelected(MenuItem item) { 85 | if (drawerToggle.onOptionsItemSelected(item)) { 86 | return true; 87 | } 88 | return super.onOptionsItemSelected(item); 89 | } 90 | 91 | 92 | @Override 93 | protected void onPostCreate(Bundle savedInstanceState) { 94 | super.onPostCreate(savedInstanceState); 95 | drawerToggle.syncState(); 96 | } 97 | 98 | 99 | @Override 100 | public void onConfigurationChanged(Configuration newConfig) { 101 | super.onConfigurationChanged(newConfig); 102 | drawerToggle.onConfigurationChanged(newConfig); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/ui/activity/SettingActivity.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.ui.activity; 2 | 3 | import android.support.v7.widget.Toolbar; 4 | 5 | import com.diffey.view.rxzhihu.R; 6 | import com.diffey.view.rxzhihu.base.SimpleActivity; 7 | 8 | import butterknife.Bind; 9 | import butterknife.ButterKnife; 10 | 11 | public class SettingActivity extends SimpleActivity { 12 | 13 | @Bind(R.id.toolbar) 14 | Toolbar toolbar; 15 | 16 | @Override 17 | protected int getContentView() { 18 | return R.layout.activity_setting; 19 | } 20 | 21 | @Override 22 | protected void initView() { 23 | super.initView(); 24 | ButterKnife.bind(this); 25 | initToolBar(); 26 | } 27 | 28 | private void initToolBar() { 29 | toolbar.setTitle("设置"); 30 | setSupportActionBar(toolbar); 31 | toolbar.setNavigationIcon(R.drawable.ic_actionbar_back); 32 | toolbar.setNavigationOnClickListener(v -> finish()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/ui/activity/StoryActivity.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.ui.activity; 2 | 3 | import android.content.Intent; 4 | import android.support.v4.view.ViewPager; 5 | import android.support.v7.widget.Toolbar; 6 | 7 | import com.diffey.view.rxzhihu.R; 8 | import com.diffey.view.rxzhihu.adapter.StoryAdapter; 9 | import com.diffey.view.rxzhihu.base.SimpleActivity; 10 | import com.diffey.view.rxzhihu.bean.StoriesEntity; 11 | 12 | import java.util.ArrayList; 13 | 14 | import butterknife.Bind; 15 | import butterknife.ButterKnife; 16 | 17 | public class StoryActivity extends SimpleActivity { 18 | 19 | public static final String PARAM_POS = "param_pos"; 20 | public static final String PARAM_DATA_LIST = "param_data_list"; 21 | 22 | @Bind(R.id.toolbar) 23 | Toolbar toolbar; 24 | 25 | @Bind(R.id.story_viewpager) 26 | ViewPager storyViewpager; 27 | 28 | private int curPos = -1; 29 | private ArrayList arrayList; 30 | 31 | @Override 32 | protected int getContentView() { 33 | return R.layout.activity_story; 34 | } 35 | 36 | @Override 37 | protected void obtainParam(Intent intent) { 38 | super.obtainParam(intent); 39 | curPos = intent.getIntExtra(PARAM_POS, -1); 40 | arrayList = intent.getParcelableArrayListExtra(PARAM_DATA_LIST); 41 | } 42 | 43 | @Override 44 | protected void initView() { 45 | super.initView(); 46 | ButterKnife.bind(this); 47 | initToolBar(); 48 | 49 | storyViewpager.setAdapter(new StoryAdapter(getSupportFragmentManager(), arrayList)); 50 | storyViewpager.setCurrentItem(curPos); 51 | } 52 | 53 | private void initToolBar() { 54 | setSupportActionBar(toolbar); 55 | toolbar.setNavigationIcon(R.drawable.ic_actionbar_back); 56 | toolbar.setNavigationOnClickListener(v -> finish()); 57 | } 58 | 59 | @Override 60 | protected void initData() { 61 | super.initData(); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/ui/activity/TRClientActivity.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.ui.activity; 2 | 3 | import android.support.v7.widget.Toolbar; 4 | import android.text.TextUtils; 5 | import android.widget.Button; 6 | import android.widget.EditText; 7 | import android.widget.ListView; 8 | import android.widget.RelativeLayout; 9 | 10 | import com.diffey.view.rxzhihu.R; 11 | import com.diffey.view.rxzhihu.adapter.TRClientAdapter; 12 | import com.diffey.view.rxzhihu.api.TRApi; 13 | import com.diffey.view.rxzhihu.api.TRService; 14 | import com.diffey.view.rxzhihu.base.SimpleActivity; 15 | import com.diffey.view.rxzhihu.bean.ChatBean; 16 | import com.diffey.view.rxzhihu.bean.TREntity; 17 | import com.diffey.view.rxzhihu.contant.Contant; 18 | 19 | import butterknife.Bind; 20 | import butterknife.ButterKnife; 21 | import retrofit2.Call; 22 | import retrofit2.Callback; 23 | import retrofit2.Response; 24 | 25 | public class TRClientActivity extends SimpleActivity { 26 | 27 | @Bind(R.id.toolbar) 28 | Toolbar toolbar; 29 | 30 | @Bind(R.id.trc_list) 31 | ListView trcList; 32 | 33 | @Bind(R.id.trc_edit) 34 | EditText trcEdit; 35 | 36 | @Bind(R.id.trc_btn_send) 37 | Button trcBtnSend; 38 | 39 | @Bind(R.id.trc_bottom) 40 | RelativeLayout trcBottom; 41 | 42 | private TRClientAdapter trClientAdapter; 43 | private TRApi service; 44 | 45 | @Override 46 | protected int getContentView() { 47 | return R.layout.activity_trclient; 48 | } 49 | 50 | @Override 51 | protected void initView() { 52 | super.initView(); 53 | ButterKnife.bind(this); 54 | 55 | initToolBar(); 56 | trClientAdapter = new TRClientAdapter(this); 57 | trcList.setAdapter(trClientAdapter); 58 | } 59 | 60 | private void initToolBar() { 61 | toolbar.setTitle("小er"); 62 | setSupportActionBar(toolbar); 63 | toolbar.setNavigationIcon(R.drawable.ic_actionbar_back); 64 | toolbar.setNavigationOnClickListener(v -> finish()); 65 | } 66 | 67 | @Override 68 | protected void initData() { 69 | super.initData(); 70 | service = TRService.createTRService(); 71 | trClientAdapter.addData(new ChatBean(TRClientAdapter.TYPE_ROBOT, Contant.TRC_ROBOT_REC)); 72 | } 73 | 74 | @Override 75 | protected void initListener() { 76 | super.initListener(); 77 | trcBtnSend.setOnClickListener(v -> { 78 | String str = trcEdit.getText().toString(); 79 | if (TextUtils.isEmpty(str)) { 80 | return; 81 | } 82 | addData(new ChatBean(TRClientAdapter.TYPE_USER, str)); 83 | trcEdit.setText(""); 84 | gainChat(str); 85 | }); 86 | } 87 | 88 | private void gainChat(String str) { 89 | Call call = service.getTRResponse(Contant.TRC_KEY, str, Contant.TRC_USER_ID); 90 | call.enqueue(new Callback() { 91 | @Override 92 | public void onResponse(Call call, Response response) { 93 | TREntity entity = response.body(); 94 | if (entity != null) { 95 | String str; 96 | if (entity.getCode() == 40004) { 97 | str = Contant.TRC_ROBOT_REST; 98 | } else { 99 | str = entity.getText(); 100 | } 101 | addData(new ChatBean(TRClientAdapter.TYPE_ROBOT, str)); 102 | } 103 | } 104 | 105 | @Override 106 | public void onFailure(Call call, Throwable t) { 107 | addData(new ChatBean(TRClientAdapter.TYPE_ROBOT, Contant.TRC_ROBOT_FAILED)); 108 | } 109 | }); 110 | } 111 | 112 | private void addData(ChatBean chatBean) { 113 | trClientAdapter.addData(chatBean); 114 | trcList.setSelection(trClientAdapter.getCount()); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/ui/fragment/MainFragment.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.ui.fragment; 2 | 3 | import android.app.Fragment; 4 | import android.content.Context; 5 | import android.graphics.Color; 6 | import android.os.Bundle; 7 | import android.support.annotation.Nullable; 8 | import android.support.v4.content.ContextCompat; 9 | import android.support.v7.widget.DefaultItemAnimator; 10 | import android.support.v7.widget.LinearLayoutManager; 11 | import android.view.LayoutInflater; 12 | import android.view.Menu; 13 | import android.view.MenuInflater; 14 | import android.view.MenuItem; 15 | import android.view.View; 16 | import android.view.ViewGroup; 17 | import android.widget.FrameLayout; 18 | import android.widget.RelativeLayout; 19 | 20 | import com.diffey.view.rxzhihu.R; 21 | import com.diffey.view.rxzhihu.adapter.MainAdapter; 22 | import com.diffey.view.rxzhihu.api.ZhihuApi; 23 | import com.diffey.view.rxzhihu.api.ZhihuService; 24 | import com.diffey.view.rxzhihu.bean.NewsEntity; 25 | import com.diffey.view.rxzhihu.bean.StoriesEntity; 26 | import com.diffey.view.rxzhihu.db.bean.NewBean; 27 | import com.diffey.view.rxzhihu.db.dao.NewDao; 28 | import com.diffey.view.rxzhihu.util.ViewUtils; 29 | import com.diffey.view.rxzhihu.view.AutoLoadRecylerView; 30 | 31 | import java.util.ArrayList; 32 | import java.util.List; 33 | 34 | import butterknife.Bind; 35 | import butterknife.ButterKnife; 36 | import jp.co.recruit_lifestyle.android.widget.WaveSwipeRefreshLayout; 37 | import rx.android.schedulers.AndroidSchedulers; 38 | import rx.schedulers.Schedulers; 39 | 40 | /** 41 | * Created by diff on 2016/2/3. 42 | */ 43 | public class MainFragment extends Fragment implements WaveSwipeRefreshLayout.OnRefreshListener, AutoLoadRecylerView.loadMoreListener { 44 | 45 | @Bind(R.id.main_recycler) 46 | AutoLoadRecylerView mainRecycler; 47 | 48 | @Bind(R.id.main_wsrefresh) 49 | WaveSwipeRefreshLayout mainWsrefresh; 50 | 51 | @Bind(R.id.common_loading) 52 | FrameLayout commonLoading; 53 | 54 | @Bind(R.id.common_error) 55 | RelativeLayout commonError; 56 | 57 | private Context mActivity; 58 | private MainAdapter mainAdapter; 59 | private String curDate; 60 | 61 | private NewDao dao; 62 | private List beanList; 63 | 64 | @Override 65 | public void onCreate(@Nullable Bundle savedInstanceState) { 66 | super.onCreate(savedInstanceState); 67 | mActivity = getActivity(); 68 | setHasOptionsMenu(true); 69 | } 70 | 71 | @Nullable 72 | @Override 73 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 74 | View view = inflater.inflate(R.layout.fragment_main, container, false); 75 | ButterKnife.bind(this, view); 76 | return view; 77 | } 78 | 79 | @Override 80 | public void onViewCreated(View view, Bundle savedInstanceState) { 81 | super.onViewCreated(view, savedInstanceState); 82 | mainWsrefresh.setColorSchemeColors(Color.WHITE); 83 | mainWsrefresh.setWaveColor(ContextCompat.getColor(mActivity, R.color.colorPrimary)); 84 | mainWsrefresh.setOnRefreshListener(this); 85 | 86 | mainRecycler.setHasFixedSize(true); 87 | mainRecycler.setLayoutManager(new LinearLayoutManager(mActivity)); 88 | mainRecycler.setItemAnimator(new DefaultItemAnimator()); 89 | 90 | mainAdapter = new MainAdapter(mActivity); 91 | mainRecycler.setAdapter(mainAdapter); 92 | mainRecycler.setLoadMoreListener(this); 93 | } 94 | 95 | @Override 96 | public void onActivityCreated(Bundle savedInstanceState) { 97 | super.onActivityCreated(savedInstanceState); 98 | loadLastestData(); 99 | } 100 | 101 | @Override 102 | public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 103 | inflater.inflate(R.menu.menu_main, menu); 104 | } 105 | 106 | @Override 107 | public boolean onOptionsItemSelected(MenuItem item) { 108 | if (item.getItemId() == R.id.action_refresh) { 109 | loadLastestData(); 110 | return true; 111 | } 112 | return false; 113 | } 114 | 115 | 116 | @Override 117 | public void onDestroyView() { 118 | super.onDestroyView(); 119 | removeAutoScroller(); 120 | ButterKnife.unbind(this); 121 | } 122 | 123 | @Override 124 | public void onRefresh() { 125 | loadLastestData(); 126 | } 127 | 128 | @Override 129 | public void onLoadMore() { 130 | loadBeforeData(curDate); 131 | } 132 | 133 | private void removeAutoScroller() { 134 | if (mainRecycler != null) { 135 | mainRecycler.removeAutoScroller(); 136 | } 137 | } 138 | 139 | /** 140 | * 加载最近数据 141 | */ 142 | private void loadLastestData() { 143 | ViewUtils.setViewVisibility(commonLoading, true); 144 | ZhihuApi service = ZhihuService.createZhihuService(); 145 | service.getLastestNews() 146 | .observeOn(Schedulers.io()) 147 | .subscribeOn(Schedulers.io()) 148 | .map(newsEntity -> changeReadState(newsEntity)) 149 | .observeOn(AndroidSchedulers.mainThread()) 150 | .subscribe(newsEntity1 -> handlerSuccess(newsEntity1, true), throwable -> handlerFailure(true)); 151 | } 152 | 153 | /** 154 | * 改变阅读状态 155 | * 156 | * @param newsEntity 157 | */ 158 | private NewsEntity changeReadState(NewsEntity newsEntity) { 159 | dao = new NewDao(mActivity); 160 | beanList = dao.getAllNewBeans(); 161 | for (StoriesEntity entity : newsEntity.getStories()) { 162 | for (NewBean bean : beanList) { 163 | if (entity.getId() == bean.getId()) { 164 | entity.setRead(true); 165 | } 166 | } 167 | } 168 | return newsEntity; 169 | } 170 | 171 | private void loadBeforeData(String id) { 172 | ZhihuApi service = ZhihuService.createZhihuService(); 173 | service.getBeforeNews(id) 174 | .observeOn(Schedulers.io()) 175 | .subscribeOn(Schedulers.io()) 176 | .map(newsEntity -> changeReadState(newsEntity)) 177 | .observeOn(AndroidSchedulers.mainThread()) 178 | .subscribe(newsEntity1 -> handlerSuccess(newsEntity1, false), throwable -> handlerFailure(false)); 179 | } 180 | 181 | private void handlerSuccess(NewsEntity entity, boolean isRefresh) { 182 | ViewUtils.setViewVisibility(commonLoading, false); 183 | ViewUtils.setViewVisibility(commonError, false); 184 | ViewUtils.setViewVisibility(mainWsrefresh, true); 185 | curDate = entity.getDate(); 186 | stopLoadStatus(isRefresh); 187 | chageListDatas(isRefresh, entity.getStories()); 188 | } 189 | 190 | private void handlerFailure(boolean isRefresh) { 191 | stopLoadStatus(isRefresh); 192 | ViewUtils.setViewVisibility(commonError, true); 193 | ViewUtils.setViewVisibility(commonLoading, false); 194 | ViewUtils.setViewVisibility(mainWsrefresh, false); 195 | } 196 | 197 | 198 | /** 199 | * 改变list数据 200 | * 201 | * @param isRefresh 202 | * @param stories 203 | */ 204 | private void chageListDatas(boolean isRefresh, ArrayList stories) { 205 | if (mainAdapter == null) { 206 | return; 207 | } 208 | if (isRefresh) { 209 | mainAdapter.changeData(stories); 210 | } else { 211 | mainAdapter.addData(stories); 212 | } 213 | } 214 | 215 | /** 216 | * 停止加载状态 217 | * 218 | * @param isRefresh 是否刷新 219 | */ 220 | private void stopLoadStatus(boolean isRefresh) { 221 | if (isRefresh && mainWsrefresh != null) { 222 | mainWsrefresh.setRefreshing(false); 223 | } else if (mainRecycler != null) { 224 | mainRecycler.setLoading(false); 225 | } 226 | } 227 | 228 | } 229 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/ui/fragment/MainMenuFragment.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.ui.fragment; 2 | 3 | import android.app.Fragment; 4 | import android.os.Bundle; 5 | import android.support.annotation.Nullable; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.LinearLayout; 10 | import android.widget.ListView; 11 | 12 | import com.diffey.view.rxzhihu.R; 13 | import com.diffey.view.rxzhihu.adapter.MainMenuAdapter; 14 | import com.diffey.view.rxzhihu.bean.MenuItem; 15 | import com.diffey.view.rxzhihu.util.IntentUtils; 16 | 17 | import java.util.ArrayList; 18 | import java.util.List; 19 | 20 | import butterknife.Bind; 21 | import butterknife.ButterKnife; 22 | 23 | /** 24 | * Created by diff on 2016/2/3. 25 | */ 26 | public class MainMenuFragment extends Fragment { 27 | 28 | @Bind(R.id.main_menu_list) 29 | ListView mainMenuList; 30 | 31 | @Bind(R.id.main_menu_ll_setting) 32 | LinearLayout mainMenuLlSetting; 33 | 34 | @Nullable 35 | @Override 36 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 37 | View view = inflater.inflate(R.layout.fragment_main_menu, container, false); 38 | ButterKnife.bind(this, view); 39 | return view; 40 | } 41 | 42 | @Override 43 | public void onViewCreated(View view, Bundle savedInstanceState) { 44 | super.onViewCreated(view, savedInstanceState); 45 | mainMenuList.setAdapter(new MainMenuAdapter(getActivity(), getMenuList())); 46 | mainMenuList.setOnItemClickListener((parent, view1, position, id) -> { 47 | switch (position) { 48 | case 0: 49 | IntentUtils.toTRClientActivity(getActivity()); 50 | break; 51 | default: 52 | break; 53 | } 54 | }); 55 | mainMenuLlSetting.setOnClickListener(v -> IntentUtils.toSettingActivity(v.getContext())); 56 | } 57 | 58 | private List getMenuList() { 59 | List list = new ArrayList<>(); 60 | list.add(new MenuItem(R.drawable.ic_movie_white_24dp, "聊一会")); 61 | return list; 62 | } 63 | 64 | @Override 65 | public void onDestroyView() { 66 | super.onDestroyView(); 67 | ButterKnife.unbind(this); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/ui/fragment/SettingFragment.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.ui.fragment; 2 | 3 | import android.graphics.Color; 4 | import android.os.Bundle; 5 | import android.preference.Preference; 6 | import android.preference.PreferenceFragment; 7 | import android.support.v4.content.ContextCompat; 8 | 9 | import com.afollestad.materialdialogs.MaterialDialog; 10 | import com.diffey.view.rxzhihu.R; 11 | import com.diffey.view.rxzhihu.contant.UrlContant; 12 | import com.diffey.view.rxzhihu.util.AppInfoUtils; 13 | import com.diffey.view.rxzhihu.util.IntentUtils; 14 | 15 | /** 16 | * Created by diff on 2016/2/5. 17 | */ 18 | public class SettingFragment extends PreferenceFragment implements Preference.OnPreferenceClickListener { 19 | private static final String APP_VERSION = "app_version"; 20 | private static final String ABOUT_DEV = "about_dev"; 21 | 22 | @Override 23 | public void onCreate(Bundle savedInstanceState) { 24 | super.onCreate(savedInstanceState); 25 | addPreferencesFromResource(R.xml.preferences); 26 | 27 | Preference appVersion = findPreference(APP_VERSION); 28 | appVersion.setTitle("版本号:" + AppInfoUtils.getVersionName(getActivity())); 29 | 30 | Preference aboutDev = findPreference(ABOUT_DEV); 31 | aboutDev.setOnPreferenceClickListener(this); 32 | } 33 | 34 | @Override 35 | public boolean onPreferenceClick(Preference preference) { 36 | String key = preference.getKey(); 37 | if (ABOUT_DEV.equals(key)) { 38 | showDialog(); 39 | } 40 | return true; 41 | } 42 | 43 | private void showDialog() { 44 | MaterialDialog dialog = new MaterialDialog.Builder(getActivity()) 45 | .title(getString(R.string.app_name)) 46 | .backgroundColor(ContextCompat.getColor(getActivity(), R.color.colorPrimary)) 47 | .contentColor(Color.WHITE) 48 | .positiveColor(Color.WHITE) 49 | .negativeColor(Color.WHITE) 50 | .neutralColor(Color.WHITE) 51 | .titleColor(Color.WHITE) 52 | .content(R.string.person_info) 53 | .positiveText("GitHub") 54 | .negativeText("简书") 55 | .onPositive((dialog1, which) -> { 56 | IntentUtils.toBrowserView(getActivity(), UrlContant.URL_DEV_GITHUB); 57 | dialog1.dismiss(); 58 | }) 59 | .onNegative((dialog1, which) -> IntentUtils.toBrowserView(getActivity(), UrlContant.URL_DEV_JIANSHU)) 60 | .build(); 61 | dialog.show(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/ui/fragment/StoryFragment.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.ui.fragment; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v4.app.Fragment; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.webkit.WebView; 10 | import android.widget.FrameLayout; 11 | import android.widget.RelativeLayout; 12 | 13 | import com.diffey.view.rxzhihu.R; 14 | import com.diffey.view.rxzhihu.api.ZhihuApi; 15 | import com.diffey.view.rxzhihu.api.ZhihuService; 16 | import com.diffey.view.rxzhihu.util.HtmlUtils; 17 | import com.diffey.view.rxzhihu.util.ViewUtils; 18 | import com.orhanobut.logger.Logger; 19 | 20 | import butterknife.Bind; 21 | import butterknife.ButterKnife; 22 | import rx.android.schedulers.AndroidSchedulers; 23 | import rx.schedulers.Schedulers; 24 | 25 | /** 26 | * Created by diff on 2016/2/5. 27 | */ 28 | public class StoryFragment extends Fragment { 29 | 30 | public static final String PARAM_ID = "param_id"; 31 | 32 | @Bind(R.id.story_web) 33 | WebView storyWeb; 34 | 35 | @Bind(R.id.common_error) 36 | RelativeLayout commonError; 37 | 38 | @Bind(R.id.common_loading) 39 | FrameLayout commonLoading; 40 | 41 | private int curId = -1; 42 | 43 | @Override 44 | public void onCreate(@Nullable Bundle savedInstanceState) { 45 | super.onCreate(savedInstanceState); 46 | curId = getArguments().getInt(PARAM_ID, -1); 47 | Logger.i("curId:" + curId); 48 | } 49 | 50 | @Nullable 51 | @Override 52 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 53 | View view = inflater.inflate(R.layout.fragment_story, container, false); 54 | ButterKnife.bind(this, view); 55 | return view; 56 | } 57 | 58 | @Override 59 | public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { 60 | super.onViewCreated(view, savedInstanceState); 61 | storyWeb.setVerticalScrollBarEnabled(false); 62 | storyWeb.getSettings().setDefaultTextEncodingName("UTF-8"); 63 | 64 | loadData(); 65 | } 66 | 67 | @Override 68 | public void onDestroyView() { 69 | super.onDestroyView(); 70 | ButterKnife.unbind(this); 71 | } 72 | 73 | private void loadData() { 74 | ZhihuApi service = ZhihuService.createZhihuService(); 75 | service.getNewsDetails(curId).observeOn(Schedulers.io()) 76 | .subscribeOn(Schedulers.io()) 77 | .map(storyDetailsEntity -> HtmlUtils.structHtml(storyDetailsEntity.getBody(), storyDetailsEntity.getCss())) 78 | .observeOn(AndroidSchedulers.mainThread()) 79 | .subscribe(s -> webShowData(s), throwable -> handlerFailure()); 80 | 81 | } 82 | 83 | private void handlerFailure() { 84 | ViewUtils.setViewVisibility(commonError, true); 85 | ViewUtils.setViewVisibility(commonLoading, false); 86 | ViewUtils.setViewVisibility(storyWeb, false); 87 | } 88 | 89 | private void webShowData(String htl) { 90 | if (storyWeb != null) { 91 | ViewUtils.setViewVisibility(commonLoading, false); 92 | ViewUtils.setViewVisibility(commonError, false); 93 | storyWeb.loadData(htl, "text/html; charset=UTF-8", null); 94 | } 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/util/AppInfoUtils.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.util; 2 | 3 | import android.app.Activity; 4 | import android.content.pm.PackageInfo; 5 | import android.content.pm.PackageManager; 6 | 7 | /** 8 | * Created by diff on 2016/2/5. 9 | */ 10 | public class AppInfoUtils { 11 | 12 | /** 13 | * 获取版本名 14 | * 15 | * @param activity 16 | * @return 17 | */ 18 | public static String getVersionName(Activity activity) { 19 | PackageManager packageManager = activity.getPackageManager(); 20 | PackageInfo packInfo; 21 | try { 22 | packInfo = packageManager.getPackageInfo(activity.getPackageName(), 0); 23 | return packInfo.versionName; 24 | } catch (PackageManager.NameNotFoundException e) { 25 | e.printStackTrace(); 26 | return "1.0"; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/util/DensityUtils.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.util; 2 | 3 | import android.content.Context; 4 | 5 | public class DensityUtils { 6 | 7 | /** 8 | * 根据手机的分辨率从 dp 的单位 转成为 px(像素) 9 | */ 10 | public static int dip2px(Context context, float dpValue) { 11 | final float scale = context.getResources().getDisplayMetrics().density; 12 | return (int) (dpValue * scale + 0.5f); 13 | } 14 | 15 | /** 16 | * 根据手机的分辨率从 px(像素) 的单位 转成为 dp 17 | */ 18 | public static int px2dip(Context context, float pxValue) { 19 | final float scale = context.getResources().getDisplayMetrics().density; 20 | return (int) (pxValue / scale + 0.5f); 21 | } 22 | } -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/util/GsonUtils.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.util; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.reflect.TypeToken; 5 | 6 | /** 7 | * Gson封装类 8 | * Created by diff on 2016/2/3. 9 | */ 10 | public class GsonUtils { 11 | private static Gson gson; 12 | 13 | static { 14 | if (gson == null) { 15 | gson = new Gson(); 16 | } 17 | } 18 | 19 | /** 20 | * 对象转Json字符串 21 | * 22 | * @param object 23 | * @return 24 | */ 25 | public static String toJson(Object object) { 26 | checkGson(); 27 | return gson.toJson(object); 28 | } 29 | 30 | /** 31 | * 字符串转Json对象 32 | * 33 | * @param json 34 | * @param clazz 35 | * @param 36 | * @return 37 | */ 38 | public static T fromJson(String json, Class clazz) { 39 | checkGson(); 40 | return gson.fromJson(json, clazz); 41 | } 42 | 43 | public static T fromJson(String json, TypeToken token) { 44 | checkGson(); 45 | return gson.fromJson(json, token.getType()); 46 | } 47 | 48 | private static void checkGson() { 49 | if (gson == null) { 50 | gson = new Gson(); 51 | } 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/util/HtmlUtils.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.util; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Created by diff on 2016/2/4. 7 | */ 8 | public class HtmlUtils { 9 | public static String structHtml(String oriStr, List cssList) { 10 | StringBuilder htmlString = new StringBuilder(""); 11 | for (String css : cssList) { 12 | htmlString.append(structCssLink(css)); 13 | } 14 | htmlString.append(""); 15 | htmlString.append(""); 16 | htmlString.append(oriStr); 17 | htmlString.append(""); 18 | return htmlString.toString(); 19 | } 20 | 21 | public static String structCssLink(String css) { 22 | return ""; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/util/IntentUtils.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.util; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.net.Uri; 6 | 7 | import com.diffey.view.rxzhihu.bean.StoriesEntity; 8 | import com.diffey.view.rxzhihu.ui.activity.SettingActivity; 9 | import com.diffey.view.rxzhihu.ui.activity.StoryActivity; 10 | import com.diffey.view.rxzhihu.ui.activity.TRClientActivity; 11 | 12 | import java.util.ArrayList; 13 | 14 | /** 15 | * Created by diff on 2016/2/4. 16 | */ 17 | public class IntentUtils { 18 | 19 | public static void toStoryActivity(Context context, int pos, ArrayList storiesEntityList) { 20 | Intent intent = new Intent(context, StoryActivity.class); 21 | intent.putExtra(StoryActivity.PARAM_POS, pos); 22 | intent.putParcelableArrayListExtra(StoryActivity.PARAM_DATA_LIST, storiesEntityList); 23 | context.startActivity(intent); 24 | } 25 | 26 | public static void toTRClientActivity(Context context) { 27 | context.startActivity(new Intent(context, TRClientActivity.class)); 28 | } 29 | 30 | public static void toSettingActivity(Context context) { 31 | context.startActivity(new Intent(context, SettingActivity.class)); 32 | } 33 | 34 | public static void toBrowserView(Context context, String url) { 35 | context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url))); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/util/NetWorkUtils.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.util; 2 | 3 | import android.content.Context; 4 | import android.net.ConnectivityManager; 5 | import android.net.NetworkInfo; 6 | 7 | /** 8 | * Created by diff on 2016/2/16. 9 | */ 10 | public class NetWorkUtils { 11 | /** 12 | * 判断当前网络是否已连接 13 | * 14 | * @param context 15 | * @return 16 | */ 17 | public static boolean isNetWorkConnected(Context context) { 18 | boolean result; 19 | ConnectivityManager cm = (ConnectivityManager) context 20 | .getSystemService(Context.CONNECTIVITY_SERVICE); 21 | NetworkInfo netInfo = cm.getActiveNetworkInfo(); 22 | result = netInfo != null && netInfo.isConnected(); 23 | return result; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/util/ScreenSizeUtils.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.util; 2 | 3 | import android.app.Activity; 4 | import android.util.DisplayMetrics; 5 | 6 | /** 7 | * Created by diff on 2016/2/4. 8 | */ 9 | public class ScreenSizeUtils { 10 | 11 | public static int getScreenWidth(Activity activity) { 12 | DisplayMetrics dm = new DisplayMetrics(); 13 | activity.getWindowManager().getDefaultDisplay().getMetrics(dm); 14 | return dm.widthPixels; 15 | } 16 | 17 | public static int getScreenHeight(Activity activity) { 18 | DisplayMetrics dm = new DisplayMetrics(); 19 | activity.getWindowManager().getDefaultDisplay().getMetrics(dm); 20 | return dm.heightPixels; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/util/ViewUtils.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.util; 2 | 3 | import android.view.View; 4 | 5 | /** 6 | * Created by diff on 2016/2/5. 7 | */ 8 | public class ViewUtils { 9 | 10 | public static void setViewVisibility(View view, boolean visibility) { 11 | if (view == null) { 12 | return; 13 | } 14 | if (visibility) { 15 | if (view.getVisibility() != View.VISIBLE) { 16 | view.setVisibility(View.VISIBLE); 17 | } 18 | } else { 19 | if (view.getVisibility() == View.VISIBLE) { 20 | view.setVisibility(View.GONE); 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/com/diffey/view/rxzhihu/view/AutoLoadRecylerView.java: -------------------------------------------------------------------------------- 1 | package com.diffey.view.rxzhihu.view; 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 diff on 2016/2/5. 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/res/anim/item_bottom_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/chat_bg_normal.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Diffey/RxZhihuPager/79bf9c5550f09689d3d17850c3250886f2b05acd/app/src/main/res/drawable-hdpi/chat_bg_normal.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/chat_robot_bg_normal.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Diffey/RxZhihuPager/79bf9c5550f09689d3d17850c3250886f2b05acd/app/src/main/res/drawable-hdpi/chat_robot_bg_normal.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_action_refresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Diffey/RxZhihuPager/79bf9c5550f09689d3d17850c3250886f2b05acd/app/src/main/res/drawable-hdpi/ic_action_refresh.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_actionbar_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Diffey/RxZhihuPager/79bf9c5550f09689d3d17850c3250886f2b05acd/app/src/main/res/drawable-hdpi/ic_actionbar_back.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_movie_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Diffey/RxZhihuPager/79bf9c5550f09689d3d17850c3250886f2b05acd/app/src/main/res/drawable-hdpi/ic_movie_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Diffey/RxZhihuPager/79bf9c5550f09689d3d17850c3250886f2b05acd/app/src/main/res/drawable-hdpi/icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/send_btn_normal.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Diffey/RxZhihuPager/79bf9c5550f09689d3d17850c3250886f2b05acd/app/src/main/res/drawable-hdpi/send_btn_normal.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/send_btn_pressed.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Diffey/RxZhihuPager/79bf9c5550f09689d3d17850c3250886f2b05acd/app/src/main/res/drawable-hdpi/send_btn_pressed.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_action_refresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Diffey/RxZhihuPager/79bf9c5550f09689d3d17850c3250886f2b05acd/app/src/main/res/drawable-xhdpi/ic_action_refresh.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_movie_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Diffey/RxZhihuPager/79bf9c5550f09689d3d17850c3250886f2b05acd/app/src/main/res/drawable-xhdpi/ic_movie_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_settings_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Diffey/RxZhihuPager/79bf9c5550f09689d3d17850c3250886f2b05acd/app/src/main/res/drawable-xhdpi/ic_settings_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/common_card_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/common_card_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/common_card_trans.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/item_chat_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/item_list_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/item_main_bg_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/send_btn_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 15 | 16 | 17 | 22 | 23 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_setting.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_story.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_trclient.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 14 | 15 | 23 | 24 | 30 | 31 | 36 | 37 | 44 | 45 | 52 | 53 | 54 | 55 |