├── LICENSE ├── README.md ├── app ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── cn │ │ └── droidlover │ │ └── xdroidmvp │ │ └── demo │ │ ├── App.java │ │ ├── adapter │ │ ├── GanhuoAdapter.java │ │ ├── GirlAdapter.java │ │ └── HomeAdapter.java │ │ ├── kit │ │ └── AppKit.java │ │ ├── model │ │ ├── BaseModel.java │ │ └── GankResults.java │ │ ├── net │ │ ├── Api.java │ │ └── GankService.java │ │ ├── present │ │ └── PBasePager.java │ │ ├── ui │ │ ├── AboutActivity.java │ │ ├── BasePagerFragment.java │ │ ├── GanhuoFragment.java │ │ ├── GirlFragment.java │ │ ├── HomeFragment.java │ │ ├── MainActivity.java │ │ └── WebActivity.java │ │ └── widget │ │ └── StateView.java │ └── res │ ├── drawable-v21 │ └── item_part_touch.xml │ ├── drawable │ ├── ic_arrow_white_24dp.xml │ ├── ic_keyboard_arrow_right_green_24dp.xml │ ├── ic_person_black_24dp.xml │ ├── ic_save_white_24dp.xml │ ├── ic_share_white_24dp.xml │ ├── item_part_touch.xml │ ├── view_border.xml │ └── view_shadow.xml │ ├── layout │ ├── activity_about.xml │ ├── activity_main.xml │ ├── activity_web.xml │ ├── adapter_ganhuo.xml │ ├── adapter_girl.xml │ ├── adapter_home.xml │ ├── fragment_base_pager.xml │ ├── view_loading.xml │ ├── view_state.xml │ └── view_toolbar.xml │ ├── menu │ ├── menu_main.xml │ └── menu_web.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ ├── ic_error.png │ ├── ic_launcher.png │ └── xdroid_logo_128.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ ├── android_icon.png │ ├── ic_launcher.png │ ├── ios_icon.png │ ├── js_icon.png │ ├── other_icon.png │ └── video_icon.jpg │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── art ├── XdroidMvp_total.png ├── snapshot_1.png └── snapshot_2.png ├── build.gradle ├── conf.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── mvp.png ├── mvp ├── build.gradle ├── proguard-pro │ ├── proguard-ARecyclerView.pro │ ├── proguard-avi-loading.pro │ ├── proguard-butterknife.pro │ ├── proguard-canary-debug.pro │ ├── proguard-canary-release.pro │ ├── proguard-constraint-layout.pro │ ├── proguard-design.pro │ ├── proguard-eventbus-3.pro │ ├── proguard-eventbus.pro │ ├── proguard-glide.pro │ ├── proguard-google-gson.pro │ ├── proguard-normal.pro │ ├── proguard-okhttp3-logging-interceptor.pro │ ├── proguard-okhttp3.pro │ ├── proguard-picasso.pro │ ├── proguard-proguard-design.pro │ ├── proguard-recyclerview-v7.pro │ ├── proguard-retrofit-adapter-rxjava.pro │ ├── proguard-retrofit-converter-gson.pro │ ├── proguard-retrofit.pro │ ├── proguard-rxandroid.pro │ ├── proguard-rxjava.pro │ ├── proguard-rxlifecycle-android.pro │ ├── proguard-rxlifecycle-components.pro │ ├── proguard-rxlifecycle.pro │ ├── proguard-rxpermissions.pro │ ├── proguard-self.pro │ ├── proguard-support-v4.pro │ └── proguard-support-v7-appcompat.pro ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── cn │ │ └── droidlover │ │ └── xdroidmvp │ │ ├── XDroidConf.java │ │ ├── base │ │ ├── ListItemCallback.java │ │ ├── SimpleListAdapter.java │ │ ├── SimpleRecAdapter.java │ │ ├── XFragmentAdapter.java │ │ └── XListAdapter.java │ │ ├── cache │ │ ├── DiskCache.java │ │ ├── DiskLruCache.java │ │ ├── ICache.java │ │ ├── MemoryCache.java │ │ └── SharedPref.java │ │ ├── event │ │ ├── BusProvider.java │ │ ├── IBus.java │ │ └── RxBusImpl.java │ │ ├── imageloader │ │ ├── GlideLoader.java │ │ ├── ILFactory.java │ │ ├── ILoader.java │ │ └── LoadCallback.java │ │ ├── kit │ │ ├── Codec.java │ │ ├── Kits.java │ │ ├── KnifeKit.java │ │ └── SimpleCallback.java │ │ ├── log │ │ ├── LogFormat.java │ │ ├── XLog.java │ │ └── XPrinter.java │ │ ├── mvp │ │ ├── IPresent.java │ │ ├── IView.java │ │ ├── LazyFragment.java │ │ ├── VDelegate.java │ │ ├── VDelegateBase.java │ │ ├── XActivity.java │ │ ├── XFragment.java │ │ ├── XLazyFragment.java │ │ └── XPresent.java │ │ ├── net │ │ ├── ApiSubscriber.java │ │ ├── Https.java │ │ ├── IModel.java │ │ ├── LogInterceptor.java │ │ ├── NetError.java │ │ ├── NetProvider.java │ │ ├── RequestHandler.java │ │ ├── XApi.java │ │ ├── XInterceptor.java │ │ ├── cookie │ │ │ ├── CookieJarImpl.java │ │ │ ├── CookieStore.java │ │ │ ├── HasCookieStore.java │ │ │ ├── MemoryCookieStore.java │ │ │ ├── PersistentCookieStore.java │ │ │ └── SerializableHttpCookie.java │ │ └── progress │ │ │ ├── ProRequestBody.java │ │ │ ├── ProResponseBody.java │ │ │ ├── ProgressHelper.java │ │ │ └── ProgressListener.java │ │ └── router │ │ ├── Router.java │ │ ├── RouterCallback.java │ │ └── SimpleRouterCallback.java │ └── res │ └── values │ └── strings.xml ├── settings.gradle ├── test ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── cn │ │ └── droidlover │ │ └── xdroidmvp │ │ └── test │ │ ├── ImageLoaderTest.java │ │ ├── base │ │ ├── AListAdapter.java │ │ ├── BRecAdapter.java │ │ ├── CListAdapter.java │ │ └── DRecAdapter.java │ │ ├── mvp │ │ ├── PermissionActivity.java │ │ ├── UiDelegateActivity.java │ │ ├── multi_p │ │ │ ├── BActivity.java │ │ │ ├── CActivity.java │ │ │ ├── ICommonV.java │ │ │ └── PMulti.java │ │ ├── no_p │ │ │ └── NoPActivity.java │ │ └── single_p │ │ │ ├── PSingle.java │ │ │ └── SinglePActivity.java │ │ ├── router │ │ ├── EndActivity.java │ │ └── StartActivity.java │ │ └── rxbus │ │ ├── LoginEvent.java │ │ └── RxBusActivity.java │ └── res │ ├── layout │ └── item_single.xml │ └── values │ └── strings.xml └── xdroid_logo_128.png /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 WangLei 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #XDroidMvp 轻量级的Android MVP快速开发框架 2 | 3 | ## 概述 4 | 5 |

6 | 7 |

8 | 9 | **XDroidMvp**是[XDroid](https://github.com/limedroid/XDroid)Android快速开发框架的MVP版本,其使用方式类似于`XDroid`,大部分源码也来自`XDroid`。 10 | 11 | **XDroidMvp全新文档**:[https://github.com/limedroid/XDroidMvp/wiki](https://github.com/limedroid/XDroidMvp/wiki) 12 | 13 | [![](https://jitpack.io/v/limedroid/XDroidMvp.svg)](https://jitpack.io/#limedroid/XDroidMvp) 14 | 15 |

16 | 17 |

18 | 19 | `XDroidMvp`主要会有这些特性: 20 | 21 | **无需写`Contract`! 无需写`Present`接口! 无需写`View`接口!** 22 | 23 | 新增: 24 | 25 | * Mvp实现 26 | * `RxJava` & `RxAndroid` 27 | * 权限适配 `RxPermission` 28 | * 事件订阅默认采用 `RxBus` 29 | * 网络交互: 30 | * `Retrofit` + `rx` 31 | * `Https` 32 | * **统一异常处理** 33 | * 缓存 34 | * **支持多个baseUrl** 35 | * 。。。。 36 | * 无需担心rx内存泄漏 37 | * 适配AndroidX,请前往`android-x`分支 38 | 39 | 保留: 40 | 41 | * 提供`XActivity`、`XFragment`、`SimpleRecAdapter`、`SimpleListAdapter`等基类,可快速进行开发 42 | * 完整封装`XRecyclerView`,可实现绝大部分需求 43 | * `XStateController`、`XRecyclerContentLayout`实现loading、error、empty、content四种状态的自由切换 44 | * 实现了`Memory`、`Disk`、`SharedPreferences`三种方式的缓存,可自由扩展 45 | * 内置了`RxBus`,可自由切换到其他事件订阅库 46 | * 内置`Glide`,可自由切换其他图片加载库 47 | * 可输出漂亮的`Log`,支持`Json`、`Xml`、`Throwable`等,蝇量级实现 48 | * 内置链式路由 49 | * 内置常用工具类:`package`、`random`、`file`...,提供的都是非常常用的方法 50 | * 内置加密工具类 `XCodec`,你想要的加密姿势都有 51 | 52 | 53 |

54 | 55 |

56 | 57 | 58 | **先睹为快** 59 | 60 | 你可以这么使用: 61 | 62 | BasePagerFragment 63 | 64 | ```java 65 | public abstract class BasePagerFragment extends XFragment{ 66 | 67 | @Override 68 | public void initData(Bundle savedInstanceState) { 69 | getP().loadData(getType(), 1); //调用P方法 70 | } 71 | 72 | public void showData(int page, GankResults model) { 73 | if (page > 1) { 74 | getAdapter().addData(model.getResults()); 75 | } else { 76 | getAdapter().setData(model.getResults()); 77 | } 78 | 79 | contentLayout.getRecyclerView().setPage(page, MAX_PAGE); 80 | 81 | if (getAdapter().getItemCount() < 1) { 82 | contentLayout.showEmpty(); 83 | return; 84 | } 85 | } 86 | 87 | @Override 88 | public PBasePager newP() { 89 | return new PBasePager(); 90 | }} 91 | 92 | @Override 93 | public int getLayoutId() { 94 | return R.layout.fragment_base_pager; 95 | } 96 | ``` 97 | 98 | PBasePager 99 | 100 | ```java 101 | public class PBasePager extends XPresent { 102 | protected static final int PAGE_SIZE = 10; 103 | 104 | 105 | public void loadData(String type, final int page) { 106 | Api.getGankService().getGankData(type, PAGE_SIZE, page) 107 | .compose(XApi.getApiTransformer()) 108 | .compose(XApi.getScheduler()) 109 | .subscribe(new ApiSubcriber() { 110 | @Override 111 | protected void onFail(NetError error) { 112 | getV().showError(error); //调用V方法 113 | } 114 | 115 | @Override 116 | public void onNext(GankResults gankResults) { 117 | getV().showData(page, gankResults); 118 | } 119 | }); 120 | } 121 | } 122 | ``` 123 | 124 | ## Get Started 125 | 126 | 使用,仅需四步: 127 | 128 | ### step1 129 | 130 | clone 'XDroid'库到本地: 131 | ```groovy 132 | git clone https://github.com/limedroid/XDroidMvp.git 133 | ``` 134 | 135 | ### step2 136 | 137 | 将`mvp`作为依赖库,在您的app module 中 添加如下依赖: 138 | ```groovy 139 | compile project(':mvp') 140 | ``` 141 | 142 | ### step3 143 | 144 | 拷贝`conf.gradle`到您的项目根目录,并修改项目gradle文件下引入: 145 | ```groovy 146 | apply from: "conf.gradle" 147 | ``` 148 | 149 | 并添加: 150 | 151 | ```groovy 152 | allprojects { 153 | repositories { 154 | jcenter() 155 | maven { url "https://jitpack.io" } 156 | } 157 | } 158 | ``` 159 | 160 | ### step4 161 | 162 | 修改`XDroidConf`配置类,主要针对log、cache、router、imageloader。若采用默认配置,此步骤可略过. 163 | 164 | ## 第二种方式,通过JitPack引入 165 | 166 | ### step1 在根目录的gradle文件中配置: 167 | ```groovy 168 | allprojects { 169 | repositories { 170 | jcenter() 171 | maven { url "https://jitpack.io" } 172 | } 173 | } 174 | ``` 175 | 176 | ### step2 添加依赖: 177 | ```groovy 178 | dependencies { 179 | implementation 'com.github.limedroid:XDroidMvp:v2.0.1' 180 | } 181 | ``` 182 | 183 | 184 | ## Demo效果 185 | 186 |

187 | 188 |

189 | 190 |

191 | 192 |

193 | 194 | 195 | ## 重要说明 196 | 197 | * [ButterKnife](https://github.com/JakeWharton/butterknife)使用的是8.4.0版本,重点是 `@BindView`,可以去项目官网查看。 198 | * [Rxlifecycle](https://github.com/trello/RxLifecycle)使用的是1.0版本,具体如何使用可以查看官网。 199 | * [RxPermissions](https://github.com/tbruyelle/RxPermissions)使用的是0.9.1版本,具体如何使用可以查看官网。 200 | * [retrofit](https://github.com/square/retrofit),具体如何使用可以查看官网。 201 | 202 | ## 更新日志 203 | 204 | * 2017-04-23,新增proguard rules,upgrade to rx2 205 | * 2016-12-23,新增mvp、base、cache、event、imageloader、log、router 206 | * 2016-12-25,新增rxJava、rxAndroid、rxlifecycle、rxpermission、rxbus、net(retrofit) 207 | * 2016-12-26,新增网络异常统一处理 208 | * 2016-12-28,重构MVP 209 | * 2016-12-30,重构网络层 210 | * 2016-12-31,新增[Demo](https://github.com/limedroid/XDroidMvp/tree/master/app) 211 | 212 | 213 | ## TODO 214 | 215 | * [x] rx 216 | * [x] retrofit 217 | * [x] rxpermission 218 | * [x] rxbus 219 | * [x] cache 220 | * [x] wiki 221 | * [x] demo 222 | 223 | ## Star History 224 | 225 | [![Star History Chart](https://api.star-history.com/svg?repos=limedroid/XDroidMvp&type=Date)](https://star-history.com/#limedroid/XDroidMvp&Date) 226 | 227 | ## About Me 228 | 229 | **Email** : droidlover@126.com 230 | 231 | **XDroid交流群**:153569290 232 | 233 | **XDroid MVC版本**:[XDroid](https://github.com/limedroid/XDroid) 234 | 235 | 若您在使用过程中遇到任何问题,欢迎加入 **153569290** 群或者是邮件反馈,谢谢您的关注。**XDroidMvp**会持续维护,如果喜欢,记得star fork。 236 | 237 | 238 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion rootProject.ext.android.compileSdkVersion 5 | 6 | defaultConfig { 7 | applicationId 'cn.droidlover.xdroidmvp.demo' 8 | minSdkVersion rootProject.ext.android.minSdkVersion 9 | targetSdkVersion rootProject.ext.android.targetSdkVersion 10 | versionCode rootProject.ext.android.versionCode 11 | versionName rootProject.ext.android.versionName 12 | } 13 | 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | 23 | dependencies { 24 | compile fileTree(dir: 'libs', include: ['*.jar']) 25 | annotationProcessor rootProject.ext.dependencies["butterknife-apt"] 26 | implementation rootProject.ext.dependencies["avi-loading"] 27 | implementation project(":mvp") 28 | } 29 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/wanglei/DevTools/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/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/java/cn/droidlover/xdroidmvp/demo/App.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.demo; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | 6 | import cn.droidlover.xdroidmvp.net.NetError; 7 | import cn.droidlover.xdroidmvp.net.NetProvider; 8 | import cn.droidlover.xdroidmvp.net.RequestHandler; 9 | import cn.droidlover.xdroidmvp.net.XApi; 10 | import okhttp3.CookieJar; 11 | import okhttp3.Interceptor; 12 | import okhttp3.OkHttpClient; 13 | 14 | /** 15 | * Created by wanglei on 2016/12/31. 16 | */ 17 | 18 | public class App extends Application { 19 | 20 | private static Context context; 21 | 22 | @Override 23 | public void onCreate() { 24 | super.onCreate(); 25 | context = this; 26 | 27 | XApi.registerProvider(new NetProvider() { 28 | 29 | @Override 30 | public Interceptor[] configInterceptors() { 31 | return new Interceptor[0]; 32 | } 33 | 34 | @Override 35 | public void configHttps(OkHttpClient.Builder builder) { 36 | 37 | } 38 | 39 | @Override 40 | public CookieJar configCookie() { 41 | return null; 42 | } 43 | 44 | @Override 45 | public RequestHandler configHandler() { 46 | return null; 47 | } 48 | 49 | @Override 50 | public long configConnectTimeoutMills() { 51 | return 0; 52 | } 53 | 54 | @Override 55 | public long configReadTimeoutMills() { 56 | return 0; 57 | } 58 | 59 | @Override 60 | public boolean configLogEnable() { 61 | return true; 62 | } 63 | 64 | @Override 65 | public boolean handleError(NetError error) { 66 | return false; 67 | } 68 | 69 | @Override 70 | public boolean dispatchProgressEnable() { 71 | return false; 72 | } 73 | }); 74 | } 75 | 76 | public static Context getContext() { 77 | return context; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /app/src/main/java/cn/droidlover/xdroidmvp/demo/adapter/GanhuoAdapter.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.demo.adapter; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.view.View; 6 | import android.widget.TextView; 7 | 8 | import butterknife.BindView; 9 | import cn.droidlover.xdroidmvp.base.SimpleRecAdapter; 10 | import cn.droidlover.xdroidmvp.demo.R; 11 | import cn.droidlover.xdroidmvp.demo.model.GankResults; 12 | import cn.droidlover.xdroidmvp.kit.KnifeKit; 13 | 14 | /** 15 | * Created by wanglei on 2016/12/10. 16 | */ 17 | 18 | public class GanhuoAdapter extends SimpleRecAdapter { 19 | 20 | public static final int TAG_VIEW = 0; 21 | 22 | public GanhuoAdapter(Context context) { 23 | super(context); 24 | } 25 | 26 | @Override 27 | public ViewHolder newViewHolder(View itemView) { 28 | return new ViewHolder(itemView); 29 | } 30 | 31 | @Override 32 | public int getLayoutId() { 33 | return R.layout.adapter_ganhuo; 34 | } 35 | 36 | @Override 37 | public void onBindViewHolder(final ViewHolder holder, final int position) { 38 | final GankResults.Item item = data.get(position); 39 | holder.tvItem.setText(item.getDesc()); 40 | 41 | holder.itemView.setOnClickListener(new View.OnClickListener() { 42 | @Override 43 | public void onClick(View v) { 44 | if (getRecItemClick() != null) { 45 | getRecItemClick().onItemClick(position, item, TAG_VIEW, holder); 46 | } 47 | } 48 | }); 49 | } 50 | 51 | public static class ViewHolder extends RecyclerView.ViewHolder { 52 | 53 | 54 | @BindView(R.id.tv_item) 55 | TextView tvItem; 56 | 57 | public ViewHolder(View itemView) { 58 | super(itemView); 59 | KnifeKit.bind(this, itemView); 60 | } 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /app/src/main/java/cn/droidlover/xdroidmvp/demo/adapter/GirlAdapter.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.demo.adapter; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.view.View; 6 | import android.widget.ImageView; 7 | 8 | import butterknife.BindView; 9 | import cn.droidlover.xdroidmvp.base.SimpleRecAdapter; 10 | import cn.droidlover.xdroidmvp.demo.R; 11 | import cn.droidlover.xdroidmvp.demo.model.GankResults; 12 | import cn.droidlover.xdroidmvp.imageloader.ILFactory; 13 | import cn.droidlover.xdroidmvp.imageloader.ILoader; 14 | import cn.droidlover.xdroidmvp.kit.KnifeKit; 15 | 16 | /** 17 | * Created by wanglei on 2016/12/10. 18 | */ 19 | 20 | public class GirlAdapter extends SimpleRecAdapter { 21 | 22 | 23 | public GirlAdapter(Context context) { 24 | super(context); 25 | } 26 | 27 | @Override 28 | public ViewHolder newViewHolder(View itemView) { 29 | return new ViewHolder(itemView); 30 | } 31 | 32 | @Override 33 | public int getLayoutId() { 34 | return R.layout.adapter_girl; 35 | } 36 | 37 | @Override 38 | public void onBindViewHolder(ViewHolder holder, int position) { 39 | GankResults.Item item = data.get(position); 40 | 41 | //圆形 42 | // ILFactory.getLoader().loadCircle(item.getUrl(),holder.ivGirl, new ILoader.Options(R.mipmap.xdroid_logo_128, R.mipmap.xdroid_logo_128)); 43 | //圆角 44 | // ILFactory.getLoader().loadCorner(item.getUrl(),holder.ivGirl, 50,new ILoader.Options(R.mipmap.xdroid_logo_128, R.mipmap.xdroid_logo_128)); 45 | //正常 46 | ILFactory.getLoader().loadNet(holder.ivGirl, item.getUrl(), new ILoader.Options(R.mipmap.xdroid_logo_128, R.mipmap.xdroid_logo_128)); 47 | 48 | holder.itemView.setOnClickListener(new View.OnClickListener() { 49 | @Override 50 | public void onClick(View v) { 51 | if (getRecItemClick() != null) { 52 | 53 | } 54 | } 55 | }); 56 | } 57 | 58 | public static class ViewHolder extends RecyclerView.ViewHolder { 59 | 60 | @BindView(R.id.iv_girl) 61 | ImageView ivGirl; 62 | 63 | public ViewHolder(View itemView) { 64 | super(itemView); 65 | KnifeKit.bind(this, itemView); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /app/src/main/java/cn/droidlover/xdroidmvp/demo/adapter/HomeAdapter.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.demo.adapter; 2 | 3 | import android.content.Context; 4 | import android.graphics.Color; 5 | import android.net.Uri; 6 | import android.support.v7.widget.RecyclerView; 7 | import android.view.View; 8 | import android.widget.ImageView; 9 | import android.widget.RelativeLayout; 10 | import android.widget.TextView; 11 | 12 | import butterknife.BindView; 13 | import cn.droidlover.xdroidmvp.base.SimpleRecAdapter; 14 | import cn.droidlover.xdroidmvp.demo.R; 15 | import cn.droidlover.xdroidmvp.demo.model.GankResults; 16 | import cn.droidlover.xdroidmvp.imageloader.ILFactory; 17 | import cn.droidlover.xdroidmvp.kit.KnifeKit; 18 | 19 | /** 20 | * Created by wanglei on 2016/12/10. 21 | */ 22 | 23 | public class HomeAdapter extends SimpleRecAdapter { 24 | 25 | public static final int TAG_VIEW = 0; 26 | 27 | public HomeAdapter(Context context) { 28 | super(context); 29 | } 30 | 31 | @Override 32 | public ViewHolder newViewHolder(View itemView) { 33 | return new ViewHolder(itemView); 34 | } 35 | 36 | @Override 37 | public int getLayoutId() { 38 | return R.layout.adapter_home; 39 | } 40 | 41 | @Override 42 | public void onBindViewHolder(final ViewHolder holder, final int position) { 43 | final GankResults.Item item = data.get(position); 44 | 45 | String type = item.getType(); 46 | switch (type) { 47 | case "休息视频": 48 | holder.rlMessage.setVisibility(View.VISIBLE); 49 | holder.ivPart.setVisibility(View.GONE); 50 | holder.ivVedio.setVisibility(View.VISIBLE); 51 | holder.tvItem.setText(item.getDesc()); 52 | holder.itemView.setOnClickListener(new View.OnClickListener() { 53 | @Override 54 | public void onClick(View v) { 55 | if (getRecItemClick() != null) { 56 | 57 | } 58 | } 59 | }); 60 | break; 61 | case "福利": 62 | holder.rlMessage.setVisibility(View.GONE); 63 | holder.ivPart.setVisibility(View.VISIBLE); 64 | holder.ivVedio.setVisibility(View.GONE); 65 | 66 | ILFactory.getLoader().loadNet(holder.ivPart, item.getUrl(), null); 67 | holder.tvItem.setText("瞧瞧妹纸,扩展扩展视野......"); 68 | holder.itemView.setOnClickListener(new View.OnClickListener() { 69 | @Override 70 | public void onClick(View v) { 71 | if (getRecItemClick() != null) { 72 | 73 | } 74 | } 75 | }); 76 | break; 77 | default: 78 | holder.rlMessage.setVisibility(View.VISIBLE); 79 | holder.ivPart.setVisibility(View.GONE); 80 | holder.ivVedio.setVisibility(View.GONE); 81 | holder.tvItem.setText(item.getDesc()); 82 | holder.itemView.setOnClickListener(new View.OnClickListener() { 83 | @Override 84 | public void onClick(View v) { 85 | if (getRecItemClick() != null) { 86 | 87 | } 88 | } 89 | }); 90 | break; 91 | } 92 | Uri uri = null; 93 | switch (item.getType()) { 94 | case "Android": 95 | holder.ivType.setImageResource(R.mipmap.android_icon); 96 | break; 97 | case "iOS": 98 | holder.ivType.setImageResource(R.mipmap.ios_icon); 99 | break; 100 | case "前端": 101 | holder.ivType.setImageResource(R.mipmap.js_icon); 102 | break; 103 | case "拓展资源": 104 | holder.ivType.setImageResource(R.mipmap.other_icon); 105 | break; 106 | } 107 | 108 | String author = item.getWho(); 109 | if (author != null) { 110 | holder.tvAuthor.setText(author); 111 | holder.tvAuthor.setTextColor(Color.parseColor("#87000000")); 112 | } else { 113 | holder.tvAuthor.setText(""); 114 | } 115 | 116 | holder.tvTime.setText(item.getCreatedAt()); 117 | 118 | holder.tvType.setText(type); 119 | 120 | holder.itemView.setOnClickListener(new View.OnClickListener() { 121 | @Override 122 | public void onClick(View v) { 123 | if (getRecItemClick() != null) { 124 | getRecItemClick().onItemClick(position, item, TAG_VIEW, holder); 125 | } 126 | } 127 | }); 128 | 129 | } 130 | 131 | public static class ViewHolder extends RecyclerView.ViewHolder { 132 | 133 | @BindView(R.id.iv_type) 134 | ImageView ivType; 135 | @BindView(R.id.tv_type) 136 | TextView tvType; 137 | @BindView(R.id.iv_author) 138 | ImageView ivAuthor; 139 | @BindView(R.id.tv_author) 140 | TextView tvAuthor; 141 | @BindView(R.id.tv_time) 142 | TextView tvTime; 143 | @BindView(R.id.rl_message) 144 | RelativeLayout rlMessage; 145 | @BindView(R.id.iv_part) 146 | ImageView ivPart; 147 | @BindView(R.id.iv_vedio) 148 | ImageView ivVedio; 149 | @BindView(R.id.tv_item) 150 | TextView tvItem; 151 | 152 | public ViewHolder(View itemView) { 153 | super(itemView); 154 | KnifeKit.bind(this, itemView); 155 | } 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /app/src/main/java/cn/droidlover/xdroidmvp/demo/kit/AppKit.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.demo.kit; 2 | 3 | import android.content.ClipData; 4 | import android.content.ClipboardManager; 5 | import android.content.Context; 6 | import android.content.Intent; 7 | import android.net.Uri; 8 | import android.widget.Toast; 9 | 10 | import java.io.IOException; 11 | 12 | import okhttp3.MediaType; 13 | import okhttp3.Request; 14 | import okio.Buffer; 15 | 16 | /** 17 | * Created by wanglei on 2016/12/11. 18 | */ 19 | 20 | public class AppKit { 21 | 22 | public static void copyToClipBoard(Context context, String text) { 23 | ClipboardManager cm = (ClipboardManager) context.getSystemService( 24 | Context.CLIPBOARD_SERVICE); 25 | cm.setPrimaryClip(ClipData.newPlainText("xdroid_copy", text)); 26 | Toast.makeText(context, "复制成功", Toast.LENGTH_SHORT).show(); 27 | } 28 | 29 | public static void openInBrowser(Context context, String url) { 30 | Intent intent = new Intent(); 31 | intent.setAction(Intent.ACTION_VIEW); 32 | Uri uri = Uri.parse(url); 33 | intent.setData(uri); 34 | if (intent.resolveActivity(context.getPackageManager()) != null) { 35 | context.startActivity(intent); 36 | } else { 37 | Toast.makeText(context, "打开失败了,没有可打开的应用", Toast.LENGTH_SHORT).show(); 38 | } 39 | } 40 | 41 | public static void shareText(Context context, String shareText) { 42 | Intent intent = new Intent(Intent.ACTION_SEND); 43 | intent.setType("text/plain"); 44 | intent.putExtra(Intent.EXTRA_SUBJECT, "分享"); 45 | intent.putExtra(Intent.EXTRA_TEXT, shareText); 46 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 47 | context.startActivity(Intent.createChooser(intent, "分享")); 48 | } 49 | 50 | public static void shareImage(Context context, Uri uri) { 51 | Intent shareIntent = new Intent(); 52 | shareIntent.setAction(Intent.ACTION_SEND); 53 | shareIntent.putExtra(Intent.EXTRA_STREAM, uri); 54 | shareIntent.setType("image/jpeg"); 55 | context.startActivity(Intent.createChooser(shareIntent, "分享图片")); 56 | } 57 | 58 | public static boolean isText(MediaType mediaType) { 59 | if (mediaType.type() != null && mediaType.type().equals("text")) { 60 | return true; 61 | } 62 | if (mediaType.subtype() != null) { 63 | if (mediaType.subtype().equals("json") || 64 | mediaType.subtype().equals("xml") || 65 | mediaType.subtype().equals("html") || 66 | mediaType.subtype().equals("webviewhtml") 67 | ) 68 | return true; 69 | } 70 | return false; 71 | } 72 | 73 | public static String bodyToString(final Request request) { 74 | try { 75 | final Request copy = request.newBuilder().build(); 76 | final Buffer buffer = new Buffer(); 77 | copy.body().writeTo(buffer); 78 | return buffer.readUtf8(); 79 | } catch (final IOException e) { 80 | return "something error when show requestBody."; 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /app/src/main/java/cn/droidlover/xdroidmvp/demo/model/BaseModel.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.demo.model; 2 | 3 | import cn.droidlover.xdroidmvp.net.IModel; 4 | 5 | /** 6 | * Created by wanglei on 2016/12/11. 7 | */ 8 | 9 | public class BaseModel implements IModel { 10 | protected boolean error; 11 | 12 | 13 | public boolean isError() { 14 | return error; 15 | } 16 | 17 | public void setError(boolean error) { 18 | this.error = error; 19 | } 20 | 21 | @Override 22 | public boolean isNull() { 23 | return false; 24 | } 25 | 26 | @Override 27 | public boolean isAuthError() { 28 | return false; 29 | } 30 | 31 | @Override 32 | public boolean isBizError() { 33 | return error; 34 | } 35 | 36 | @Override 37 | public String getErrorMsg() { 38 | return null; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/cn/droidlover/xdroidmvp/demo/model/GankResults.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.demo.model; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Created by wanglei on 2016/12/10. 7 | */ 8 | 9 | public class GankResults extends BaseModel { 10 | 11 | private List results; 12 | 13 | public List getResults() { 14 | return results; 15 | } 16 | 17 | public void setResults(List results) { 18 | this.results = results; 19 | } 20 | 21 | @Override 22 | public boolean isNull() { 23 | return results == null || results.isEmpty(); 24 | } 25 | 26 | 27 | public static class Item { 28 | private String _id; 29 | private String _ns; 30 | private String createdAt; 31 | private String desc; 32 | private String publishedAt; 33 | private String source; 34 | private String type; 35 | private String url; 36 | private String used; 37 | private String who; 38 | 39 | public String get_id() { 40 | return _id; 41 | } 42 | 43 | public void set_id(String _id) { 44 | this._id = _id; 45 | } 46 | 47 | public String get_ns() { 48 | return _ns; 49 | } 50 | 51 | public void set_ns(String _ns) { 52 | this._ns = _ns; 53 | } 54 | 55 | public String getCreatedAt() { 56 | return createdAt; 57 | } 58 | 59 | public void setCreatedAt(String createdAt) { 60 | this.createdAt = createdAt; 61 | } 62 | 63 | public String getDesc() { 64 | return desc; 65 | } 66 | 67 | public void setDesc(String desc) { 68 | this.desc = desc; 69 | } 70 | 71 | public String getPublishedAt() { 72 | return publishedAt; 73 | } 74 | 75 | public void setPublishedAt(String publishedAt) { 76 | this.publishedAt = publishedAt; 77 | } 78 | 79 | public String getSource() { 80 | return source; 81 | } 82 | 83 | public void setSource(String source) { 84 | this.source = source; 85 | } 86 | 87 | public String getType() { 88 | return type; 89 | } 90 | 91 | public void setType(String type) { 92 | this.type = type; 93 | } 94 | 95 | public String getUrl() { 96 | return url; 97 | } 98 | 99 | public void setUrl(String url) { 100 | this.url = url; 101 | } 102 | 103 | public String getUsed() { 104 | return used; 105 | } 106 | 107 | public void setUsed(String used) { 108 | this.used = used; 109 | } 110 | 111 | public String getWho() { 112 | return who; 113 | } 114 | 115 | public void setWho(String who) { 116 | this.who = who; 117 | } 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /app/src/main/java/cn/droidlover/xdroidmvp/demo/net/Api.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.demo.net; 2 | 3 | import cn.droidlover.xdroidmvp.net.XApi; 4 | 5 | /** 6 | * Created by wanglei on 2016/12/31. 7 | */ 8 | 9 | public class Api { 10 | public static final String API_BASE_URL = "http://gank.io/api/"; 11 | 12 | private static GankService gankService; 13 | 14 | public static GankService getGankService() { 15 | if (gankService == null) { 16 | synchronized (Api.class) { 17 | if (gankService == null) { 18 | gankService = XApi.getInstance().getRetrofit(API_BASE_URL, true).create(GankService.class); 19 | } 20 | } 21 | } 22 | return gankService; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/cn/droidlover/xdroidmvp/demo/net/GankService.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.demo.net; 2 | 3 | import cn.droidlover.xdroidmvp.demo.model.GankResults; 4 | import io.reactivex.Flowable; 5 | import retrofit2.http.GET; 6 | import retrofit2.http.Path; 7 | 8 | /** 9 | * Created by wanglei on 2016/12/31. 10 | */ 11 | 12 | public interface GankService { 13 | 14 | @GET("data/{type}/{number}/{page}") 15 | Flowable getGankData(@Path("type") String type, 16 | @Path("number") int pageSize, 17 | @Path("page") int pageNum); 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/cn/droidlover/xdroidmvp/demo/present/PBasePager.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.demo.present; 2 | 3 | import cn.droidlover.xdroidmvp.demo.model.GankResults; 4 | import cn.droidlover.xdroidmvp.demo.net.Api; 5 | import cn.droidlover.xdroidmvp.demo.ui.BasePagerFragment; 6 | import cn.droidlover.xdroidmvp.mvp.XPresent; 7 | import cn.droidlover.xdroidmvp.net.ApiSubscriber; 8 | import cn.droidlover.xdroidmvp.net.NetError; 9 | import cn.droidlover.xdroidmvp.net.XApi; 10 | 11 | /** 12 | * Created by wanglei on 2016/12/31. 13 | */ 14 | 15 | public class PBasePager extends XPresent { 16 | protected static final int PAGE_SIZE = 10; 17 | 18 | 19 | public void loadData(String type, final int page) { 20 | Api.getGankService().getGankData(type, PAGE_SIZE, page) 21 | .compose(XApi.getApiTransformer()) 22 | .compose(XApi.getScheduler()) 23 | .compose(getV().bindToLifecycle()) 24 | .subscribe(new ApiSubscriber() { 25 | @Override 26 | protected void onFail(NetError error) { 27 | getV().showError(error); 28 | } 29 | 30 | @Override 31 | public void onNext(GankResults gankResults) { 32 | getV().showData(page, gankResults); 33 | } 34 | }); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/cn/droidlover/xdroidmvp/demo/ui/AboutActivity.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.demo.ui; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | import android.support.v7.widget.Toolbar; 6 | import android.view.MenuItem; 7 | import android.view.View; 8 | 9 | import butterknife.BindView; 10 | import butterknife.OnClick; 11 | import cn.droidlover.xdroidmvp.demo.R; 12 | import cn.droidlover.xdroidmvp.mvp.XActivity; 13 | import cn.droidlover.xdroidmvp.router.Router; 14 | 15 | /** 16 | * Created by wanglei on 2016/12/31. 17 | */ 18 | 19 | public class AboutActivity extends XActivity { 20 | @BindView(R.id.toolbar) 21 | Toolbar toolbar; 22 | 23 | 24 | @Override 25 | public void initData(Bundle savedInstanceState) { 26 | initToolbar(); 27 | } 28 | 29 | private void initToolbar() { 30 | setSupportActionBar(toolbar); 31 | getSupportActionBar().setDisplayHomeAsUpEnabled(true); 32 | getSupportActionBar().setHomeButtonEnabled(true); 33 | getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_arrow_white_24dp); 34 | getSupportActionBar().setTitle("关于XDroidMvp"); 35 | } 36 | 37 | @OnClick({ 38 | R.id.tv_githubMvc, 39 | R.id.tv_githubMvp 40 | }) 41 | public void clickEvent(View view) { 42 | switch (view.getId()) { 43 | 44 | case R.id.tv_githubMvc: 45 | WebActivity.launch(context, "https://github.com/limedroid/XDroid", "XDroid"); 46 | break; 47 | 48 | case R.id.tv_githubMvp: 49 | WebActivity.launch(context, "https://github.com/limedroid/XDroidMvp", "XDroid"); 50 | break; 51 | } 52 | } 53 | 54 | public static void launch(Activity activity) { 55 | Router.newIntent(activity) 56 | .to(AboutActivity.class) 57 | .data(new Bundle()) 58 | .launch(); 59 | } 60 | 61 | @Override 62 | public int getLayoutId() { 63 | return R.layout.activity_about; 64 | } 65 | 66 | @Override 67 | public Object newP() { 68 | return null; 69 | } 70 | 71 | @Override 72 | public boolean onOptionsItemSelected(MenuItem item) { 73 | if (item.getItemId() == android.R.id.home) { 74 | finish(); 75 | return true; 76 | } 77 | return super.onOptionsItemSelected(item); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /app/src/main/java/cn/droidlover/xdroidmvp/demo/ui/BasePagerFragment.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.demo.ui; 2 | 3 | import android.os.Bundle; 4 | import android.view.View; 5 | 6 | import butterknife.BindView; 7 | import cn.droidlover.xdroidmvp.base.SimpleRecAdapter; 8 | import cn.droidlover.xdroidmvp.demo.R; 9 | import cn.droidlover.xdroidmvp.demo.model.GankResults; 10 | import cn.droidlover.xdroidmvp.demo.present.PBasePager; 11 | import cn.droidlover.xdroidmvp.demo.widget.StateView; 12 | import cn.droidlover.xdroidmvp.mvp.XLazyFragment; 13 | import cn.droidlover.xdroidmvp.net.NetError; 14 | import cn.droidlover.xrecyclerview.XRecyclerContentLayout; 15 | import cn.droidlover.xrecyclerview.XRecyclerView; 16 | 17 | /** 18 | * Created by wanglei on 2016/12/31. 19 | */ 20 | 21 | public abstract class BasePagerFragment extends XLazyFragment { 22 | 23 | @BindView(R.id.contentLayout) 24 | XRecyclerContentLayout contentLayout; 25 | 26 | StateView errorView; 27 | 28 | protected static final int MAX_PAGE = 10; 29 | 30 | 31 | @Override 32 | public void initData(Bundle savedInstanceState) { 33 | initAdapter(); 34 | getP().loadData(getType(), 1); 35 | } 36 | 37 | private void initAdapter() { 38 | setLayoutManager(contentLayout.getRecyclerView()); 39 | contentLayout.getRecyclerView() 40 | .setAdapter(getAdapter()); 41 | contentLayout.getRecyclerView() 42 | .setOnRefreshAndLoadMoreListener(new XRecyclerView.OnRefreshAndLoadMoreListener() { 43 | @Override 44 | public void onRefresh() { 45 | getP().loadData(getType(), 1); 46 | } 47 | 48 | @Override 49 | public void onLoadMore(int page) { 50 | getP().loadData(getType(), page); 51 | } 52 | }); 53 | 54 | 55 | if (errorView == null) { 56 | errorView = new StateView(context); 57 | } 58 | contentLayout.errorView(errorView); 59 | contentLayout.loadingView(View.inflate(getContext(), R.layout.view_loading, null)); 60 | 61 | contentLayout.getRecyclerView().useDefLoadMoreView(); 62 | } 63 | 64 | public abstract SimpleRecAdapter getAdapter(); 65 | 66 | public abstract void setLayoutManager(XRecyclerView recyclerView); 67 | 68 | public abstract String getType(); 69 | 70 | 71 | public void showError(NetError error) { 72 | if (error != null) { 73 | switch (error.getType()) { 74 | case NetError.ParseError: 75 | errorView.setMsg("数据解析异常"); 76 | break; 77 | 78 | case NetError.AuthError: 79 | errorView.setMsg("身份验证异常"); 80 | break; 81 | 82 | case NetError.BusinessError: 83 | errorView.setMsg("业务异常"); 84 | break; 85 | 86 | case NetError.NoConnectError: 87 | errorView.setMsg("网络无连接"); 88 | break; 89 | 90 | case NetError.NoDataError: 91 | errorView.setMsg("数据为空"); 92 | break; 93 | 94 | case NetError.OtherError: 95 | errorView.setMsg("其他异常"); 96 | break; 97 | } 98 | contentLayout.showError(); 99 | } 100 | } 101 | 102 | public void showData(int page, GankResults model) { 103 | if (page > 1) { 104 | getAdapter().addData(model.getResults()); 105 | } else { 106 | getAdapter().setData(model.getResults()); 107 | } 108 | 109 | contentLayout.getRecyclerView().setPage(page, MAX_PAGE); 110 | 111 | if (getAdapter().getItemCount() < 1) { 112 | contentLayout.showEmpty(); 113 | return; 114 | } 115 | } 116 | 117 | 118 | @Override 119 | public int getLayoutId() { 120 | return R.layout.fragment_base_pager; 121 | } 122 | 123 | @Override 124 | public PBasePager newP() { 125 | return new PBasePager(); 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /app/src/main/java/cn/droidlover/xdroidmvp/demo/ui/GanhuoFragment.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.demo.ui; 2 | 3 | import cn.droidlover.xdroidmvp.base.SimpleRecAdapter; 4 | import cn.droidlover.xdroidmvp.demo.adapter.GanhuoAdapter; 5 | import cn.droidlover.xdroidmvp.demo.model.GankResults; 6 | import cn.droidlover.xrecyclerview.RecyclerItemCallback; 7 | import cn.droidlover.xrecyclerview.XRecyclerView; 8 | 9 | /** 10 | * Created by wanglei on 2016/12/31. 11 | */ 12 | 13 | public class GanhuoFragment extends BasePagerFragment { 14 | 15 | GanhuoAdapter adapter; 16 | 17 | @Override 18 | public SimpleRecAdapter getAdapter() { 19 | if (adapter == null) { 20 | adapter = new GanhuoAdapter(context); 21 | adapter.setRecItemClick(new RecyclerItemCallback() { 22 | @Override 23 | public void onItemClick(int position, GankResults.Item model, int tag, GanhuoAdapter.ViewHolder holder) { 24 | super.onItemClick(position, model, tag, holder); 25 | switch (tag) { 26 | case GanhuoAdapter.TAG_VIEW: 27 | WebActivity.launch(context, model.getUrl(), model.getDesc()); 28 | break; 29 | } 30 | } 31 | }); 32 | } 33 | return adapter; 34 | } 35 | 36 | @Override 37 | public void setLayoutManager(XRecyclerView recyclerView) { 38 | recyclerView.verticalLayoutManager(context); 39 | } 40 | 41 | @Override 42 | public String getType() { 43 | return "Android"; 44 | } 45 | 46 | public static GanhuoFragment newInstance() { 47 | return new GanhuoFragment(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/cn/droidlover/xdroidmvp/demo/ui/GirlFragment.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.demo.ui; 2 | 3 | import cn.droidlover.xdroidmvp.base.SimpleRecAdapter; 4 | import cn.droidlover.xdroidmvp.demo.adapter.GirlAdapter; 5 | import cn.droidlover.xdroidmvp.demo.model.GankResults; 6 | import cn.droidlover.xrecyclerview.RecyclerItemCallback; 7 | import cn.droidlover.xrecyclerview.XRecyclerView; 8 | 9 | /** 10 | * Created by wanglei on 2016/12/31. 11 | */ 12 | 13 | public class GirlFragment extends BasePagerFragment { 14 | 15 | GirlAdapter adapter; 16 | 17 | @Override 18 | public SimpleRecAdapter getAdapter() { 19 | if (adapter == null) { 20 | adapter = new GirlAdapter(context); 21 | adapter.setRecItemClick(new RecyclerItemCallback() { 22 | @Override 23 | public void onItemClick(int position, GankResults.Item model, int tag, GirlAdapter.ViewHolder holder) { 24 | super.onItemClick(position, model, tag, holder); 25 | } 26 | }); 27 | } 28 | return adapter; 29 | } 30 | 31 | @Override 32 | public void setLayoutManager(XRecyclerView recyclerView) { 33 | recyclerView.gridLayoutManager(context, 2); 34 | } 35 | 36 | @Override 37 | public String getType() { 38 | return "福利"; 39 | } 40 | 41 | public static GirlFragment newInstance() { 42 | return new GirlFragment(); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/cn/droidlover/xdroidmvp/demo/ui/HomeFragment.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.demo.ui; 2 | 3 | import cn.droidlover.xdroidmvp.base.SimpleRecAdapter; 4 | import cn.droidlover.xdroidmvp.demo.adapter.HomeAdapter; 5 | import cn.droidlover.xdroidmvp.demo.model.GankResults; 6 | import cn.droidlover.xrecyclerview.RecyclerItemCallback; 7 | import cn.droidlover.xrecyclerview.XRecyclerView; 8 | 9 | /** 10 | * Created by wanglei on 2016/12/31. 11 | */ 12 | 13 | public class HomeFragment extends BasePagerFragment { 14 | 15 | HomeAdapter adapter; 16 | 17 | @Override 18 | public SimpleRecAdapter getAdapter() { 19 | if (adapter == null) { 20 | adapter = new HomeAdapter(context); 21 | adapter.setRecItemClick(new RecyclerItemCallback() { 22 | @Override 23 | public void onItemClick(int position, GankResults.Item model, int tag, HomeAdapter.ViewHolder holder) { 24 | super.onItemClick(position, model, tag, holder); 25 | switch (tag) { 26 | case HomeAdapter.TAG_VIEW: 27 | WebActivity.launch(context, model.getUrl(), model.getDesc()); 28 | break; 29 | } 30 | } 31 | }); 32 | } 33 | return adapter; 34 | } 35 | 36 | @Override 37 | public void setLayoutManager(XRecyclerView recyclerView) { 38 | recyclerView.verticalLayoutManager(context); 39 | } 40 | 41 | @Override 42 | public String getType() { 43 | return "all"; 44 | } 45 | 46 | public static HomeFragment newInstance() { 47 | return new HomeFragment(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/cn/droidlover/xdroidmvp/demo/ui/MainActivity.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.demo.ui; 2 | 3 | import android.os.Bundle; 4 | import android.support.design.widget.TabLayout; 5 | import android.support.v4.app.Fragment; 6 | import android.support.v4.view.ViewPager; 7 | import android.support.v7.widget.Toolbar; 8 | import android.view.MenuItem; 9 | 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | import butterknife.BindView; 14 | import cn.droidlover.xdroidmvp.base.XFragmentAdapter; 15 | import cn.droidlover.xdroidmvp.demo.R; 16 | import cn.droidlover.xdroidmvp.mvp.XActivity; 17 | 18 | /** 19 | * Created by wanglei on 2016/12/22. 20 | */ 21 | 22 | public class MainActivity extends XActivity { 23 | @BindView(R.id.toolbar) 24 | Toolbar toolbar; 25 | @BindView(R.id.tabLayout) 26 | TabLayout tabLayout; 27 | @BindView(R.id.viewPager) 28 | ViewPager viewPager; 29 | 30 | List fragmentList = new ArrayList<>(); 31 | String[] titles = {"首页", "干货", "妹子"}; 32 | 33 | XFragmentAdapter adapter; 34 | 35 | 36 | @Override 37 | public void initData(Bundle savedInstanceState) { 38 | setSupportActionBar(toolbar); 39 | 40 | fragmentList.clear(); 41 | fragmentList.add(HomeFragment.newInstance()); 42 | fragmentList.add(GanhuoFragment.newInstance()); 43 | fragmentList.add(GirlFragment.newInstance()); 44 | 45 | if (adapter == null) { 46 | adapter = new XFragmentAdapter(getSupportFragmentManager(), fragmentList, titles); 47 | } 48 | viewPager.setAdapter(adapter); 49 | viewPager.setOffscreenPageLimit(3); 50 | 51 | tabLayout.setupWithViewPager(viewPager); 52 | } 53 | 54 | @Override 55 | public int getLayoutId() { 56 | return R.layout.activity_main; 57 | } 58 | 59 | @Override 60 | public int getOptionsMenuId() { 61 | return R.menu.menu_main; 62 | } 63 | 64 | @Override 65 | public boolean onOptionsItemSelected(MenuItem item) { 66 | switch (item.getItemId()) { 67 | case R.id.action_droid: 68 | AboutActivity.launch(context); 69 | break; 70 | } 71 | return super.onOptionsItemSelected(item); 72 | } 73 | 74 | @Override 75 | public Object newP() { 76 | return null; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /app/src/main/java/cn/droidlover/xdroidmvp/demo/widget/StateView.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.demo.widget; 2 | 3 | import android.content.Context; 4 | import android.text.TextUtils; 5 | import android.util.AttributeSet; 6 | import android.widget.LinearLayout; 7 | import android.widget.TextView; 8 | 9 | import butterknife.BindView; 10 | import cn.droidlover.xdroidmvp.demo.R; 11 | import cn.droidlover.xdroidmvp.kit.KnifeKit; 12 | 13 | /** 14 | * Created by wanglei on 2016/12/31. 15 | */ 16 | 17 | public class StateView extends LinearLayout { 18 | 19 | @BindView(R.id.tv_msg) 20 | TextView tvMsg; 21 | 22 | public StateView(Context context) { 23 | super(context); 24 | setupView(context); 25 | } 26 | 27 | public StateView(Context context, AttributeSet attrs) { 28 | super(context, attrs); 29 | setupView(context); 30 | } 31 | 32 | public StateView(Context context, AttributeSet attrs, int defStyleAttr) { 33 | super(context, attrs, defStyleAttr); 34 | setupView(context); 35 | } 36 | 37 | private void setupView(Context context) { 38 | inflate(context, R.layout.view_state, this); 39 | KnifeKit.bind(this); 40 | } 41 | 42 | public void setMsg(String msg) { 43 | if (!TextUtils.isEmpty(msg)) { 44 | tvMsg.setText(msg); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/item_part_touch.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_arrow_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_keyboard_arrow_right_green_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_person_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_save_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_share_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/item_part_touch.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/view_border.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 12 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/view_shadow.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_about.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 12 | 13 | 14 | 22 | 23 | 30 | 31 | 42 | 43 | 54 | 55 | 56 | 64 | 65 | 72 | 73 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 12 | 13 | 21 | 22 | 26 | 27 | 28 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 13 | 14 | 18 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/layout/adapter_ganhuo.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/layout/adapter_girl.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/layout/adapter_home.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 20 | 21 | 28 | 29 | 38 | 39 | 47 | 48 | 55 | 56 | 64 | 65 | 66 | 67 | 72 | 73 | 78 | 79 | 83 | 84 | 94 | 95 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_base_pager.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/layout/view_loading.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/layout/view_state.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 13 | 14 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/res/layout/view_toolbar.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_web.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 9 | 13 | 17 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limedroid/XDroidMvp/d650d69d67f55ea3fc7aace05c8dc95b6338829f/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limedroid/XDroidMvp/d650d69d67f55ea3fc7aace05c8dc95b6338829f/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limedroid/XDroidMvp/d650d69d67f55ea3fc7aace05c8dc95b6338829f/app/src/main/res/mipmap-xhdpi/ic_error.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limedroid/XDroidMvp/d650d69d67f55ea3fc7aace05c8dc95b6338829f/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/xdroid_logo_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limedroid/XDroidMvp/d650d69d67f55ea3fc7aace05c8dc95b6338829f/app/src/main/res/mipmap-xhdpi/xdroid_logo_128.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limedroid/XDroidMvp/d650d69d67f55ea3fc7aace05c8dc95b6338829f/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/android_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limedroid/XDroidMvp/d650d69d67f55ea3fc7aace05c8dc95b6338829f/app/src/main/res/mipmap-xxxhdpi/android_icon.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limedroid/XDroidMvp/d650d69d67f55ea3fc7aace05c8dc95b6338829f/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ios_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limedroid/XDroidMvp/d650d69d67f55ea3fc7aace05c8dc95b6338829f/app/src/main/res/mipmap-xxxhdpi/ios_icon.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/js_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limedroid/XDroidMvp/d650d69d67f55ea3fc7aace05c8dc95b6338829f/app/src/main/res/mipmap-xxxhdpi/js_icon.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/other_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limedroid/XDroidMvp/d650d69d67f55ea3fc7aace05c8dc95b6338829f/app/src/main/res/mipmap-xxxhdpi/other_icon.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/video_icon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limedroid/XDroidMvp/d650d69d67f55ea3fc7aace05c8dc95b6338829f/app/src/main/res/mipmap-xxxhdpi/video_icon.jpg -------------------------------------------------------------------------------- /app/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #0ba25d 4 | #098049 5 | #ffffff 6 | 7 | #000000 8 | #87000000 9 | #38000000 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 18sp 4 | 10sp 5 | 16sp 6 | 15sp 7 | 12sp 8 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | XDroidMvp 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /art/XdroidMvp_total.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limedroid/XDroidMvp/d650d69d67f55ea3fc7aace05c8dc95b6338829f/art/XdroidMvp_total.png -------------------------------------------------------------------------------- /art/snapshot_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limedroid/XDroidMvp/d650d69d67f55ea3fc7aace05c8dc95b6338829f/art/snapshot_1.png -------------------------------------------------------------------------------- /art/snapshot_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limedroid/XDroidMvp/d650d69d67f55ea3fc7aace05c8dc95b6338829f/art/snapshot_2.png -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | apply from: "conf.gradle" 3 | 4 | buildscript { 5 | repositories { 6 | jcenter() 7 | maven { 8 | url 'https://maven.google.com/' 9 | name 'Google' 10 | } 11 | } 12 | dependencies { 13 | classpath 'com.android.tools.build:gradle:3.1.3' 14 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' 15 | classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' 16 | 17 | // NOTE: Do not place your application dependencies here; they belong 18 | // in the individual module build.gradle files 19 | } 20 | } 21 | 22 | allprojects { 23 | repositories { 24 | mavenCentral() 25 | maven { 26 | url 'https://maven.google.com/' 27 | name 'Google' 28 | } 29 | jcenter() 30 | maven { url "https://jitpack.io" } 31 | } 32 | } 33 | 34 | task clean(type: Delete) { 35 | delete rootProject.buildDir 36 | } 37 | -------------------------------------------------------------------------------- /conf.gradle: -------------------------------------------------------------------------------- 1 | ext { 2 | 3 | android = [ 4 | compileSdkVersion: 27, 5 | 6 | minSdkVersion : 15, 7 | targetSdkVersion : 26, 8 | 9 | versionCode : 1, 10 | versionName : '1.0.0', 11 | 12 | VSupportSdk : '27.1.1', 13 | VRetrofitSdk : "2.2.0", 14 | VOkhttp : "3.4.2", 15 | VRxlifecycle : "2.0.1" 16 | ] 17 | dependencies = [ 18 | "appcompat-v7" : "com.android.support:appcompat-v7:${android["VSupportSdk"]}", 19 | "support-v4" : "com.android.support:support-v4:${android["VSupportSdk"]}", 20 | "design" : "com.android.support:design:${android["VSupportSdk"]}", 21 | "annotations" : "com.android.support:support-annotations:${android["VSupportSdk"]}", 22 | "recyclerview-v7" : "com.android.support:recyclerview-v7:${android["VSupportSdk"]}", 23 | 24 | "butterknife" : "com.jakewharton:butterknife:8.4.0", 25 | "butterknife-apt" : "com.jakewharton:butterknife-compiler:8.4.0", 26 | "eventbus" : "org.greenrobot:eventbus:3.0.0", 27 | "glide" : "com.github.bumptech.glide:glide:4.8.0", 28 | "glide-compiler" : "com.github.bumptech.glide:compiler:4.8.0", 29 | "picasso" : "com.squareup.picasso:picasso:2.5.2", 30 | "xrecyclerview" : "com.github.limedroid:ARecyclerView:v1.2.3", 31 | "avi-loading" : "com.wang.avi:library:1.0.2", 32 | "rxbus" : "com.blankj:rxbus:1.2", 33 | 34 | "gson" : "com.google.code.gson:gson:2.6.2", 35 | "rxandroid" : "io.reactivex.rxjava2:rxandroid:2.0.1", 36 | "rxjava" : "io.reactivex.rxjava2:rxjava:2.0.1", 37 | "retrofit" : "com.squareup.retrofit2:retrofit:${android["VRetrofitSdk"]}", 38 | "retrofit-converter-gson" : "com.squareup.retrofit2:converter-gson:${android["VRetrofitSdk"]}", 39 | "retrofit-adapter-rxjava" : "com.squareup.retrofit2:adapter-rxjava2:${android["VRetrofitSdk"]}", 40 | "okhttp3-logging-interceptor": "com.squareup.okhttp3:logging-interceptor:${android["VOkhttp"]}", 41 | "okhttp3" : "com.squareup.okhttp3:okhttp:${android["VOkhttp"]}", 42 | "rxlifecycle" : "com.trello.rxlifecycle2:rxlifecycle:${android["VRxlifecycle"]}", 43 | "rxlifecycle-android" : "com.trello.rxlifecycle2:rxlifecycle-android:${android["VRxlifecycle"]}", 44 | "rxlifecycle-components" : "com.trello.rxlifecycle2:rxlifecycle-components:${android["VRxlifecycle"]}", 45 | "rxpermissions" : "com.tbruyelle.rxpermissions2:rxpermissions:0.9.3@aar", 46 | 47 | "canary-debug" : "com.squareup.leakcanary:leakcanary-android:1.4-beta2", 48 | "canary-release" : "com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta2", 49 | ] 50 | 51 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limedroid/XDroidMvp/d650d69d67f55ea3fc7aace05c8dc95b6338829f/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Apr 13 19:19:31 CST 2018 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /mvp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limedroid/XDroidMvp/d650d69d67f55ea3fc7aace05c8dc95b6338829f/mvp.png -------------------------------------------------------------------------------- /mvp/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'com.github.dcendents.android-maven' 3 | 4 | group = 'com.github.limedroid' 5 | 6 | android { 7 | compileSdkVersion rootProject.ext.android.compileSdkVersion 8 | 9 | defaultConfig { 10 | minSdkVersion rootProject.ext.android.minSdkVersion 11 | targetSdkVersion rootProject.ext.android.targetSdkVersion 12 | versionCode rootProject.ext.android.versionCode 13 | versionName rootProject.ext.android.versionName 14 | } 15 | buildTypes { 16 | release { 17 | minifyEnabled false 18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 19 | } 20 | } 21 | buildToolsVersion '27.0.3' 22 | } 23 | 24 | dependencies { 25 | api fileTree(dir: 'libs', include: ['*.jar']) 26 | api rootProject.ext.dependencies["appcompat-v7"] 27 | api rootProject.ext.dependencies["support-v4"] 28 | api rootProject.ext.dependencies["design"] 29 | api rootProject.ext.dependencies["annotations"] 30 | api rootProject.ext.dependencies["recyclerview-v7"] 31 | 32 | api rootProject.ext.dependencies["xrecyclerview"] 33 | api rootProject.ext.dependencies["butterknife"] 34 | api rootProject.ext.dependencies["glide"] 35 | annotationProcessor rootProject.ext.dependencies["glide-compiler"] 36 | 37 | api rootProject.ext.dependencies["gson"] 38 | api rootProject.ext.dependencies["rxandroid"] 39 | api rootProject.ext.dependencies["rxjava"] 40 | api rootProject.ext.dependencies["retrofit"] 41 | api rootProject.ext.dependencies["retrofit-converter-gson"] 42 | api rootProject.ext.dependencies["retrofit-adapter-rxjava"] 43 | api rootProject.ext.dependencies["okhttp3"] 44 | api rootProject.ext.dependencies["rxbus"] 45 | 46 | api rootProject.ext.dependencies["rxlifecycle"] 47 | api rootProject.ext.dependencies["rxlifecycle-android"] 48 | api rootProject.ext.dependencies["rxlifecycle-components"] 49 | api rootProject.ext.dependencies["rxpermissions"] 50 | } 51 | 52 | tasks.withType(JavaCompile) { 53 | options.encoding = "UTF-8" 54 | } 55 | 56 | task sourcesJar(type: Jar) { 57 | from android.sourceSets.main.java.srcDirs 58 | classifier = 'sources' 59 | } 60 | 61 | artifacts { 62 | archives sourcesJar 63 | } 64 | -------------------------------------------------------------------------------- /mvp/proguard-pro/proguard-ARecyclerView.pro: -------------------------------------------------------------------------------- 1 | ##ARecyclerView:v1.1.5 -------------------------------------------------------------------------------- /mvp/proguard-pro/proguard-avi-loading.pro: -------------------------------------------------------------------------------- 1 | #com.wang.avi:library:1.0.2 2 | 3 | -keep class com.wang.avi.** { *; } 4 | -keep class com.wang.avi.indicators.** { *; } -------------------------------------------------------------------------------- /mvp/proguard-pro/proguard-butterknife.pro: -------------------------------------------------------------------------------- 1 | #butterknife 8.4.0 2 | -keep class butterknife.** { *; } 3 | -dontwarn butterknife.internal.** 4 | -keep class **$$ViewBinder { *; } 5 | 6 | -keepclasseswithmembernames class * { 7 | @butterknife.* ; 8 | } 9 | 10 | -keepclasseswithmembernames class * { 11 | @butterknife.* ; 12 | } -------------------------------------------------------------------------------- /mvp/proguard-pro/proguard-canary-debug.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limedroid/XDroidMvp/d650d69d67f55ea3fc7aace05c8dc95b6338829f/mvp/proguard-pro/proguard-canary-debug.pro -------------------------------------------------------------------------------- /mvp/proguard-pro/proguard-canary-release.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limedroid/XDroidMvp/d650d69d67f55ea3fc7aace05c8dc95b6338829f/mvp/proguard-pro/proguard-canary-release.pro -------------------------------------------------------------------------------- /mvp/proguard-pro/proguard-constraint-layout.pro: -------------------------------------------------------------------------------- 1 | #constraint-layout:1.0.2 -------------------------------------------------------------------------------- /mvp/proguard-pro/proguard-design.pro: -------------------------------------------------------------------------------- 1 | 2 | -dontwarn android.support.design.** 3 | -keep class android.support.design.** { *; } 4 | -keep interface android.support.design.** { *; } 5 | 6 | 7 | -dontwarn android.support.design.internal.** 8 | -keep class android.support.design.internal.** { *; } 9 | -keep interface android.support.design.internal.** { *; } 10 | 11 | 12 | -dontwarn android.support.design.widget.** 13 | -keep class android.support.design.widget.** { *; } 14 | -keep interface android.support.design.widget.** { *; } 15 | 16 | -------------------------------------------------------------------------------- /mvp/proguard-pro/proguard-eventbus-3.pro: -------------------------------------------------------------------------------- 1 | ## EventBus3 specific rules ## 2 | # http://greenrobot.org/eventbus/documentation/proguard/ 3 | 4 | -keepattributes *Annotation* 5 | -keepclassmembers class ** { 6 | @org.greenrobot.eventbus.Subscribe ; 7 | } 8 | -keep enum org.greenrobot.eventbus.ThreadMode { *; } 9 | 10 | # Only required if you use AsyncExecutor 11 | -keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent { 12 | (java.lang.Throwable); 13 | } -------------------------------------------------------------------------------- /mvp/proguard-pro/proguard-eventbus.pro: -------------------------------------------------------------------------------- 1 | #eventbus:3.0.0 2 | ## EventBus3 specific rules ## 3 | # http://greenrobot.org/eventbus/documentation/proguard/ 4 | 5 | -keepattributes *Annotation* 6 | -keepclassmembers class ** { 7 | @org.greenrobot.eventbus.Subscribe ; 8 | } 9 | -keep enum org.greenrobot.eventbus.ThreadMode { *; } 10 | 11 | # Only required if you use AsyncExecutor 12 | -keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent { 13 | (java.lang.Throwable); 14 | } 15 | -------------------------------------------------------------------------------- /mvp/proguard-pro/proguard-glide.pro: -------------------------------------------------------------------------------- 1 | # Glide3.7 specific rules # 2 | # https://github.com/bumptech/glide/wiki/Configuration#keeping-a-glidemodule 3 | 4 | 5 | -keep public class * implements com.bumptech.glide.module.GlideModule 6 | -keep public class * extends com.bumptech.glide.module.AppGlideModule 7 | -keep public enum com.bumptech.glide.load.ImageHeaderParser$** { 8 | **[] $VALUES; 9 | public *; 10 | } -------------------------------------------------------------------------------- /mvp/proguard-pro/proguard-google-gson.pro: -------------------------------------------------------------------------------- 1 | ##com.google.code.gson:gson:2.6.2 2 | 3 | ## GSON 2.6.2 specific rules ## 4 | 5 | # Gson uses generic type information stored in a class file when working with fields. Proguard 6 | # removes such information by default, so configure it to keep all of it. 7 | -keepattributes Signature 8 | 9 | # For using GSON @Expose annotation 10 | -keepattributes *Annotation* 11 | 12 | -keepattributes EnclosingMethod 13 | 14 | # Gson specific classes 15 | -keep class sun.misc.Unsafe { *; } 16 | -keep class com.google.gson.stream.** { *; } 17 | 18 | 19 | # Application classes that will be serialized/deserialized over Gson 20 | #-keep class com.google.gson.examples.android.model.** { *; } 21 | #这是google官方的proguard的文档,请注意倒数第二行,class 后方到**签名的 22 | #这一段包名应该是你所有的java bean 定义的目录(所以自己在写代码时,应该把java bean 单独放在一个包中) 23 | -------------------------------------------------------------------------------- /mvp/proguard-pro/proguard-normal.pro: -------------------------------------------------------------------------------- 1 | ## Proguard normal ## 2 | 3 | # ============================== 基本不用动区域 ============================== 4 | 5 | # ------------------------------- 基本指令区 ------------------------------- 6 | 7 | # 代码混淆的压缩比例(0-7) , 默认为5 , 一般不需要改 8 | -optimizationpasses 5 9 | 10 | # 混淆后类名都小写 (windows最后加上 , 因为windows大小写敏感) 11 | -dontusemixedcaseclassnames 12 | 13 | # 指定不去忽略非公共的库的类(即混淆第三方, 第三方库可能自己混淆了 , 可在后面配置某些第三方库不混淆) 14 | # 默认跳过,有些情况下编写的代码与类库中的类在同一个包下,并且持有包中内容的引用,此时就需要加入此条声明 15 | -dontskipnonpubliclibraryclasses 16 | 17 | # 指定不去忽略非公共的库的类的成员 18 | -dontskipnonpubliclibraryclassmembers 19 | 20 | # 不做预检验,preverify是proguard的四个步骤之一 21 | # Android不需要preverify,去掉这一步可以加快混淆速度 22 | -dontpreverify 23 | 24 | # 有了verbose这句话,混淆后就会生成映射文件 25 | # 包含有类名->混淆后类名的映射关系 26 | # 然后使用printmapping指定映射文件的名称 27 | -verbose 28 | -printmapping proguardMapping.txt 29 | 30 | # 指定混淆时采用的算法,后面的参数是一个过滤器 31 | # 这个过滤器是谷歌推荐的算法,一般不改变 32 | -optimizations !code/simplification/cast,!field/*,!class/merging/* 33 | 34 | # 保护代码中的Annotation不被混淆 35 | # 这在JSON实体映射时非常重要,比如fastJson 36 | -keepattributes *Annotation*,InnerClasses 37 | 38 | -keep public class com.google.vending.licensing.ILicensingService 39 | -keep public class com.android.vending.licensing.ILicensingService 40 | 41 | # 避免混淆泛型 42 | # 这在JSON实体映射时非常重要,比如fastJson 43 | -keepattributes Signature 44 | 45 | #抛出异常时保留源文件和代码行号 46 | -keepattributes SourceFile,LineNumberTable 47 | # ------------------------------- 基本指令区 ------------------------------- 48 | 49 | # ------------------------------- 默认保留区 ------------------------------- 50 | 51 | # 保留四大组件 52 | -keep public class * extends android.app.Activity 53 | # 保留就保证layout中定义的onClick方法不影响 54 | # We want to keep methods in Activity that could be used in the XML attribute onClick 55 | -keepclassmembers class * extends android.app.Activity{ 56 | public void *(android.view.View); 57 | } 58 | -keep public class * extends android.app.Service 59 | -keep public class * extends android.content.BroadcastReceiver 60 | -keep public class * extends android.content.ContentProvider 61 | -keep public class * extends android.app.Application 62 | 63 | -keep public class * extends android.app.backup.BackupAgentHelper 64 | -keep public class * extends android.preference.Preference 65 | 66 | # For native methods, see http://proguard.sourceforge.net/manual/examples.html#native 67 | # 保留类名和native成员方法 68 | -keepclasseswithmembernames class * { 69 | native ; 70 | } 71 | 72 | # 枚举类不能被混淆 73 | # # For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations 74 | -keepclassmembers enum * { 75 | public static **[] values(); 76 | public static ** valueOf(java.lang.String); 77 | } 78 | 79 | # 保留自定义控件(继承自View)的setter、getter和构造方法 80 | # keep setters in Views so that animations can still work. 81 | # see http://proguard.sourceforge.net/manual/examples.html#beans 82 | -keep public class * extends android.view.View{ 83 | public (android.content.Context); 84 | public (android.content.Context, android.util.AttributeSet); 85 | public (android.content.Context, android.util.AttributeSet, int); 86 | *** get*(); 87 | void set*(***); 88 | } 89 | 90 | # 保留Parcelable序列化的类不能被混淆 91 | #-keep class * implements android.os.Parcelable { 92 | # public static final android.os.Parcelable$Creator *; 93 | #} 94 | # 官方 95 | -keepclassmembers class * implements android.os.Parcelable { 96 | public static final android.os.Parcelable$Creator CREATOR; 97 | } 98 | 99 | # 所有实现了 Serializable 接口的类及其成员都不进行混淆 100 | -keepnames class * implements java.io.Serializable 101 | -keepclassmembers class * implements java.io.Serializable { 102 | static final long serialVersionUID; 103 | private static final java.io.ObjectStreamField[] serialPersistentFields; 104 | !static !transient ; 105 | private void writeObject(java.io.ObjectOutputStream); 106 | private void readObject(java.io.ObjectInputStream); 107 | java.lang.Object writeReplace(); 108 | java.lang.Object readResolve(); 109 | } 110 | 111 | # 对R文件下的所有类及其方法 , 都不能被混淆 112 | #-keep class **.R$* { 113 | # *; 114 | #} 115 | # 官方 116 | -keepclassmembers class **.R$* { 117 | public static ; 118 | } 119 | 120 | # The support library contains references to newer platform versions. 121 | # Don't warn about those in case this app is linking against an older 122 | # platform version. We know about them, and they are safe. 123 | -dontwarn android.support.** 124 | 125 | # Understand the @Keep support annotation. 126 | -keep class android.support.annotation.Keep 127 | 128 | -keep @android.support.annotation.Keep class * {*;} 129 | 130 | -keepclasseswithmembers class * { 131 | @android.support.annotation.Keep ; 132 | } 133 | 134 | -keepclasseswithmembers class * { 135 | @android.support.annotation.Keep ; 136 | } 137 | 138 | -keepclasseswithmembers class * { 139 | @android.support.annotation.Keep (...); 140 | } 141 | 142 | # ------------------------------- 默认保留区 end------------------------------- 143 | 144 | #------------------------------- 以上内容基本是SDK目录下的proguard-android-optimize.txt内容 ------------------------------- # 145 | 146 | # ------------------------------- webview相关 ------------------------------- 147 | 148 | -dontwarn android.webkit** 149 | 150 | # WebView(可选) 151 | -keepclassmembers class * extends android.webkit.WebView { 152 | public *; 153 | } 154 | 155 | # WebView的复杂操作 156 | -keepclassmembers class * extends android.webkit.WebViewClient { 157 | public void *(android.webkit.WebView,java.lang.String,android.graphics.Bitmap); 158 | public boolean *(android.webkit.WebView,java.lang.String); 159 | } 160 | -keepclassmembers class * extends android.webkit.WebChromeClient { 161 | public void *(android.webkit.WebView,java.lang.String); 162 | } 163 | 164 | # 与JS交互 165 | -keepattributes SetJavaScriptEnabled 166 | -keepattributes JavascriptInterface 167 | 168 | # 保留与JS交互接口 , API17+ 169 | -keepclassmembers class * { 170 | @android.webkit.JavascriptInterface ; 171 | } 172 | 173 | # ------------------------------- webview相关 end ------------------------------- 174 | 175 | -dontwarn org.apache.** 176 | -dontwarn org.codehaus.** 177 | -dontwarn java.nio.** 178 | -dontwarn java.lang.invoke.** 179 | -dontwarn rx.** 180 | -dontwarn okhttp3.** 181 | -dontwarn okio.** 182 | 183 | # ============================== 基本不动区域 end ============================== 184 | 185 | -------------------------------------------------------------------------------- /mvp/proguard-pro/proguard-okhttp3-logging-interceptor.pro: -------------------------------------------------------------------------------- 1 | #constraint-layout:1.0.2 -------------------------------------------------------------------------------- /mvp/proguard-pro/proguard-okhttp3.pro: -------------------------------------------------------------------------------- 1 | #com.squareup.okhttp3:okhttp V3.4.2 2 | 3 | -keepattributes Signature 4 | -keepattributes *Annotation* 5 | -keep class okhttp3.** { *; } 6 | -keep interface okhttp3.** { *; } 7 | -dontwarn okhttp3.** -------------------------------------------------------------------------------- /mvp/proguard-pro/proguard-picasso.pro: -------------------------------------------------------------------------------- 1 | ##picasso 2.5.2 2 | ## Square Picasso specific rules ## 3 | ## https://square.github.io/picasso/ ## 4 | 5 | -dontwarn com.squareup.okhttp.** -------------------------------------------------------------------------------- /mvp/proguard-pro/proguard-proguard-design.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limedroid/XDroidMvp/d650d69d67f55ea3fc7aace05c8dc95b6338829f/mvp/proguard-pro/proguard-proguard-design.pro -------------------------------------------------------------------------------- /mvp/proguard-pro/proguard-recyclerview-v7.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limedroid/XDroidMvp/d650d69d67f55ea3fc7aace05c8dc95b6338829f/mvp/proguard-pro/proguard-recyclerview-v7.pro -------------------------------------------------------------------------------- /mvp/proguard-pro/proguard-retrofit-adapter-rxjava.pro: -------------------------------------------------------------------------------- 1 | #retrofit2.adapter.rxjava 2 | 3 | -keep class retrofit2.adapter.rxjava.** { *; } 4 | -keep interface retrofit2.adapter.rxjava.** { *; } 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /mvp/proguard-pro/proguard-retrofit-converter-gson.pro: -------------------------------------------------------------------------------- 1 | #retrofit-converters-gson 2 | -keep class retrofit2.converter.gson.** { *; } 3 | -keep interface retrofit2.converter.gson.** { *; } 4 | -------------------------------------------------------------------------------- /mvp/proguard-pro/proguard-retrofit.pro: -------------------------------------------------------------------------------- 1 | # Retrofit 2.X 2 | ## https://square.github.io/retrofit/ ## 3 | 4 | -dontwarn retrofit2.** 5 | -keep class retrofit2.** { *; } 6 | -keepattributes Signature 7 | -keepattributes Exceptions 8 | 9 | # Platform used when running on Java 8 VMs. Will not be used at runtime. 10 | -dontwarn retrofit2.Platform$Java8 11 | 12 | -keepclasseswithmembers class * { 13 | @retrofit2.http.* ; 14 | } -------------------------------------------------------------------------------- /mvp/proguard-pro/proguard-rxandroid.pro: -------------------------------------------------------------------------------- 1 | #io.reactivex:rxandroid:1.2.1 2 | 3 | -keep class rx.android.** { *; } 4 | -keep interface rx.android.** { *; } 5 | 6 | -keep class rx.android.plugins.** { *; } 7 | -keep interface rx.android.plugins.** { *; } 8 | 9 | -keep class rx.android.schedulers.** { *; } 10 | -keep interface rx.android.schedulers.** { *; } 11 | -------------------------------------------------------------------------------- /mvp/proguard-pro/proguard-rxjava.pro: -------------------------------------------------------------------------------- 1 | #io.reactivex:rxjava:1.1.6 2 | 3 | -dontwarn sun.misc.** 4 | 5 | -keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* { 6 | long producerIndex; 7 | long consumerIndex; 8 | } 9 | 10 | -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef { 11 | rx.internal.util.atomic.LinkedQueueNode producerNode; 12 | } 13 | 14 | -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef { 15 | rx.internal.util.atomic.LinkedQueueNode consumerNode; 16 | } 17 | 18 | -dontnote rx.internal.util.PlatformDependent -------------------------------------------------------------------------------- /mvp/proguard-pro/proguard-rxlifecycle-android.pro: -------------------------------------------------------------------------------- 1 | #com.trello:rxlifecycle 2 | 3 | 4 | -keep class com.trello.rxlifecycle.android.** { *; } 5 | -keep interface com.trello.rxlifecycle.android.** { *; } 6 | -------------------------------------------------------------------------------- /mvp/proguard-pro/proguard-rxlifecycle-components.pro: -------------------------------------------------------------------------------- 1 | -keep class com.trello.rxlifecycle.components.** { *; } 2 | -keep interface com.trello.rxlifecycle.components.** { *; } 3 | 4 | 5 | -keep class com.trello.rxlifecycle.components.support.** { *; } 6 | -keep interface com.trello.rxlifecycle.components.support.** { *; } -------------------------------------------------------------------------------- /mvp/proguard-pro/proguard-rxlifecycle.pro: -------------------------------------------------------------------------------- 1 | #com.trello:rxlifecycle 2 | 3 | 4 | -keep class com.trello.rxlifecycle.** { *; } 5 | -keep interface com.trello.rxlifecycle.** { *; } 6 | 7 | 8 | -keep class com.trello.rxlifecycle.internal.** { *; } 9 | -keep interface com.trello.rxlifecycle.internal.** { *; } -------------------------------------------------------------------------------- /mvp/proguard-pro/proguard-rxpermissions.pro: -------------------------------------------------------------------------------- 1 | #rxpermissions com.tbruyelle.rxpermissions:rxpermissions:0.9.1 2 | 3 | -keep class com.tbruyelle.rxpermissions.** { *; } 4 | -keep interface com.tbruyelle.rxpermissions.** { *; } -------------------------------------------------------------------------------- /mvp/proguard-pro/proguard-self.pro: -------------------------------------------------------------------------------- 1 | # ------------------------------- 自定义区 ------------------------------- 2 | 3 | 4 | -keepattributes Signature 5 | -keepattributes *Annotation* 6 | -keep class cn.droidlover.xdroidmvp.** { *; } 7 | -keep interface cn.droidlover.xdroidmvp.** { *; } 8 | -dontwarn cn.droidlover.xdroidmvp.** 9 | 10 | # ------------------------------- 自定义区 end ------------------------------- 11 | -------------------------------------------------------------------------------- /mvp/proguard-pro/proguard-support-v4.pro: -------------------------------------------------------------------------------- 1 | #support.v4 2 | -dontwarn android.support.v4.** 3 | -dontwarn **CompatHoneycomb 4 | -dontwarn **CompatHoneycombMR2 5 | -dontwarn **CompatCreatorHoneycombMR2 6 | -keep interface android.support.v4.app.** { *; } 7 | -keep class android.support.v4.** { *; } 8 | -keep public class * extends android.support.v4.** 9 | -keep public class * extends android.app.Fragment 10 | 11 | -------------------------------------------------------------------------------- /mvp/proguard-pro/proguard-support-v7-appcompat.pro: -------------------------------------------------------------------------------- 1 | 2 | -keep public class android.support.v7.widget.** { *; } 3 | -keep public class android.support.v7.internal.widget.** { *; } 4 | -keep public class android.support.v7.internal.view.menu.** { *; } 5 | 6 | -keep public class * extends android.support.v4.view.ActionProvider { 7 | public (android.content.Context); 8 | } 9 | -------------------------------------------------------------------------------- /mvp/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Proguard 2 | 3 | -basedirectory proguard-pro 4 | 5 | -include proguard-normal.pro 6 | 7 | -include proguard-self.pro 8 | 9 | -include proguard-ARecyclerView.pro 10 | 11 | -include proguard-avi-loading.pro 12 | 13 | -include proguard-butterknife.pro 14 | 15 | -include proguard-canary-debug.pro 16 | 17 | -include proguard-canary-release.pro 18 | 19 | -include proguard-constraint-layout.pro 20 | 21 | -include proguard-design.pro 22 | 23 | -include proguard-eventbus-3.pro 24 | 25 | -include proguard-eventbus.pro 26 | 27 | -include proguard-glide.pro 28 | 29 | -include proguard-google-gson.pro 30 | 31 | -include proguard-okhttp3-logging-interceptor.pro 32 | 33 | -include proguard-okhttp3.pro 34 | 35 | -include proguard-picasso.pro 36 | 37 | -include proguard-proguard-design.pro 38 | 39 | -include proguard-recyclerview-v7.pro 40 | 41 | -include proguard-retrofit-adapter-rxjava.pro 42 | 43 | -include proguard-retrofit-converter-gson.pro 44 | 45 | -include proguard-retrofit.pro 46 | 47 | -include proguard-rxandroid.pro 48 | 49 | -include proguard-rxjava.pro 50 | 51 | -include proguard-rxlifecycle-android.pro 52 | 53 | -include proguard-rxlifecycle-components.pro 54 | 55 | -include proguard-rxlifecycle.pro 56 | 57 | -include proguard-rxpermissions.pro 58 | 59 | -include proguard-support-v4.pro 60 | 61 | -include proguard-support-v7-appcompat.pro 62 | 63 | 64 | -------------------------------------------------------------------------------- /mvp/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/XDroidConf.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp; 2 | 3 | import cn.droidlover.xdroidmvp.imageloader.ILoader; 4 | import cn.droidlover.xdroidmvp.kit.Kits; 5 | import cn.droidlover.xdroidmvp.router.Router; 6 | 7 | /** 8 | * Created by wanglei on 2016/12/4. 9 | */ 10 | 11 | public class XDroidConf { 12 | // #log 13 | public static boolean LOG = true; 14 | public static String LOG_TAG = "XDroid"; 15 | 16 | // #cache 17 | public static String CACHE_SP_NAME = "config"; 18 | public static String CACHE_DISK_DIR = "cache"; 19 | 20 | // #router 21 | public static int ROUTER_ANIM_ENTER = Router.RES_NONE; 22 | public static int ROUTER_ANIM_EXIT = Router.RES_NONE; 23 | 24 | // #imageloader 25 | public static int IL_LOADING_RES = ILoader.Options.RES_NONE; 26 | public static int IL_ERROR_RES = ILoader.Options.RES_NONE; 27 | 28 | // #dev model 29 | public static boolean DEV = true; 30 | 31 | /** 32 | * config log 33 | * 34 | * @param log 35 | * @param logTag 36 | */ 37 | public static void configLog(boolean log, String logTag) { 38 | LOG = log; 39 | if (!Kits.Empty.check(logTag)) { 40 | LOG_TAG = logTag; 41 | } 42 | } 43 | 44 | /** 45 | * conf cache 46 | * 47 | * @param spName 48 | * @param diskDir 49 | */ 50 | public static void configCache(String spName, String diskDir) { 51 | if (!Kits.Empty.check(spName)) { 52 | CACHE_SP_NAME = spName; 53 | } 54 | if (!Kits.Empty.check(diskDir)) { 55 | CACHE_DISK_DIR = diskDir; 56 | } 57 | } 58 | 59 | /** 60 | * config dev 61 | * 62 | * @param isDev 63 | */ 64 | public static void devMode(boolean isDev) { 65 | DEV = isDev; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/base/ListItemCallback.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.base; 2 | 3 | /** 4 | * Created by wanglei on 2016/12/1. 5 | */ 6 | 7 | public abstract class ListItemCallback { 8 | 9 | public void onItemClick(int position, T model, int tag) {} 10 | 11 | public void onItemLongClick(int position, T model, int tag) {} 12 | } 13 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/base/SimpleListAdapter.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.base; 2 | 3 | import android.content.Context; 4 | import android.view.View; 5 | import android.view.ViewGroup; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * Created by wanglei on 2016/12/1. 11 | */ 12 | 13 | public abstract class SimpleListAdapter extends XListAdapter { 14 | 15 | public SimpleListAdapter(Context context) { 16 | super(context); 17 | } 18 | 19 | public SimpleListAdapter(Context context, ListItemCallback callback) { 20 | super(context, callback); 21 | } 22 | 23 | public SimpleListAdapter(Context context, List data) { 24 | super(context, data); 25 | } 26 | 27 | @Override 28 | public View getView(int position, View convertView, ViewGroup parent) { 29 | H holder = null; 30 | T item = data.get(position); 31 | 32 | if (convertView == null) { 33 | convertView = View.inflate(context, getLayoutId(), null); 34 | holder = newViewHolder(convertView); 35 | 36 | convertView.setTag(holder); 37 | } else { 38 | holder = (H) convertView.getTag(); 39 | } 40 | 41 | convert(holder, item, position); 42 | 43 | return convertView; 44 | } 45 | 46 | protected abstract H newViewHolder(View convertView); 47 | 48 | protected abstract int getLayoutId(); 49 | 50 | protected abstract void convert(H holder, T item, int position); 51 | } 52 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/base/SimpleRecAdapter.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.base; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | 9 | import cn.droidlover.xrecyclerview.RecyclerAdapter; 10 | 11 | /** 12 | * Created by wanglei on 2016/11/29. 13 | */ 14 | 15 | public abstract class SimpleRecAdapter extends RecyclerAdapter { 16 | 17 | public SimpleRecAdapter(Context context) { 18 | super(context); 19 | } 20 | 21 | @Override 22 | public F onCreateViewHolder(ViewGroup parent, int viewType) { 23 | View view = LayoutInflater.from(parent.getContext()).inflate(getLayoutId(), parent, false); 24 | return newViewHolder(view); 25 | } 26 | 27 | public abstract F newViewHolder(View itemView); 28 | 29 | public abstract int getLayoutId(); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/base/XFragmentAdapter.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.base; 2 | 3 | import android.support.v4.app.Fragment; 4 | import android.support.v4.app.FragmentManager; 5 | import android.support.v4.app.FragmentPagerAdapter; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | /** 11 | * Created by wanglei on 2016/12/10. 12 | */ 13 | 14 | public class XFragmentAdapter extends FragmentPagerAdapter { 15 | private List fragmentList = new ArrayList<>(); 16 | private String[] titles; 17 | 18 | public XFragmentAdapter(FragmentManager fm, List fragmentList, String[] titles) { 19 | super(fm); 20 | this.fragmentList.clear(); 21 | this.fragmentList.addAll(fragmentList); 22 | this.titles = titles; 23 | } 24 | 25 | @Override 26 | public CharSequence getPageTitle(int position) { 27 | if (titles != null && titles.length > position) { 28 | return titles[position]; 29 | } 30 | return ""; 31 | } 32 | 33 | @Override 34 | public Fragment getItem(int position) { 35 | return fragmentList.get(position); 36 | } 37 | 38 | @Override 39 | public int getCount() { 40 | return fragmentList.size(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/base/XListAdapter.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.base; 2 | 3 | import android.content.Context; 4 | import android.graphics.drawable.Drawable; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.BaseAdapter; 8 | 9 | import java.util.ArrayList; 10 | import java.util.Arrays; 11 | import java.util.List; 12 | 13 | /** 14 | * Created by wanglei on 2016/12/1. 15 | */ 16 | 17 | public abstract class XListAdapter extends BaseAdapter { 18 | protected List data = new ArrayList(); 19 | private ListItemCallback callback; 20 | protected Context context; 21 | 22 | public XListAdapter(Context context) { 23 | this.context = context; 24 | } 25 | 26 | public XListAdapter(Context context, ListItemCallback callback) { 27 | this(context); 28 | this.callback = callback; 29 | } 30 | 31 | public XListAdapter(Context context, List data) { 32 | this.context = context; 33 | this.data.clear(); 34 | this.data.addAll(data); 35 | notifyDataSetChanged(); 36 | } 37 | 38 | public void setData(List data) { 39 | if (data != null) { 40 | this.data.clear(); 41 | this.data.addAll(data); 42 | } else { 43 | this.data.clear(); 44 | } 45 | notifyDataSetChanged(); 46 | } 47 | 48 | 49 | public void setData(T[] data) { 50 | if (data != null && data.length > 0) { 51 | setData(Arrays.asList(data)); 52 | } 53 | } 54 | 55 | 56 | public void addData(List data) { 57 | if (data != null && data.size() > 0) { 58 | if (this.data == null) { 59 | this.data = new ArrayList(); 60 | } 61 | this.data.addAll(data); 62 | notifyDataSetChanged(); 63 | } 64 | } 65 | 66 | 67 | public void addData(T[] data) { 68 | addData(Arrays.asList(data)); 69 | } 70 | 71 | public void removeElement(T element) { 72 | if (data.contains(element)) { 73 | data.remove(element); 74 | notifyDataSetChanged(); 75 | } 76 | } 77 | 78 | public void removeElement(int position) { 79 | if (data != null && data.size() > position) { 80 | data.remove(position); 81 | notifyDataSetChanged(); 82 | } 83 | } 84 | 85 | public void removeElements(List elements) { 86 | if (data != null && elements != null && elements.size() > 0 87 | && data.size() >= elements.size()) { 88 | 89 | for (T element : elements) { 90 | if (data.contains(element)) { 91 | data.remove(element); 92 | } 93 | } 94 | 95 | notifyDataSetChanged(); 96 | } 97 | } 98 | 99 | public void removeElements(T[] elements) { 100 | if (elements != null && elements.length > 0) { 101 | removeElements(Arrays.asList(elements)); 102 | } 103 | } 104 | 105 | public void updateElement(T element, int position) { 106 | if (position >= 0 && data.size() > position) { 107 | data.remove(position); 108 | data.add(position, element); 109 | notifyDataSetChanged(); 110 | } 111 | } 112 | 113 | public void addElement(T element) { 114 | if (element != null) { 115 | if (this.data == null) { 116 | this.data = new ArrayList(); 117 | } 118 | data.add(element); 119 | notifyDataSetChanged(); 120 | } 121 | } 122 | 123 | public void clearData() { 124 | if (this.data != null) { 125 | this.data.clear(); 126 | notifyDataSetChanged(); 127 | } 128 | } 129 | 130 | protected void visible(boolean flag, View view) { 131 | if (flag) 132 | view.setVisibility(View.VISIBLE); 133 | } 134 | 135 | 136 | protected void gone(boolean flag, View view) { 137 | if (flag) 138 | view.setVisibility(View.GONE); 139 | } 140 | 141 | protected void inVisible(View view) { 142 | view.setVisibility(View.INVISIBLE); 143 | } 144 | 145 | 146 | protected Drawable getDrawable(int resId) { 147 | return context.getResources().getDrawable(resId); 148 | } 149 | 150 | 151 | protected String getString(int resId) { 152 | return context.getResources().getString(resId); 153 | } 154 | 155 | 156 | protected int getColor(int resId) { 157 | return context.getResources().getColor(resId); 158 | } 159 | 160 | 161 | public List getDataSource() { 162 | return data; 163 | } 164 | 165 | public void setCallback(ListItemCallback callback) { 166 | this.callback = callback; 167 | } 168 | 169 | public ListItemCallback getCallback() { 170 | return callback; 171 | } 172 | 173 | 174 | public int getSize() { 175 | return data == null ? 0 : data.size(); 176 | } 177 | 178 | @Override 179 | public int getCount() { 180 | return data == null || data.isEmpty() ? 0 : data.size(); 181 | } 182 | 183 | @Override 184 | public Object getItem(int position) { 185 | return data != null ? data.get(position) : null; 186 | } 187 | 188 | @Override 189 | public long getItemId(int position) { 190 | return position; 191 | } 192 | 193 | @Override 194 | public abstract View getView(int position, View convertView, 195 | ViewGroup parent); 196 | 197 | 198 | } 199 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/cache/DiskCache.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.cache; 2 | 3 | import android.content.Context; 4 | import android.os.Environment; 5 | import android.text.TextUtils; 6 | 7 | import java.io.File; 8 | import java.io.IOException; 9 | import java.util.Calendar; 10 | import java.util.regex.Matcher; 11 | import java.util.regex.Pattern; 12 | 13 | import cn.droidlover.xdroidmvp.XDroidConf; 14 | import cn.droidlover.xdroidmvp.kit.Codec; 15 | import cn.droidlover.xdroidmvp.kit.Kits; 16 | 17 | /** 18 | * Created by wanglei on 2016/11/28. 19 | */ 20 | 21 | public class DiskCache implements ICache { 22 | private DiskLruCache cache; 23 | 24 | static String TAG_CACHE = "=====createTime{createTime_v}expireMills{expireMills_v}"; 25 | static String REGEX = "=====createTime\\{(\\d{1,})\\}expireMills\\{(-?\\d{1,})\\}"; 26 | private Pattern compile; 27 | 28 | public static final long NO_CACHE = -1L; 29 | 30 | private static DiskCache instance; 31 | 32 | private DiskCache(Context context) { 33 | compile = Pattern.compile(REGEX); 34 | try { 35 | File cacheDir = getDiskCacheDir(context, getCacheDir()); 36 | if (!cacheDir.exists()) { 37 | cacheDir.mkdirs(); 38 | } 39 | cache = DiskLruCache.open(cacheDir, Kits.Package.getVersionCode(context), 1, 10 * 1024 * 1024); //10M 40 | } catch (IOException e) { 41 | e.printStackTrace(); 42 | } 43 | } 44 | 45 | public static DiskCache getInstance(Context context) { 46 | if (instance == null) { 47 | synchronized (DiskCache.class) { 48 | if (instance == null) { 49 | instance = new DiskCache(context.getApplicationContext()); 50 | } 51 | } 52 | } 53 | return instance; 54 | } 55 | 56 | public void put(String key, String value) { 57 | put(key, value, NO_CACHE); 58 | } 59 | 60 | public void put(String key, String value, long expireMills) { 61 | if (TextUtils.isEmpty(key) || TextUtils.isEmpty(value)) return; 62 | 63 | String name = getMd5Key(key); 64 | try { 65 | if (!TextUtils.isEmpty(get(name))) { //如果存在,先删除 66 | cache.remove(name); 67 | } 68 | 69 | DiskLruCache.Editor editor = cache.edit(name); 70 | StringBuilder content = new StringBuilder(value); 71 | content.append(TAG_CACHE.replace("createTime_v", "" + Calendar.getInstance().getTimeInMillis()).replace("expireMills_v", "" + expireMills)); 72 | editor.set(0, content.toString()); 73 | editor.commit(); 74 | } catch (IOException e) { 75 | e.printStackTrace(); 76 | } 77 | } 78 | 79 | @Override 80 | public void put(String key, Object value) { 81 | put(key, value != null ? value.toString() : null, NO_CACHE); 82 | } 83 | 84 | 85 | public String get(String key) { 86 | try { 87 | String md5Key = getMd5Key(key); 88 | DiskLruCache.Snapshot snapshot = cache.get(md5Key); 89 | if (snapshot != null) { 90 | String content = snapshot.getString(0); 91 | 92 | if (!TextUtils.isEmpty(content)) { 93 | Matcher matcher = compile.matcher(content); 94 | long createTime = 0; 95 | long expireMills = 0; 96 | while (matcher.find()) { 97 | createTime = Long.parseLong(matcher.group(1)); 98 | expireMills = Long.parseLong(matcher.group(2)); 99 | } 100 | int index = content.indexOf("=====createTime"); 101 | 102 | if ((createTime + expireMills > Calendar.getInstance().getTimeInMillis()) 103 | || expireMills == NO_CACHE) { 104 | return content.substring(0, index); 105 | } else { 106 | //过期 107 | cache.remove(md5Key); //删除 108 | } 109 | } 110 | } 111 | 112 | } catch (Exception e) { 113 | e.printStackTrace(); 114 | } 115 | return null; 116 | } 117 | 118 | public void remove(String key) { 119 | try { 120 | cache.remove(getMd5Key(key)); 121 | } catch (Exception e) { 122 | e.printStackTrace(); 123 | } 124 | } 125 | 126 | public boolean contains(String key) { 127 | try { 128 | DiskLruCache.Snapshot snapshot = cache.get(getMd5Key(key)); 129 | return snapshot != null; 130 | } catch (IOException e) { 131 | e.printStackTrace(); 132 | } 133 | return false; 134 | } 135 | 136 | public void clear() { 137 | try { 138 | cache.delete(); 139 | } catch (IOException e) { 140 | e.printStackTrace(); 141 | } 142 | } 143 | 144 | public static String getMd5Key(String key) { 145 | return Codec.MD5.getMessageDigest(key.getBytes()); 146 | } 147 | 148 | private static File getDiskCacheDir(Context context, String dirName) { 149 | String cachePath; 150 | if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) 151 | || !Environment.isExternalStorageRemovable()) { 152 | cachePath = context.getExternalCacheDir().getPath(); 153 | } else { 154 | cachePath = context.getCacheDir().getPath(); 155 | } 156 | return new File(cachePath + File.separator + dirName); 157 | } 158 | 159 | private String getCacheDir() { 160 | return XDroidConf.CACHE_DISK_DIR; 161 | } 162 | 163 | 164 | } 165 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/cache/ICache.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.cache; 2 | 3 | /** 4 | * Created by wanglei on 2016/11/27. 5 | */ 6 | 7 | public interface ICache { 8 | void put(String key, Object value); 9 | 10 | Object get(String key); 11 | 12 | void remove(String key); 13 | 14 | boolean contains(String key); 15 | 16 | void clear(); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/cache/MemoryCache.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.cache; 2 | 3 | import android.support.v4.util.LruCache; 4 | import android.text.TextUtils; 5 | 6 | /** 7 | * Created by wanglei on 2016/11/28. 8 | */ 9 | 10 | public class MemoryCache implements ICache { 11 | 12 | private LruCache cache; 13 | private static MemoryCache instance; 14 | 15 | private MemoryCache() { 16 | int maxMemory = (int) Runtime.getRuntime().maxMemory(); 17 | int cacheSize = maxMemory / 8; 18 | cache = new LruCache(cacheSize); 19 | 20 | } 21 | 22 | public static MemoryCache getInstance() { 23 | if (instance == null) { 24 | synchronized (MemoryCache.class) { 25 | if (instance == null) { 26 | instance = new MemoryCache(); 27 | } 28 | } 29 | } 30 | return instance; 31 | } 32 | 33 | 34 | @Override 35 | public synchronized void put(String key, Object value) { 36 | if (TextUtils.isEmpty(key)) return; 37 | 38 | if (cache.get(key) != null) { 39 | cache.remove(key); 40 | } 41 | cache.put(key, value); 42 | } 43 | 44 | @Override 45 | public Object get(String key) { 46 | return cache.get(key); 47 | } 48 | 49 | public synchronized T get(String key, Class clazz) { 50 | try { 51 | return (T) cache.get(key); 52 | } catch (Exception e) { 53 | e.printStackTrace(); 54 | } 55 | return null; 56 | } 57 | 58 | @Override 59 | public void remove(String key) { 60 | if (cache.get(key) != null) { 61 | cache.remove(key); 62 | } 63 | } 64 | 65 | @Override 66 | public boolean contains(String key) { 67 | return cache.get(key) != null; 68 | } 69 | 70 | @Override 71 | public void clear() { 72 | cache.evictAll(); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/cache/SharedPref.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.cache; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | 6 | import cn.droidlover.xdroidmvp.XDroidConf; 7 | 8 | /** 9 | * Created by wanglei on 2016/11/27. 10 | */ 11 | 12 | public class SharedPref implements ICache { 13 | 14 | private static SharedPreferences sharedPreferences; 15 | private static SharedPreferences.Editor editor; 16 | 17 | static final String SP_NAME = XDroidConf.CACHE_SP_NAME; 18 | 19 | private static SharedPref instance; 20 | 21 | private SharedPref(Context context) { 22 | sharedPreferences = context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE); 23 | editor = sharedPreferences.edit(); 24 | } 25 | 26 | public static SharedPref getInstance(Context context) { 27 | if (instance == null) { 28 | synchronized (SharedPref.class) { 29 | if (instance == null) { 30 | instance = new SharedPref(context.getApplicationContext()); 31 | } 32 | } 33 | } 34 | return instance; 35 | } 36 | 37 | @Override 38 | public void remove(String key) { 39 | editor.remove(key); 40 | editor.apply(); 41 | } 42 | 43 | 44 | @Override 45 | public boolean contains(String key) { 46 | return sharedPreferences.contains(key); 47 | } 48 | 49 | @Override 50 | public void clear() { 51 | editor.clear().apply(); 52 | } 53 | 54 | 55 | public void putInt(String key, int value) { 56 | editor.putInt(key, value); 57 | editor.apply(); 58 | } 59 | 60 | public int getInt(String key, int defValue) { 61 | return sharedPreferences.getInt(key, defValue); 62 | } 63 | 64 | public void putLong(String key, Long value) { 65 | editor.putLong(key, value); 66 | editor.apply(); 67 | } 68 | 69 | public long getLong(String key, long defValue) { 70 | return sharedPreferences.getLong(key, defValue); 71 | } 72 | 73 | 74 | public void putBoolean(String key, Boolean value) { 75 | editor.putBoolean(key, value); 76 | editor.apply(); 77 | } 78 | 79 | public boolean getBoolean(String key, boolean defValue) { 80 | return sharedPreferences.getBoolean(key, defValue); 81 | } 82 | 83 | 84 | public void putString(String key, String value) { 85 | editor.putString(key, value); 86 | editor.apply(); 87 | } 88 | 89 | public String getString(String key, String defValue) { 90 | return sharedPreferences.getString(key, defValue); 91 | } 92 | 93 | @Override 94 | public Object get(String key) { 95 | return null; 96 | } 97 | 98 | @Override 99 | public void put(String key, Object value) { 100 | 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/event/BusProvider.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.event; 2 | 3 | /** 4 | * Created by wanglei on 2016/12/22. 5 | */ 6 | 7 | public class BusProvider { 8 | 9 | private static RxBusImpl bus; 10 | 11 | public static RxBusImpl getBus() { 12 | if (bus == null) { 13 | synchronized (BusProvider.class) { 14 | if (bus == null) { 15 | bus = RxBusImpl.get(); 16 | } 17 | } 18 | } 19 | return bus; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/event/IBus.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.event; 2 | 3 | /** 4 | * Created by wanglei on 2016/12/22. 5 | */ 6 | 7 | public interface IBus { 8 | 9 | void register(Object object); 10 | 11 | void unregister(Object object); 12 | 13 | void post(AbsEvent event); 14 | 15 | void postSticky(AbsEvent event); 16 | 17 | 18 | abstract class AbsEvent { 19 | public abstract int getTag(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/event/RxBusImpl.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.event; 2 | 3 | 4 | import com.blankj.rxbus.RxBus; 5 | 6 | /** 7 | * Created by wanglei on 2016/12/22. 8 | */ 9 | 10 | public class RxBusImpl implements IBus { 11 | 12 | private RxBusImpl() { 13 | } 14 | 15 | 16 | @Override 17 | public void register(Object object) { 18 | } 19 | 20 | @Override 21 | public void unregister(Object object) { 22 | RxBus.getDefault().unregister(object); 23 | } 24 | 25 | @Override 26 | public void post(AbsEvent event) { 27 | RxBus.getDefault().post(event); 28 | } 29 | 30 | @Override 31 | public void postSticky(AbsEvent event) { 32 | RxBus.getDefault().postSticky(event); 33 | } 34 | 35 | public void subscribe(Object subscriber, 36 | RxBus.Callback callback) { 37 | RxBus.getDefault().subscribe(subscriber, callback); 38 | } 39 | 40 | public void subscribeSticky(Object subscriber, 41 | RxBus.Callback callback) { 42 | RxBus.getDefault().subscribeSticky(subscriber, callback); 43 | } 44 | 45 | public static RxBusImpl get() { 46 | return Holder.instance; 47 | } 48 | 49 | private static class Holder { 50 | private static final RxBusImpl instance = new RxBusImpl(); 51 | } 52 | } 53 | 54 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/imageloader/ILFactory.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.imageloader; 2 | 3 | /** 4 | * Created by wanglei on 2016/11/28. 5 | */ 6 | public class ILFactory { 7 | 8 | private static ILoader loader; 9 | 10 | 11 | public static ILoader getLoader() { 12 | if (loader == null) { 13 | synchronized (ILFactory.class) { 14 | if (loader == null) { 15 | loader = new GlideLoader(); 16 | } 17 | } 18 | } 19 | return loader; 20 | } 21 | 22 | 23 | } 24 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/imageloader/ILoader.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.imageloader; 2 | 3 | import android.content.Context; 4 | import android.widget.ImageView; 5 | 6 | import java.io.File; 7 | 8 | import cn.droidlover.xdroidmvp.XDroidConf; 9 | 10 | /** 11 | * Created by wanglei on 2016/11/27. 12 | */ 13 | 14 | public interface ILoader { 15 | 16 | void init(Context context); 17 | 18 | void loadNet(ImageView target, String url, Options options); 19 | 20 | void loadNet(Context context, String url, Options options, LoadCallback callback); 21 | 22 | void loadResource(ImageView target, int resId, Options options); 23 | 24 | void loadAssets(ImageView target, String assetName, Options options); 25 | 26 | void loadFile(ImageView target, File file, Options options); 27 | 28 | void clearMemoryCache(Context context); 29 | 30 | void clearDiskCache(Context context); 31 | 32 | void resume(Context context); 33 | 34 | void pause(Context context); 35 | 36 | void loadCircle(String url, ImageView target, Options options); 37 | 38 | void loadCorner(String url, ImageView target, int radius, Options options); 39 | 40 | class Options { 41 | 42 | public int loadingResId = RES_NONE; //加载中的资源id 43 | public int loadErrorResId = RES_NONE; //加载失败的资源id 44 | public ImageView.ScaleType scaleType = ImageView.ScaleType.CENTER_CROP; 45 | 46 | public static final int RES_NONE = -1; 47 | 48 | public static Options defaultOptions() { 49 | return new Options(XDroidConf.IL_LOADING_RES, XDroidConf.IL_ERROR_RES); 50 | } 51 | 52 | public Options(int loadingResId, int loadErrorResId) { 53 | this.loadingResId = loadingResId; 54 | this.loadErrorResId = loadErrorResId; 55 | } 56 | 57 | public Options scaleType(ImageView.ScaleType scaleType) { 58 | this.scaleType = scaleType; 59 | return this; 60 | } 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/imageloader/LoadCallback.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.imageloader; 2 | 3 | import android.graphics.drawable.Drawable; 4 | 5 | /** 6 | * Created by wanglei on 2016/12/21. 7 | */ 8 | 9 | public abstract class LoadCallback { 10 | void onLoadFailed() {} 11 | 12 | public abstract void onLoadReady(Drawable drawable); 13 | 14 | void onLoadCanceled() {} 15 | } 16 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/kit/KnifeKit.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.kit; 2 | 3 | import android.app.Activity; 4 | import android.app.Dialog; 5 | import android.view.View; 6 | 7 | import butterknife.ButterKnife; 8 | import butterknife.Unbinder; 9 | 10 | /** 11 | * Created by wanglei on 2016/11/27. 12 | */ 13 | 14 | public class KnifeKit { 15 | 16 | public static Unbinder bind(Object target) { 17 | if (target instanceof Activity) { 18 | return ButterKnife.bind((Activity) target); 19 | } else if (target instanceof Dialog) { 20 | return ButterKnife.bind((Dialog) target); 21 | } else if (target instanceof View) { 22 | return ButterKnife.bind((View) target); 23 | } 24 | return Unbinder.EMPTY; 25 | } 26 | 27 | 28 | public static Unbinder bind(Object target, Object source) { 29 | if (source instanceof Activity) { 30 | return ButterKnife.bind(target, (Activity) source); 31 | } else if (source instanceof Dialog) { 32 | return ButterKnife.bind(target, (Dialog) source); 33 | } else if (source instanceof View) { 34 | return ButterKnife.bind(target, (View) source); 35 | } 36 | return Unbinder.EMPTY; 37 | } 38 | 39 | 40 | public static void unbind(Unbinder unbinder) { 41 | if (unbinder != Unbinder.EMPTY) { 42 | unbinder.unbind(); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/kit/SimpleCallback.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.kit; 2 | 3 | /** 4 | * Created by wanglei on 2016/12/1. 5 | */ 6 | public interface SimpleCallback { 7 | void action(T data); 8 | } 9 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/log/LogFormat.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.log; 2 | 3 | import org.json.JSONArray; 4 | import org.json.JSONObject; 5 | 6 | import java.io.PrintWriter; 7 | import java.io.StringReader; 8 | import java.io.StringWriter; 9 | import java.net.UnknownHostException; 10 | 11 | import javax.xml.transform.OutputKeys; 12 | import javax.xml.transform.Source; 13 | import javax.xml.transform.Transformer; 14 | import javax.xml.transform.TransformerFactory; 15 | import javax.xml.transform.stream.StreamResult; 16 | import javax.xml.transform.stream.StreamSource; 17 | 18 | import cn.droidlover.xdroidmvp.kit.Kits; 19 | 20 | /** 21 | * Created by wanglei on 2016/11/29. 22 | */ 23 | 24 | public class LogFormat { 25 | 26 | static final int JSON_INDENT = 4; 27 | static final int XML_INDENT = 4; 28 | 29 | private static final char VERTICAL_BORDER_CHAR = '║'; 30 | 31 | // Length: 100. 32 | private static final String TOP_HORIZONTAL_BORDER = 33 | "╔═════════════════════════════════════════════════" + 34 | "══════════════════════════════════════════════════"; 35 | 36 | // Length: 99. 37 | private static final String DIVIDER_HORIZONTAL_BORDER = 38 | "╟─────────────────────────────────────────────────" + 39 | "──────────────────────────────────────────────────"; 40 | 41 | // Length: 100. 42 | private static final String BOTTOM_HORIZONTAL_BORDER = 43 | "╚═════════════════════════════════════════════════" + 44 | "══════════════════════════════════════════════════"; 45 | 46 | public static String formatJson(String json) { 47 | String formatted = null; 48 | if (json == null || json.length() == 0) { 49 | return formatted; 50 | } 51 | try { 52 | if (json.startsWith("{")) { 53 | JSONObject jo = new JSONObject(json); 54 | formatted = jo.toString(JSON_INDENT); 55 | } else if (json.startsWith("[")) { 56 | JSONArray ja = new JSONArray(json); 57 | formatted = ja.toString(JSON_INDENT); 58 | } 59 | } catch (Exception e) { 60 | e.printStackTrace(); 61 | } 62 | 63 | return formatted; 64 | } 65 | 66 | public static String formatXml(String xml) { 67 | String formatted = null; 68 | if (xml == null || xml.trim().length() == 0) { 69 | return formatted; 70 | } 71 | try { 72 | Source xmlInput = new StreamSource(new StringReader(xml)); 73 | StreamResult xmlOutput = new StreamResult(new StringWriter()); 74 | Transformer transformer = TransformerFactory.newInstance().newTransformer(); 75 | transformer.setOutputProperty(OutputKeys.INDENT, "yes"); 76 | transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", 77 | String.valueOf(XML_INDENT)); 78 | transformer.transform(xmlInput, xmlOutput); 79 | formatted = xmlOutput.getWriter().toString().replaceFirst(">", ">" 80 | + XPrinter.lineSeparator); 81 | } catch (Exception e) { 82 | e.printStackTrace(); 83 | } 84 | return formatted; 85 | } 86 | 87 | public static String formatThrowable(Throwable tr) { 88 | if (tr == null) { 89 | return ""; 90 | } 91 | Throwable t = tr; 92 | while (t != null) { 93 | if (t instanceof UnknownHostException) { 94 | return ""; 95 | } 96 | t = t.getCause(); 97 | } 98 | 99 | StringWriter sw = new StringWriter(); 100 | PrintWriter pw = new PrintWriter(sw); 101 | tr.printStackTrace(pw); 102 | pw.flush(); 103 | return sw.toString(); 104 | } 105 | 106 | 107 | public static String formatArgs(String format, Object... args) { 108 | try { 109 | if (!Kits.Empty.check(format)) { 110 | return String.format(format, args); 111 | } 112 | 113 | StringBuilder sb = new StringBuilder(); 114 | for (int i = 0, N = args.length; i < N; i++) { 115 | if (i != 0) { 116 | sb.append(", "); 117 | } 118 | sb.append(args[i]); 119 | } 120 | return sb.toString(); 121 | 122 | } catch (Exception e) { 123 | } 124 | return ""; 125 | } 126 | 127 | public static String formatBorder(String[] segments) { 128 | if (segments == null || segments.length == 0) { 129 | return ""; 130 | } 131 | String[] nonNullSegments = new String[segments.length]; 132 | int nonNullCount = 0; 133 | for (String segment : segments) { 134 | if (segment != null) { 135 | nonNullSegments[nonNullCount++] = segment; 136 | } 137 | } 138 | if (nonNullCount == 0) { 139 | return ""; 140 | } 141 | 142 | StringBuilder msgBuilder = new StringBuilder(); 143 | msgBuilder.append(TOP_HORIZONTAL_BORDER).append(XPrinter.lineSeparator); 144 | for (int i = 0; i < nonNullCount; i++) { 145 | msgBuilder.append(appendVerticalBorder(nonNullSegments[i])); 146 | if (i != nonNullCount - 1) { 147 | msgBuilder.append(XPrinter.lineSeparator).append(DIVIDER_HORIZONTAL_BORDER) 148 | .append(XPrinter.lineSeparator); 149 | } else { 150 | msgBuilder.append(XPrinter.lineSeparator).append(BOTTOM_HORIZONTAL_BORDER); 151 | } 152 | } 153 | return msgBuilder.toString(); 154 | } 155 | 156 | private static String appendVerticalBorder(String msg) { 157 | StringBuilder borderedMsgBuilder = new StringBuilder(msg.length() + 10); 158 | String[] lines = msg.split(XPrinter.lineSeparator); 159 | for (int i = 0, N = lines.length; i < N; i++) { 160 | if (i != 0) { 161 | borderedMsgBuilder.append(XPrinter.lineSeparator); 162 | } 163 | String line = lines[i]; 164 | borderedMsgBuilder.append(VERTICAL_BORDER_CHAR).append(line); 165 | } 166 | return borderedMsgBuilder.toString(); 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/log/XLog.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.log; 2 | 3 | import android.text.TextUtils; 4 | import android.util.Log; 5 | 6 | import cn.droidlover.xdroidmvp.XDroidConf; 7 | 8 | /** 9 | * Created by wanglei on 2016/11/29. 10 | */ 11 | 12 | public class XLog { 13 | 14 | public static boolean LOG = XDroidConf.LOG; 15 | public static String TAG_ROOT = XDroidConf.LOG_TAG; 16 | 17 | public static void json(String json) { 18 | json(Log.DEBUG, null, json); 19 | } 20 | 21 | public static void json(int logLevel, String tag, String json) { 22 | if (LOG) { 23 | String formatJson = LogFormat.formatBorder(new String[]{LogFormat.formatJson(json)}); 24 | XPrinter.println(logLevel, TextUtils.isEmpty(tag) ? TAG_ROOT : tag, formatJson); 25 | } 26 | } 27 | 28 | public static void xml(String xml) { 29 | xml(Log.DEBUG, null, xml); 30 | } 31 | 32 | 33 | public static void xml(int logLevel, String tag, String xml) { 34 | if (LOG) { 35 | String formatXml = LogFormat.formatBorder(new String[]{LogFormat.formatXml(xml)}); 36 | XPrinter.println(logLevel, TextUtils.isEmpty(tag) ? TAG_ROOT : tag, formatXml); 37 | } 38 | } 39 | 40 | public static void error(Throwable throwable) { 41 | error(null, throwable); 42 | } 43 | 44 | public static void error(String tag, Throwable throwable) { 45 | if (LOG) { 46 | String formatError = LogFormat.formatBorder(new String[]{LogFormat.formatThrowable(throwable)}); 47 | XPrinter.println(Log.ERROR, TextUtils.isEmpty(tag) ? TAG_ROOT : tag, formatError); 48 | } 49 | } 50 | 51 | private static void msg(int logLevel, String tag, String format, Object... args) { 52 | if (LOG) { 53 | String formatMsg = LogFormat.formatBorder(new String[]{LogFormat.formatArgs(format, args)}); 54 | XPrinter.println(logLevel, TextUtils.isEmpty(tag) ? TAG_ROOT : tag, formatMsg); 55 | } 56 | } 57 | 58 | public static void d(String msg, Object... args) { 59 | msg(Log.DEBUG, null, msg, args); 60 | } 61 | 62 | public static void d(String tag, String msg, Object... args) { 63 | msg(Log.DEBUG, tag, msg, args); 64 | } 65 | 66 | public static void e(String msg, Object... args) { 67 | msg(Log.ERROR, null, msg, args); 68 | } 69 | 70 | public static void e(String tag, String msg, Object... args) { 71 | msg(Log.ERROR, tag, msg, args); 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/log/XPrinter.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.log; 2 | 3 | import android.annotation.TargetApi; 4 | import android.os.Build; 5 | 6 | /** 7 | * Created by wanglei on 2016/11/29. 8 | */ 9 | 10 | public class XPrinter { 11 | static final int MAX_LENGTH_OF_SINGLE_MESSAGE = 3500; 12 | 13 | public static String lineSeparator = lineSeparator(); 14 | 15 | public static void println(int logLevel, String tag, String msg) { 16 | if (msg.length() <= MAX_LENGTH_OF_SINGLE_MESSAGE) { 17 | printChunk(logLevel, tag, msg); 18 | return; 19 | } 20 | 21 | int msgLength = msg.length(); 22 | int start = 0; 23 | int end = start + MAX_LENGTH_OF_SINGLE_MESSAGE; 24 | while (start < msgLength) { 25 | printChunk(logLevel, tag, msg.substring(start, end)); 26 | 27 | start = end; 28 | end = Math.min(start + MAX_LENGTH_OF_SINGLE_MESSAGE, msgLength); 29 | } 30 | } 31 | 32 | private static void printChunk(int logLevel, String tag, String msg) { 33 | android.util.Log.println(logLevel, tag, msg); 34 | } 35 | 36 | 37 | @TargetApi(Build.VERSION_CODES.KITKAT) 38 | private static String lineSeparator() { 39 | try { 40 | Class.forName("android.os.Build"); 41 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 42 | return System.lineSeparator(); 43 | } 44 | } catch (Exception ignored) { 45 | } 46 | return "\n"; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/IPresent.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.mvp; 2 | 3 | /** 4 | * Created by wanglei on 2016/12/29. 5 | */ 6 | 7 | public interface IPresent { 8 | void attachV(V view); 9 | 10 | void detachV(); 11 | 12 | boolean hasV(); 13 | } 14 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/IView.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.mvp; 2 | 3 | import android.os.Bundle; 4 | import android.view.View; 5 | 6 | /** 7 | * Created by wanglei on 2016/12/29. 8 | */ 9 | 10 | public interface IView

{ 11 | void bindUI(View rootView); 12 | 13 | void bindEvent(); 14 | 15 | void initData(Bundle savedInstanceState); 16 | 17 | int getOptionsMenuId(); 18 | 19 | int getLayoutId(); 20 | 21 | boolean useEventBus(); 22 | 23 | P newP(); 24 | } 25 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/VDelegate.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.mvp; 2 | 3 | import android.view.View; 4 | 5 | /** 6 | * Created by wanglei on 2016/12/29. 7 | */ 8 | 9 | public interface VDelegate { 10 | void resume(); 11 | 12 | void pause(); 13 | 14 | void destory(); 15 | 16 | void visible(boolean flag, View view); 17 | void gone(boolean flag, View view); 18 | void inVisible(View view); 19 | 20 | void toastShort(String msg); 21 | void toastLong(String msg); 22 | } 23 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/VDelegateBase.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.mvp; 2 | 3 | import android.content.Context; 4 | import android.view.View; 5 | import android.widget.Toast; 6 | 7 | /** 8 | * Created by wanglei on 2016/12/29. 9 | */ 10 | 11 | public class VDelegateBase implements VDelegate { 12 | 13 | private Context context; 14 | 15 | private VDelegateBase(Context context) { 16 | this.context = context; 17 | } 18 | 19 | public static VDelegate create(Context context) { 20 | return new VDelegateBase(context); 21 | } 22 | 23 | 24 | @Override 25 | public void resume() { 26 | 27 | } 28 | 29 | @Override 30 | public void pause() { 31 | 32 | } 33 | 34 | @Override 35 | public void destory() { 36 | 37 | } 38 | 39 | @Override 40 | public void visible(boolean flag, View view) { 41 | if (flag) view.setVisibility(View.VISIBLE); 42 | } 43 | 44 | @Override 45 | public void gone(boolean flag, View view) { 46 | if (flag) view.setVisibility(View.GONE); 47 | } 48 | 49 | @Override 50 | public void inVisible(View view) { 51 | view.setVisibility(View.INVISIBLE); 52 | } 53 | 54 | @Override 55 | public void toastShort(String msg) { 56 | Toast.makeText(context, msg, Toast.LENGTH_SHORT).show(); 57 | } 58 | 59 | @Override 60 | public void toastLong(String msg) { 61 | Toast.makeText(context, msg, Toast.LENGTH_LONG).show(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/XActivity.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.mvp; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | import android.support.annotation.Nullable; 6 | import android.view.Menu; 7 | import android.view.View; 8 | 9 | import com.tbruyelle.rxpermissions2.RxPermissions; 10 | import com.trello.rxlifecycle2.components.support.RxAppCompatActivity; 11 | 12 | import butterknife.Unbinder; 13 | import cn.droidlover.xdroidmvp.XDroidConf; 14 | import cn.droidlover.xdroidmvp.event.BusProvider; 15 | import cn.droidlover.xdroidmvp.kit.KnifeKit; 16 | 17 | /** 18 | * Created by wanglei on 2016/12/29. 19 | */ 20 | 21 | public abstract class XActivity

extends RxAppCompatActivity implements IView

{ 22 | 23 | private VDelegate vDelegate; 24 | private P p; 25 | protected Activity context; 26 | 27 | private RxPermissions rxPermissions; 28 | 29 | private Unbinder unbinder; 30 | 31 | 32 | @Override 33 | protected void onCreate(@Nullable Bundle savedInstanceState) { 34 | super.onCreate(savedInstanceState); 35 | context = this; 36 | 37 | getP(); 38 | 39 | if (getLayoutId() > 0) { 40 | setContentView(getLayoutId()); 41 | bindUI(null); 42 | bindEvent(); 43 | } 44 | initData(savedInstanceState); 45 | 46 | } 47 | 48 | @Override 49 | public void bindUI(View rootView) { 50 | unbinder = KnifeKit.bind(this); 51 | } 52 | 53 | protected VDelegate getvDelegate() { 54 | if (vDelegate == null) { 55 | vDelegate = VDelegateBase.create(context); 56 | } 57 | return vDelegate; 58 | } 59 | 60 | protected P getP() { 61 | if (p == null) { 62 | p = newP(); 63 | } 64 | if (p != null) { 65 | if (!p.hasV()) { 66 | p.attachV(this); 67 | } 68 | } 69 | return p; 70 | } 71 | 72 | @Override 73 | protected void onStart() { 74 | super.onStart(); 75 | if (useEventBus()) { 76 | BusProvider.getBus().register(this); 77 | } 78 | } 79 | 80 | 81 | @Override 82 | protected void onResume() { 83 | super.onResume(); 84 | getvDelegate().resume(); 85 | } 86 | 87 | 88 | @Override 89 | protected void onPause() { 90 | super.onPause(); 91 | getvDelegate().pause(); 92 | } 93 | 94 | @Override 95 | public boolean useEventBus() { 96 | return false; 97 | } 98 | 99 | @Override 100 | protected void onDestroy() { 101 | super.onDestroy(); 102 | if (useEventBus()) { 103 | BusProvider.getBus().unregister(this); 104 | } 105 | if (getP() != null) { 106 | getP().detachV(); 107 | } 108 | getvDelegate().destory(); 109 | p = null; 110 | vDelegate = null; 111 | } 112 | 113 | @Override 114 | public boolean onCreateOptionsMenu(Menu menu) { 115 | if (getOptionsMenuId() > 0) { 116 | getMenuInflater().inflate(getOptionsMenuId(), menu); 117 | } 118 | return super.onCreateOptionsMenu(menu); 119 | } 120 | 121 | protected RxPermissions getRxPermissions() { 122 | rxPermissions = new RxPermissions(this); 123 | rxPermissions.setLogging(XDroidConf.DEV); 124 | return rxPermissions; 125 | } 126 | 127 | @Override 128 | public int getOptionsMenuId() { 129 | return 0; 130 | } 131 | 132 | @Override 133 | public void bindEvent() { 134 | 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/XFragment.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.mvp; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.os.Bundle; 6 | import android.support.annotation.Nullable; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | 11 | import com.tbruyelle.rxpermissions2.RxPermissions; 12 | import com.trello.rxlifecycle2.components.support.RxFragment; 13 | 14 | import butterknife.Unbinder; 15 | import cn.droidlover.xdroidmvp.XDroidConf; 16 | import cn.droidlover.xdroidmvp.event.BusProvider; 17 | import cn.droidlover.xdroidmvp.kit.KnifeKit; 18 | 19 | /** 20 | * Created by wanglei on 2016/12/29. 21 | */ 22 | 23 | public abstract class XFragment

extends RxFragment implements IView

{ 24 | 25 | private VDelegate vDelegate; 26 | private P p; 27 | protected Activity context; 28 | private View rootView; 29 | protected LayoutInflater layoutInflater; 30 | 31 | private RxPermissions rxPermissions; 32 | 33 | private Unbinder unbinder; 34 | 35 | 36 | @Nullable 37 | @Override 38 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 39 | layoutInflater = inflater; 40 | if (rootView == null && getLayoutId() > 0) { 41 | rootView = inflater.inflate(getLayoutId(), null); 42 | bindUI(rootView); 43 | } else { 44 | ViewGroup viewGroup = (ViewGroup) rootView.getParent(); 45 | if (viewGroup != null) { 46 | viewGroup.removeView(rootView); 47 | } 48 | } 49 | 50 | return rootView; 51 | } 52 | 53 | 54 | @Override 55 | public void onActivityCreated(@Nullable Bundle savedInstanceState) { 56 | super.onActivityCreated(savedInstanceState); 57 | getP(); 58 | 59 | if (useEventBus()) { 60 | BusProvider.getBus().register(this); 61 | } 62 | bindEvent(); 63 | initData(savedInstanceState); 64 | } 65 | 66 | @Override 67 | public void bindUI(View rootView) { 68 | unbinder = KnifeKit.bind(this, rootView); 69 | } 70 | 71 | protected VDelegate getvDelegate() { 72 | if (vDelegate == null) { 73 | vDelegate = VDelegateBase.create(context); 74 | } 75 | return vDelegate; 76 | } 77 | 78 | protected P getP() { 79 | if (p == null) { 80 | p = newP(); 81 | } 82 | if (p != null) { 83 | if (!p.hasV()) { 84 | p.attachV(this); 85 | } 86 | } 87 | return p; 88 | } 89 | 90 | @Override 91 | public void onAttach(Context context) { 92 | super.onAttach(context); 93 | if (context instanceof Activity) { 94 | this.context = (Activity) context; 95 | } 96 | } 97 | 98 | @Override 99 | public void onDetach() { 100 | super.onDetach(); 101 | context = null; 102 | } 103 | 104 | @Override 105 | public boolean useEventBus() { 106 | return false; 107 | } 108 | 109 | 110 | @Override 111 | public void onDestroyView() { 112 | super.onDestroyView(); 113 | if (useEventBus()) { 114 | BusProvider.getBus().unregister(this); 115 | } 116 | if (getP() != null) { 117 | getP().detachV(); 118 | } 119 | getvDelegate().destory(); 120 | 121 | p = null; 122 | vDelegate = null; 123 | } 124 | 125 | protected RxPermissions getRxPermissions() { 126 | rxPermissions = new RxPermissions(getActivity()); 127 | rxPermissions.setLogging(XDroidConf.DEV); 128 | return rxPermissions; 129 | } 130 | 131 | @Override 132 | public int getOptionsMenuId() { 133 | return 0; 134 | } 135 | 136 | @Override 137 | public void bindEvent() { 138 | 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/XLazyFragment.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.mvp; 2 | 3 | import android.os.Bundle; 4 | import android.view.View; 5 | 6 | import com.tbruyelle.rxpermissions2.RxPermissions; 7 | 8 | import butterknife.Unbinder; 9 | import cn.droidlover.xdroidmvp.XDroidConf; 10 | import cn.droidlover.xdroidmvp.event.BusProvider; 11 | import cn.droidlover.xdroidmvp.kit.KnifeKit; 12 | 13 | /** 14 | * Created by wanglei on 2017/1/26. 15 | */ 16 | 17 | public abstract class XLazyFragment

18 | extends LazyFragment implements IView

{ 19 | 20 | private VDelegate vDelegate; 21 | private P p; 22 | 23 | private RxPermissions rxPermissions; 24 | private Unbinder unbinder; 25 | 26 | @Override 27 | protected void onCreateViewLazy(Bundle savedInstanceState) { 28 | super.onCreateViewLazy(savedInstanceState); 29 | 30 | getP(); 31 | 32 | if (getLayoutId() > 0) { 33 | setContentView(getLayoutId()); 34 | bindUI(getRealRootView()); 35 | } 36 | if (useEventBus()) { 37 | BusProvider.getBus().register(this); 38 | } 39 | bindEvent(); 40 | initData(savedInstanceState); 41 | } 42 | 43 | @Override 44 | public void bindUI(View rootView) { 45 | unbinder = KnifeKit.bind(this, rootView); 46 | } 47 | 48 | @Override 49 | public void bindEvent() { 50 | 51 | } 52 | 53 | 54 | public VDelegate getvDelegate() { 55 | if (vDelegate == null) { 56 | vDelegate = VDelegateBase.create(context); 57 | } 58 | return vDelegate; 59 | } 60 | 61 | protected P getP() { 62 | if (p == null) { 63 | p = newP(); 64 | } 65 | if (p != null) { 66 | if (!p.hasV()) { 67 | p.attachV(this); 68 | } 69 | } 70 | return p; 71 | } 72 | 73 | @Override 74 | protected void onDestoryLazy() { 75 | super.onDestoryLazy(); 76 | if (useEventBus()) { 77 | BusProvider.getBus().unregister(this); 78 | } 79 | if (getP() != null) { 80 | getP().detachV(); 81 | } 82 | getvDelegate().destory(); 83 | 84 | p = null; 85 | vDelegate = null; 86 | } 87 | 88 | 89 | protected RxPermissions getRxPermissions() { 90 | rxPermissions = new RxPermissions(getActivity()); 91 | rxPermissions.setLogging(XDroidConf.DEV); 92 | return rxPermissions; 93 | } 94 | 95 | 96 | @Override 97 | public int getOptionsMenuId() { 98 | return 0; 99 | } 100 | 101 | 102 | @Override 103 | public boolean useEventBus() { 104 | return false; 105 | } 106 | 107 | 108 | } 109 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/mvp/XPresent.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.mvp; 2 | 3 | import java.lang.ref.WeakReference; 4 | 5 | /** 6 | * Created by wanglei on 2016/12/29. 7 | */ 8 | 9 | public class XPresent implements IPresent { 10 | private WeakReference v; 11 | 12 | @Override 13 | public void attachV(V view) { 14 | v = new WeakReference(view); 15 | } 16 | 17 | @Override 18 | public void detachV() { 19 | if (v.get() != null) { 20 | v.clear(); 21 | } 22 | v = null; 23 | } 24 | 25 | protected V getV() { 26 | if (v == null || v.get() == null) { 27 | throw new IllegalStateException("v can not be null"); 28 | } 29 | return v.get(); 30 | } 31 | 32 | 33 | @Override 34 | public boolean hasV() { 35 | return v != null && v.get() != null; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/net/ApiSubscriber.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.net; 2 | 3 | import com.google.gson.JsonParseException; 4 | import com.google.gson.JsonSyntaxException; 5 | 6 | import org.json.JSONException; 7 | 8 | import java.net.UnknownHostException; 9 | 10 | import io.reactivex.subscribers.ResourceSubscriber; 11 | 12 | 13 | /** 14 | * Created by wanglei on 2016/12/26. 15 | */ 16 | 17 | public abstract class ApiSubscriber extends ResourceSubscriber { 18 | 19 | 20 | @Override 21 | public void onError(Throwable e) { 22 | NetError error = null; 23 | if (e != null) { 24 | if (!(e instanceof NetError)) { 25 | if (e instanceof UnknownHostException) { 26 | error = new NetError(e, NetError.NoConnectError); 27 | } else if (e instanceof JSONException 28 | || e instanceof JsonParseException 29 | || e instanceof JsonSyntaxException) { 30 | error = new NetError(e, NetError.ParseError); 31 | } else { 32 | error = new NetError(e, NetError.OtherError); 33 | } 34 | } else { 35 | error = (NetError) e; 36 | } 37 | 38 | if (useCommonErrorHandler() 39 | && XApi.getCommonProvider() != null) { 40 | if (XApi.getCommonProvider().handleError(error)) { //使用通用异常处理 41 | return; 42 | } 43 | } 44 | onFail(error); 45 | } 46 | 47 | } 48 | 49 | protected abstract void onFail(NetError error); 50 | 51 | @Override 52 | public void onComplete() { 53 | 54 | } 55 | 56 | 57 | protected boolean useCommonErrorHandler() { 58 | return true; 59 | } 60 | 61 | 62 | } 63 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/net/IModel.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.net; 2 | 3 | /** 4 | * Created by wanglei on 2016/12/26. 5 | */ 6 | 7 | public interface IModel { 8 | boolean isNull(); //空数据 9 | 10 | boolean isAuthError(); //验证错误 11 | 12 | boolean isBizError(); //业务错误 13 | 14 | String getErrorMsg(); //后台返回的错误信息 15 | } 16 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/net/LogInterceptor.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.net; 2 | 3 | import android.util.Log; 4 | 5 | import java.io.IOException; 6 | 7 | import cn.droidlover.xdroidmvp.log.XLog; 8 | import okhttp3.Headers; 9 | import okhttp3.Interceptor; 10 | import okhttp3.MediaType; 11 | import okhttp3.Request; 12 | import okhttp3.RequestBody; 13 | import okhttp3.Response; 14 | import okhttp3.ResponseBody; 15 | import okio.Buffer; 16 | 17 | /** 18 | * Created by wanglei on 2017/1/7. 19 | */ 20 | 21 | public class LogInterceptor implements Interceptor { 22 | public static final String TAG = "XDroid_Net"; 23 | 24 | @Override 25 | public Response intercept(Chain chain) throws IOException { 26 | Request request = chain.request(); 27 | logRequest(request); 28 | Response response = chain.proceed(request); 29 | return logResponse(response); 30 | } 31 | 32 | 33 | private void logRequest(Request request) { 34 | try { 35 | String url = request.url().toString(); 36 | Headers headers = request.headers(); 37 | 38 | XLog.d(TAG, "url : " + url); 39 | XLog.d(TAG, "method : " + request.method()); 40 | if (headers != null && headers.size() > 0) { 41 | XLog.e(TAG, "headers : " + headers.toString()); 42 | } 43 | RequestBody requestBody = request.body(); 44 | if (requestBody != null) { 45 | MediaType mediaType = requestBody.contentType(); 46 | if (mediaType != null) { 47 | if (isText(mediaType)) { 48 | XLog.d(TAG, "params : " + bodyToString(request)); 49 | } else { 50 | XLog.d(TAG, "params : " + " maybe [file part] , too large too print , ignored!"); 51 | } 52 | } 53 | } 54 | } catch (Exception e) { 55 | e.printStackTrace(); 56 | } 57 | } 58 | 59 | private Response logResponse(Response response) { 60 | try { 61 | Response.Builder builder = response.newBuilder(); 62 | Response clone = builder.build(); 63 | ResponseBody body = clone.body(); 64 | if (body != null) { 65 | MediaType mediaType = body.contentType(); 66 | if (mediaType != null) { 67 | if (isText(mediaType)) { 68 | String resp = body.string(); 69 | XLog.json(Log.DEBUG, TAG, resp); 70 | 71 | body = ResponseBody.create(mediaType, resp); 72 | return response.newBuilder().body(body).build(); 73 | } else { 74 | XLog.d(TAG, "data : " + " maybe [file part] , too large too print , ignored!"); 75 | } 76 | } 77 | } 78 | 79 | } catch (Exception e) { 80 | e.printStackTrace(); 81 | } 82 | return response; 83 | } 84 | 85 | 86 | private boolean isText(MediaType mediaType) { 87 | if (mediaType == null) return false; 88 | 89 | return ("text".equals(mediaType.subtype()) 90 | || "json".equals(mediaType.subtype()) 91 | || "xml".equals(mediaType.subtype()) 92 | || "html".equals(mediaType.subtype()) 93 | || "webviewhtml".equals(mediaType.subtype()) 94 | || "x-www-form-urlencoded".equals(mediaType.subtype())); 95 | } 96 | 97 | private String bodyToString(final Request request) { 98 | try { 99 | final Request copy = request.newBuilder().build(); 100 | final Buffer buffer = new Buffer(); 101 | copy.body().writeTo(buffer); 102 | return buffer.readUtf8(); 103 | } catch (final IOException e) { 104 | return "something error when show requestBody."; 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/net/NetError.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.net; 2 | 3 | /** 4 | * Created by wanglei on 2016/12/24. 5 | */ 6 | 7 | public class NetError extends Exception { 8 | private Throwable exception; 9 | private int type = NoConnectError; 10 | 11 | public static final int ParseError = 0; //数据解析异常 12 | public static final int NoConnectError = 1; //无连接异常 13 | public static final int AuthError = 2; //用户验证异常 14 | public static final int NoDataError = 3; //无数据返回异常 15 | public static final int BusinessError = 4; //业务异常 16 | public static final int OtherError = 5; //其他异常 17 | 18 | public NetError(Throwable exception, int type) { 19 | this.exception = exception; 20 | this.type = type; 21 | } 22 | 23 | public NetError(String detailMessage, int type) { 24 | super(detailMessage); 25 | this.type = type; 26 | } 27 | 28 | @Override 29 | public String getMessage() { 30 | if (exception != null) return exception.getMessage(); 31 | return super.getMessage(); 32 | } 33 | 34 | public int getType() { 35 | return type; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/net/NetProvider.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.net; 2 | 3 | import okhttp3.CookieJar; 4 | import okhttp3.Interceptor; 5 | import okhttp3.OkHttpClient; 6 | 7 | /** 8 | * Created by wanglei on 2016/12/24. 9 | */ 10 | 11 | public interface NetProvider { 12 | Interceptor[] configInterceptors(); 13 | 14 | void configHttps(OkHttpClient.Builder builder); 15 | 16 | CookieJar configCookie(); 17 | 18 | RequestHandler configHandler(); 19 | 20 | long configConnectTimeoutMills(); 21 | 22 | long configReadTimeoutMills(); 23 | 24 | boolean configLogEnable(); 25 | 26 | boolean handleError(NetError error); 27 | 28 | boolean dispatchProgressEnable(); 29 | } 30 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/net/RequestHandler.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.net; 2 | 3 | import okhttp3.Interceptor; 4 | import okhttp3.Request; 5 | import okhttp3.Response; 6 | 7 | /** 8 | * Created by wanglei on 2016/12/24. 9 | */ 10 | 11 | public interface RequestHandler { 12 | Request onBeforeRequest(Request request, Interceptor.Chain chain); 13 | 14 | Response onAfterRequest(Response response, Interceptor.Chain chain); 15 | } 16 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/net/XInterceptor.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.net; 2 | 3 | import java.io.IOException; 4 | 5 | import okhttp3.Interceptor; 6 | import okhttp3.Request; 7 | import okhttp3.Response; 8 | 9 | /** 10 | * Created by wanglei on 2016/12/24. 11 | */ 12 | 13 | public class XInterceptor implements Interceptor { 14 | 15 | RequestHandler handler; 16 | 17 | public XInterceptor(RequestHandler handler) { 18 | this.handler = handler; 19 | } 20 | 21 | @Override 22 | public Response intercept(Chain chain) throws IOException { 23 | Request request = chain.request(); 24 | if (handler != null) { 25 | request = handler.onBeforeRequest(request, chain); 26 | } 27 | Response response = chain.proceed(request); 28 | if (handler != null) { 29 | Response tmp = handler.onAfterRequest(response, chain); 30 | if (tmp != null) { 31 | return tmp; 32 | } 33 | 34 | } 35 | return response; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/net/cookie/CookieJarImpl.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.net.cookie; 2 | 3 | import java.util.List; 4 | 5 | import okhttp3.Cookie; 6 | import okhttp3.CookieJar; 7 | import okhttp3.HttpUrl; 8 | 9 | /** 10 | * Created by wanglei on 2017/9/3. 11 | */ 12 | 13 | public class CookieJarImpl implements CookieJar { 14 | private CookieStore cookieStore; 15 | 16 | public CookieJarImpl(CookieStore cookieStore) { 17 | if (cookieStore == null) { 18 | throw new IllegalStateException("cookieStore can not be null."); 19 | } 20 | this.cookieStore = cookieStore; 21 | } 22 | 23 | @Override 24 | public synchronized void saveFromResponse(HttpUrl url, List cookies) { 25 | cookieStore.add(url, cookies); 26 | } 27 | 28 | @Override 29 | public synchronized List loadForRequest(HttpUrl url) { 30 | return cookieStore.get(url); 31 | } 32 | 33 | public CookieStore getCookieStore() { 34 | return cookieStore; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/net/cookie/CookieStore.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.net.cookie; 2 | 3 | import java.util.List; 4 | 5 | import okhttp3.Cookie; 6 | import okhttp3.HttpUrl; 7 | 8 | /** 9 | * Created by wanglei on 2017/9/3. 10 | */ 11 | 12 | public interface CookieStore { 13 | void add(HttpUrl uri, List cookie); 14 | 15 | List get(HttpUrl uri); 16 | 17 | List getCookies(); 18 | 19 | boolean remove(HttpUrl uri, Cookie cookie); 20 | 21 | boolean removeAll(); 22 | } 23 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/net/cookie/HasCookieStore.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.net.cookie; 2 | 3 | /** 4 | * Created by wanglei on 2017/9/3. 5 | */ 6 | 7 | public interface HasCookieStore { 8 | CookieStore getCookieStore(); 9 | } 10 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/net/cookie/MemoryCookieStore.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.net.cookie; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.Iterator; 6 | import java.util.List; 7 | import java.util.Set; 8 | 9 | import okhttp3.Cookie; 10 | import okhttp3.HttpUrl; 11 | 12 | /** 13 | * Created by wanglei on 2017/9/3. 14 | */ 15 | 16 | public class MemoryCookieStore implements CookieStore { 17 | private final HashMap> allCookies = new HashMap<>(); 18 | 19 | @Override 20 | public void add(HttpUrl url, List cookies) { 21 | List oldCookies = allCookies.get(url.host()); 22 | 23 | if (oldCookies != null) { 24 | Iterator itNew = cookies.iterator(); 25 | Iterator itOld = oldCookies.iterator(); 26 | while (itNew.hasNext()) { 27 | String va = itNew.next().name(); 28 | while (va != null && itOld.hasNext()) { 29 | String v = itOld.next().name(); 30 | if (v != null && va.equals(v)) { 31 | itOld.remove(); 32 | } 33 | } 34 | } 35 | oldCookies.addAll(cookies); 36 | } else { 37 | allCookies.put(url.host(), cookies); 38 | } 39 | 40 | 41 | } 42 | 43 | @Override 44 | public List get(HttpUrl uri) { 45 | List cookies = allCookies.get(uri.host()); 46 | if (cookies == null) { 47 | cookies = new ArrayList<>(); 48 | allCookies.put(uri.host(), cookies); 49 | } 50 | return cookies; 51 | 52 | } 53 | 54 | @Override 55 | public boolean removeAll() { 56 | allCookies.clear(); 57 | return true; 58 | } 59 | 60 | @Override 61 | public List getCookies() { 62 | List cookies = new ArrayList<>(); 63 | Set httpUrls = allCookies.keySet(); 64 | for (String url : httpUrls) { 65 | cookies.addAll(allCookies.get(url)); 66 | } 67 | return cookies; 68 | } 69 | 70 | 71 | @Override 72 | public boolean remove(HttpUrl uri, Cookie cookie) { 73 | List cookies = allCookies.get(uri.host()); 74 | if (cookie != null) { 75 | return cookies.remove(cookie); 76 | } 77 | return false; 78 | } 79 | 80 | 81 | } 82 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/net/cookie/SerializableHttpCookie.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.net.cookie; 2 | 3 | import java.io.IOException; 4 | import java.io.ObjectInputStream; 5 | import java.io.ObjectOutputStream; 6 | import java.io.Serializable; 7 | 8 | import okhttp3.Cookie; 9 | 10 | /** 11 | * Created by wanglei on 2017/9/3. 12 | */ 13 | 14 | public class SerializableHttpCookie implements Serializable { 15 | private static final long serialVersionUID = 6374381323722046732L; 16 | 17 | private transient final Cookie cookie; 18 | private transient Cookie clientCookie; 19 | 20 | public SerializableHttpCookie(Cookie cookie) { 21 | this.cookie = cookie; 22 | } 23 | 24 | public Cookie getCookie() { 25 | Cookie bestCookie = cookie; 26 | if (clientCookie != null) { 27 | bestCookie = clientCookie; 28 | } 29 | 30 | return bestCookie; 31 | } 32 | 33 | private void writeObject(ObjectOutputStream out) throws IOException { 34 | out.writeObject(cookie.name()); 35 | out.writeObject(cookie.value()); 36 | out.writeLong(cookie.expiresAt()); 37 | out.writeObject(cookie.domain()); 38 | out.writeObject(cookie.path()); 39 | out.writeBoolean(cookie.secure()); 40 | out.writeBoolean(cookie.httpOnly()); 41 | out.writeBoolean(cookie.hostOnly()); 42 | out.writeBoolean(cookie.persistent()); 43 | } 44 | 45 | private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { 46 | String name = (String) in.readObject(); 47 | String value = (String) in.readObject(); 48 | long expiresAt = in.readLong(); 49 | String domain = (String) in.readObject(); 50 | String path = (String) in.readObject(); 51 | boolean secure = in.readBoolean(); 52 | boolean httpOnly = in.readBoolean(); 53 | boolean hostOnly = in.readBoolean(); 54 | boolean persistent = in.readBoolean(); 55 | Cookie.Builder builder = new Cookie.Builder(); 56 | builder = builder.name(name); 57 | builder = builder.value(value); 58 | builder = builder.expiresAt(expiresAt); 59 | builder = hostOnly ? builder.hostOnlyDomain(domain) : builder.domain(domain); 60 | builder = builder.path(path); 61 | builder = secure ? builder.secure() : builder; 62 | builder = httpOnly ? builder.httpOnly() : builder; 63 | clientCookie = builder.build(); 64 | 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/net/progress/ProRequestBody.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.net.progress; 2 | 3 | import java.io.IOException; 4 | import java.lang.ref.WeakReference; 5 | import java.util.Set; 6 | 7 | import okhttp3.MediaType; 8 | import okhttp3.RequestBody; 9 | import okio.Buffer; 10 | import okio.BufferedSink; 11 | import okio.ForwardingSink; 12 | import okio.Okio; 13 | 14 | /** 15 | * Created by wanglei on 2017/9/10. 16 | */ 17 | 18 | public class ProRequestBody extends RequestBody { 19 | private RequestBody delegate; 20 | private BufferedSink bufferedSink; 21 | private Set> listeners; 22 | 23 | public ProRequestBody(RequestBody delegate, Set> listeners) { 24 | this.delegate = delegate; 25 | this.listeners = listeners; 26 | } 27 | 28 | @Override 29 | public MediaType contentType() { 30 | return delegate.contentType(); 31 | } 32 | 33 | @Override 34 | public long contentLength() { 35 | try { 36 | return delegate.contentLength(); 37 | } catch (Exception e) { 38 | e.printStackTrace(); 39 | } 40 | return -1; 41 | } 42 | 43 | 44 | @Override 45 | public void writeTo(BufferedSink sink) throws IOException { 46 | if (bufferedSink == null) { 47 | bufferedSink = Okio.buffer(new ProgressSink(sink)); 48 | } 49 | try { 50 | delegate.writeTo(bufferedSink); 51 | bufferedSink.flush(); 52 | } catch (IOException e) { 53 | e.printStackTrace(); 54 | ProgressHelper.dispatchErrorEvent(listeners, e); 55 | throw e; 56 | } 57 | } 58 | 59 | final class ProgressSink extends ForwardingSink { 60 | private long soFarBytes = 0; 61 | private long totalBytes = -1; 62 | 63 | public ProgressSink(okio.Sink delegate) { 64 | super(delegate); 65 | } 66 | 67 | @Override 68 | public void write(Buffer source, long byteCount) { 69 | try { 70 | super.write(source, byteCount); 71 | } catch (Exception e) { 72 | ProgressHelper.dispatchErrorEvent(listeners, e); 73 | } 74 | 75 | if (totalBytes < 0) { 76 | totalBytes = contentLength(); 77 | } 78 | soFarBytes += byteCount; 79 | 80 | ProgressHelper.dispatchProgressEvent(listeners, soFarBytes, totalBytes); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/net/progress/ProResponseBody.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.net.progress; 2 | 3 | import java.io.IOException; 4 | import java.lang.ref.WeakReference; 5 | import java.util.Set; 6 | 7 | import okhttp3.MediaType; 8 | import okhttp3.ResponseBody; 9 | import okio.Buffer; 10 | import okio.BufferedSource; 11 | import okio.ForwardingSource; 12 | import okio.Okio; 13 | import okio.Source; 14 | 15 | /** 16 | * Created by wanglei on 2017/9/10. 17 | */ 18 | 19 | public class ProResponseBody extends ResponseBody { 20 | private ResponseBody delegate; 21 | private BufferedSource bufferedSource; 22 | private Set> listeners; 23 | 24 | public ProResponseBody(ResponseBody delegate, Set> listeners) { 25 | this.delegate = delegate; 26 | this.listeners = listeners; 27 | } 28 | 29 | @Override 30 | public MediaType contentType() { 31 | return delegate.contentType(); 32 | } 33 | 34 | @Override 35 | public long contentLength() { 36 | return delegate.contentLength(); 37 | } 38 | 39 | @Override 40 | public BufferedSource source() { 41 | if (bufferedSource == null) { 42 | bufferedSource = Okio.buffer(new ProgressSource(delegate.source())); 43 | } 44 | return bufferedSource; 45 | } 46 | 47 | 48 | final class ProgressSource extends ForwardingSource { 49 | private long soFarBytes = 0; 50 | private long totalBytes = -1; 51 | 52 | public ProgressSource(Source delegate) { 53 | super(delegate); 54 | } 55 | 56 | @Override 57 | public long read(Buffer sink, long byteCount) throws IOException { 58 | long bytesRead = 0L; 59 | try { 60 | bytesRead = super.read(sink, byteCount); 61 | 62 | if (totalBytes < 0) { 63 | totalBytes = contentLength(); 64 | } 65 | soFarBytes += (bytesRead != -1 ? bytesRead : 0); 66 | 67 | ProgressHelper.dispatchProgressEvent(listeners, soFarBytes, totalBytes); 68 | } catch (IOException e) { 69 | ProgressHelper.dispatchErrorEvent(listeners, e); 70 | throw e; 71 | } 72 | 73 | return bytesRead; 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/net/progress/ProgressListener.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.net.progress; 2 | 3 | /** 4 | * Created by wanglei on 2017/9/10. 5 | */ 6 | 7 | public interface ProgressListener { 8 | void onProgress(long soFarBytes, long totalBytes); 9 | 10 | void onError(Throwable throwable); 11 | } 12 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/router/RouterCallback.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.router; 2 | 3 | import android.app.Activity; 4 | 5 | /** 6 | * Created by wanglei on 2016/11/29. 7 | */ 8 | 9 | public interface RouterCallback { 10 | 11 | void onBefore(Activity from, Class to); 12 | 13 | void onNext(Activity from, Class to); 14 | 15 | void onError(Activity from, Class to, Throwable throwable); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /mvp/src/main/java/cn/droidlover/xdroidmvp/router/SimpleRouterCallback.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.router; 2 | 3 | import android.app.Activity; 4 | 5 | /** 6 | * Created by wanglei on 2016/11/29. 7 | */ 8 | 9 | public class SimpleRouterCallback implements RouterCallback { 10 | 11 | @Override 12 | public void onBefore(Activity from, Class to) { 13 | 14 | } 15 | 16 | @Override 17 | public void onNext(Activity from, Class to) { 18 | 19 | } 20 | 21 | @Override 22 | public void onError(Activity from, Class to, Throwable throwable) { 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /mvp/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Mvp 3 | 4 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':mvp', ':test' 2 | -------------------------------------------------------------------------------- /test/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /test/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion rootProject.ext.android.compileSdkVersion 5 | 6 | defaultConfig { 7 | minSdkVersion rootProject.ext.android.minSdkVersion 8 | targetSdkVersion rootProject.ext.android.targetSdkVersion 9 | versionCode rootProject.ext.android.versionCode 10 | versionName rootProject.ext.android.versionName 11 | } 12 | 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | implementation fileTree(dir: 'libs', include: ['*.jar']) 23 | annotationProcessor rootProject.ext.dependencies["butterknife-apt"] 24 | implementation project(":mvp") 25 | } 26 | 27 | -------------------------------------------------------------------------------- /test/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/wanglei/DevTools/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 | -------------------------------------------------------------------------------- /test/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /test/src/main/java/cn/droidlover/xdroidmvp/test/ImageLoaderTest.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.test; 2 | 3 | import android.graphics.drawable.Drawable; 4 | import android.os.Bundle; 5 | import android.widget.ImageView; 6 | 7 | import java.io.File; 8 | 9 | import cn.droidlover.xdroidmvp.imageloader.ILFactory; 10 | import cn.droidlover.xdroidmvp.imageloader.ILoader; 11 | import cn.droidlover.xdroidmvp.imageloader.LoadCallback; 12 | import cn.droidlover.xdroidmvp.mvp.XActivity; 13 | 14 | /** 15 | * Created by wanglei on 2017/1/30. 16 | */ 17 | 18 | public class ImageLoaderTest extends XActivity { 19 | 20 | @Override 21 | public void initData(Bundle savedInstanceState) { 22 | ImageView imageView = null; 23 | String assetPath = ""; 24 | String filePath = ""; 25 | String urlPath = ""; 26 | int resIds = 0; 27 | 28 | ILFactory.getLoader().init(context); 29 | ILFactory.getLoader().loadAssets(imageView, assetPath, null); 30 | ILFactory.getLoader().loadFile(imageView, new File(filePath), null); 31 | ILFactory.getLoader().loadNet(imageView, urlPath, null); 32 | ILFactory.getLoader().loadNet(context, urlPath, null, new LoadCallback() { 33 | @Override 34 | public void onLoadReady(Drawable drawable) { 35 | 36 | } 37 | }); 38 | ILFactory.getLoader().loadResource(imageView, resIds, null); 39 | ILFactory.getLoader().clearMemoryCache(context); 40 | ILFactory.getLoader().resume(context); 41 | ILFactory.getLoader().pause(context); 42 | 43 | new Thread() { 44 | @Override 45 | public void run() { 46 | super.run(); 47 | ILFactory.getLoader().clearDiskCache(context); 48 | } 49 | }.start(); 50 | 51 | int loadingResId = -1; 52 | int loadErrorResId = -1; 53 | ILFactory.getLoader().loadNet(imageView, urlPath, 54 | new ILoader.Options(loadingResId, loadErrorResId).scaleType(ImageView.ScaleType.FIT_CENTER)); 55 | 56 | } 57 | 58 | @Override 59 | public int getLayoutId() { 60 | return 0; 61 | } 62 | 63 | @Override 64 | public Object newP() { 65 | return null; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /test/src/main/java/cn/droidlover/xdroidmvp/test/base/AListAdapter.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.test.base; 2 | 3 | import android.content.Context; 4 | import android.view.View; 5 | 6 | import cn.droidlover.xdroidmvp.base.SimpleListAdapter; 7 | import cn.droidlover.xdroidmvp.kit.KnifeKit; 8 | import cn.droidlover.xdroidmvp.test.R; 9 | 10 | /** 11 | * Created by wanglei on 2017/1/30. 12 | */ 13 | 14 | public class AListAdapter extends SimpleListAdapter { 15 | 16 | 17 | public AListAdapter(Context context) { 18 | super(context); 19 | } 20 | 21 | @Override 22 | protected ViewHolder newViewHolder(View convertView) { 23 | return new ViewHolder(convertView); 24 | } 25 | 26 | @Override 27 | protected int getLayoutId() { 28 | return R.layout.item_single; 29 | } 30 | 31 | @Override 32 | protected void convert(ViewHolder holder, String item, int position) { 33 | 34 | } 35 | 36 | public static class ViewHolder { 37 | 38 | public ViewHolder(View convertView) { 39 | KnifeKit.bind(this, convertView); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /test/src/main/java/cn/droidlover/xdroidmvp/test/base/BRecAdapter.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.test.base; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.view.View; 6 | 7 | import cn.droidlover.xdroidmvp.base.SimpleRecAdapter; 8 | import cn.droidlover.xdroidmvp.kit.KnifeKit; 9 | import cn.droidlover.xdroidmvp.test.R; 10 | 11 | /** 12 | * Created by wanglei on 2017/1/30. 13 | */ 14 | 15 | public class BRecAdapter extends SimpleRecAdapter { 16 | 17 | public BRecAdapter(Context context) { 18 | super(context); 19 | } 20 | 21 | @Override 22 | public ViewHolder newViewHolder(View itemView) { 23 | return new ViewHolder(itemView); 24 | } 25 | 26 | @Override 27 | public int getLayoutId() { 28 | return R.layout.item_single; 29 | } 30 | 31 | @Override 32 | public void onBindViewHolder(final ViewHolder holder, final int position) { 33 | holder.itemView.setOnClickListener(new View.OnClickListener() { 34 | @Override 35 | public void onClick(View v) { 36 | if (getRecItemClick() != null) { 37 | getRecItemClick().onItemClick(position, data.get(position), 0, holder); 38 | } 39 | } 40 | }); 41 | } 42 | 43 | public static class ViewHolder extends RecyclerView.ViewHolder { 44 | 45 | public ViewHolder(View itemView) { 46 | super(itemView); 47 | KnifeKit.bind(this, itemView); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /test/src/main/java/cn/droidlover/xdroidmvp/test/base/CListAdapter.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.test.base; 2 | 3 | import android.content.Context; 4 | import android.view.View; 5 | import android.view.ViewGroup; 6 | 7 | import cn.droidlover.xdroidmvp.base.XListAdapter; 8 | import cn.droidlover.xdroidmvp.kit.KnifeKit; 9 | import cn.droidlover.xdroidmvp.test.R; 10 | 11 | /** 12 | * Created by wanglei on 2017/1/30. 13 | */ 14 | 15 | public class CListAdapter extends XListAdapter { 16 | 17 | public CListAdapter(Context context) { 18 | super(context); 19 | } 20 | 21 | @Override 22 | public View getView(int position, View convertView, ViewGroup parent) { 23 | String item = data.get(position); 24 | CListAdapter.ViewHolder holder = null; 25 | 26 | if (convertView == null) { 27 | convertView = View.inflate(context, R.layout.item_single, null); 28 | holder = new ViewHolder(convertView); 29 | 30 | convertView.setTag(holder); 31 | } else { 32 | holder = (ViewHolder) convertView.getTag(); 33 | } 34 | return convertView; 35 | } 36 | 37 | public static class ViewHolder { 38 | 39 | public ViewHolder(View convertView) { 40 | KnifeKit.bind(this, convertView); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /test/src/main/java/cn/droidlover/xdroidmvp/test/base/DRecAdapter.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.test.base; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | 9 | import cn.droidlover.xdroidmvp.kit.KnifeKit; 10 | import cn.droidlover.xdroidmvp.test.R; 11 | import cn.droidlover.xrecyclerview.RecyclerAdapter; 12 | 13 | /** 14 | * Created by wanglei on 2017/1/30. 15 | */ 16 | 17 | public class DRecAdapter extends RecyclerAdapter { 18 | 19 | 20 | public DRecAdapter(Context context) { 21 | super(context); 22 | } 23 | 24 | @Override 25 | public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 26 | View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_single, parent, false); 27 | return new ViewHolder(view); 28 | } 29 | 30 | @Override 31 | public void onBindViewHolder(ViewHolder holder, int position) { 32 | 33 | } 34 | 35 | public static class ViewHolder extends RecyclerView.ViewHolder { 36 | 37 | public ViewHolder(View itemView) { 38 | super(itemView); 39 | KnifeKit.bind(this, itemView); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /test/src/main/java/cn/droidlover/xdroidmvp/test/mvp/PermissionActivity.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.test.mvp; 2 | 3 | import android.Manifest; 4 | import android.os.Bundle; 5 | 6 | import cn.droidlover.xdroidmvp.mvp.XActivity; 7 | import io.reactivex.functions.Consumer; 8 | 9 | /** 10 | * Created by wanglei on 2017/1/30. 11 | */ 12 | 13 | public class PermissionActivity extends XActivity { 14 | @Override 15 | public void initData(Bundle savedInstanceState) { 16 | getRxPermissions() 17 | .request(Manifest.permission.CAMERA) 18 | .subscribe(new Consumer() { 19 | @Override 20 | public void accept(Boolean granted) throws Exception { 21 | if (granted) { 22 | //TODO 许可 23 | 24 | } else { 25 | //TODO 未许可 26 | 27 | } 28 | } 29 | }); 30 | } 31 | 32 | @Override 33 | public int getLayoutId() { 34 | return 0; 35 | } 36 | 37 | @Override 38 | public Object newP() { 39 | return null; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /test/src/main/java/cn/droidlover/xdroidmvp/test/mvp/UiDelegateActivity.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.test.mvp; 2 | 3 | import android.os.Bundle; 4 | 5 | import cn.droidlover.xdroidmvp.mvp.XActivity; 6 | 7 | /** 8 | * Created by wanglei on 2017/1/30. 9 | */ 10 | 11 | public class UiDelegateActivity extends XActivity { 12 | @Override 13 | public void initData(Bundle savedInstanceState) { 14 | getvDelegate().toastShort(""); 15 | getvDelegate().gone(true, null); 16 | getvDelegate().toastLong(""); 17 | // ... 18 | } 19 | 20 | @Override 21 | public int getLayoutId() { 22 | return 0; 23 | } 24 | 25 | @Override 26 | public Object newP() { 27 | return null; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /test/src/main/java/cn/droidlover/xdroidmvp/test/mvp/multi_p/BActivity.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.test.mvp.multi_p; 2 | 3 | import android.os.Bundle; 4 | 5 | import cn.droidlover.xdroidmvp.mvp.XActivity; 6 | 7 | /** 8 | * Created by wanglei on 2017/1/30. 9 | */ 10 | 11 | public class BActivity extends XActivity implements ICommonV { 12 | @Override 13 | public void initData(Bundle savedInstanceState) { 14 | getP().loadData(); 15 | } 16 | 17 | @Override 18 | public int getLayoutId() { 19 | return 0; 20 | } 21 | 22 | @Override 23 | public PMulti newP() { 24 | return new PMulti(); 25 | } 26 | 27 | 28 | @Override 29 | public void showError(Exception e) { 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /test/src/main/java/cn/droidlover/xdroidmvp/test/mvp/multi_p/CActivity.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.test.mvp.multi_p; 2 | 3 | import android.os.Bundle; 4 | 5 | import cn.droidlover.xdroidmvp.mvp.XActivity; 6 | 7 | /** 8 | * Created by wanglei on 2017/1/30. 9 | */ 10 | 11 | public class CActivity extends XActivity implements ICommonV { 12 | 13 | 14 | @Override 15 | public void initData(Bundle savedInstanceState) { 16 | getP().loadData(); 17 | } 18 | 19 | @Override 20 | public int getLayoutId() { 21 | return 0; 22 | } 23 | 24 | @Override 25 | public PMulti newP() { 26 | return new PMulti(); 27 | } 28 | 29 | @Override 30 | public void showError(Exception e) { 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /test/src/main/java/cn/droidlover/xdroidmvp/test/mvp/multi_p/ICommonV.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.test.mvp.multi_p; 2 | 3 | import cn.droidlover.xdroidmvp.mvp.IView; 4 | 5 | /** 6 | * Created by wanglei on 2017/1/30. 7 | */ 8 | 9 | public interface ICommonV extends IView { 10 | void showError(Exception e); 11 | } 12 | -------------------------------------------------------------------------------- /test/src/main/java/cn/droidlover/xdroidmvp/test/mvp/multi_p/PMulti.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.test.mvp.multi_p; 2 | 3 | import cn.droidlover.xdroidmvp.mvp.XPresent; 4 | 5 | /** 6 | * Created by wanglei on 2017/1/30. 7 | */ 8 | 9 | public class PMulti extends XPresent { 10 | 11 | public void loadData() { 12 | getV().showError(new IllegalStateException("")); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/src/main/java/cn/droidlover/xdroidmvp/test/mvp/no_p/NoPActivity.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.test.mvp.no_p; 2 | 3 | import android.os.Bundle; 4 | 5 | import cn.droidlover.xdroidmvp.mvp.XActivity; 6 | 7 | /** 8 | * Created by wanglei on 2017/1/30. 9 | */ 10 | 11 | public class NoPActivity extends XActivity { 12 | 13 | @Override 14 | public void initData(Bundle savedInstanceState) { 15 | 16 | } 17 | 18 | @Override 19 | public int getLayoutId() { 20 | return 0; 21 | } 22 | 23 | @Override 24 | public Object newP() { 25 | return null; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /test/src/main/java/cn/droidlover/xdroidmvp/test/mvp/single_p/PSingle.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.test.mvp.single_p; 2 | 3 | import cn.droidlover.xdroidmvp.mvp.XPresent; 4 | 5 | /** 6 | * Created by wanglei on 2017/1/30. 7 | */ 8 | 9 | public class PSingle extends XPresent { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /test/src/main/java/cn/droidlover/xdroidmvp/test/mvp/single_p/SinglePActivity.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.test.mvp.single_p; 2 | 3 | import android.os.Bundle; 4 | 5 | import cn.droidlover.xdroidmvp.mvp.XActivity; 6 | 7 | /** 8 | * Created by wanglei on 2017/1/30. 9 | */ 10 | 11 | public class SinglePActivity extends XActivity { 12 | 13 | @Override 14 | public void initData(Bundle savedInstanceState) { 15 | 16 | } 17 | 18 | @Override 19 | public int getLayoutId() { 20 | return 0; 21 | } 22 | 23 | @Override 24 | public PSingle newP() { 25 | return new PSingle(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /test/src/main/java/cn/droidlover/xdroidmvp/test/router/EndActivity.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.test.router; 2 | 3 | import android.os.Bundle; 4 | 5 | import cn.droidlover.xdroidmvp.mvp.XActivity; 6 | 7 | /** 8 | * Created by wanglei on 2017/1/30. 9 | */ 10 | 11 | public class EndActivity extends XActivity { 12 | 13 | @Override 14 | public void initData(Bundle savedInstanceState) { 15 | 16 | } 17 | 18 | @Override 19 | public int getLayoutId() { 20 | return 0; 21 | } 22 | 23 | @Override 24 | public Object newP() { 25 | return null; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /test/src/main/java/cn/droidlover/xdroidmvp/test/router/StartActivity.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.test.router; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.v4.app.ActivityOptionsCompat; 6 | 7 | import cn.droidlover.xdroidmvp.mvp.XActivity; 8 | import cn.droidlover.xdroidmvp.router.Router; 9 | 10 | /** 11 | * Created by wanglei on 2017/1/30. 12 | */ 13 | 14 | public class StartActivity extends XActivity { 15 | 16 | @Override 17 | public void initData(Bundle savedInstanceState) { 18 | Router.newIntent(context) 19 | .to(EndActivity.class) 20 | .putString("arg_name", "xdroid") 21 | .launch(); 22 | 23 | Router.newIntent(context) 24 | .to(EndActivity.class) 25 | .putString("arg_name", "xdroid") 26 | .requestCode(100) 27 | .launch(); 28 | 29 | int exitAnim = 0, enterAnim = 0; 30 | Router.newIntent(context) 31 | .to(EndActivity.class) 32 | .putString("arg_name", "xdroid") 33 | .anim(enterAnim, exitAnim) 34 | .launch(); 35 | 36 | Router.newIntent(context) 37 | .to(EndActivity.class) 38 | .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) 39 | .launch(); 40 | 41 | Router.newIntent(context) 42 | .to(EndActivity.class) 43 | .options(ActivityOptionsCompat.makeBasic()) 44 | .launch(); 45 | 46 | } 47 | 48 | @Override 49 | public int getLayoutId() { 50 | return 0; 51 | } 52 | 53 | @Override 54 | public Object newP() { 55 | return null; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /test/src/main/java/cn/droidlover/xdroidmvp/test/rxbus/LoginEvent.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.test.rxbus; 2 | 3 | import cn.droidlover.xdroidmvp.event.IBus; 4 | 5 | /** 6 | * Created by wanglei on 2017/1/30. 7 | */ 8 | 9 | public class LoginEvent extends IBus.AbsEvent { 10 | 11 | @Override 12 | public int getTag() { 13 | return 0; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/src/main/java/cn/droidlover/xdroidmvp/test/rxbus/RxBusActivity.java: -------------------------------------------------------------------------------- 1 | package cn.droidlover.xdroidmvp.test.rxbus; 2 | 3 | import android.os.Bundle; 4 | 5 | import com.blankj.rxbus.RxBus; 6 | 7 | import cn.droidlover.xdroidmvp.event.BusProvider; 8 | import cn.droidlover.xdroidmvp.mvp.XActivity; 9 | 10 | /** 11 | * Created by wanglei on 2017/1/30. 12 | */ 13 | 14 | public class RxBusActivity extends XActivity { 15 | 16 | @Override 17 | public void initData(Bundle savedInstanceState) { 18 | 19 | BusProvider.getBus().post(new LoginEvent()); 20 | 21 | BusProvider.getBus() 22 | .subscribe(this, new RxBus.Callback() { 23 | @Override 24 | public void onEvent(LoginEvent loginEvent) { 25 | //TODO 事件处理 26 | } 27 | }); 28 | 29 | } 30 | 31 | @Override 32 | public int getLayoutId() { 33 | return 0; 34 | } 35 | 36 | @Override 37 | public boolean useEventBus() { 38 | return true; 39 | } 40 | 41 | @Override 42 | public Object newP() { 43 | return null; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /test/src/main/res/layout/item_single.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 13 | 14 | -------------------------------------------------------------------------------- /test/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Test 3 | 4 | -------------------------------------------------------------------------------- /xdroid_logo_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limedroid/XDroidMvp/d650d69d67f55ea3fc7aace05c8dc95b6338829f/xdroid_logo_128.png --------------------------------------------------------------------------------